Skip to content
This repository has been archived by the owner on Jun 9, 2024. It is now read-only.

Commit

Permalink
feat(statedb): Reintroduce and simplify StateDB (#14)
Browse files Browse the repository at this point in the history
Signed-off-by: Devon Bear <itsdevbear@berachain.com>
Co-authored-by: Cal Bera <calbera@berachain.com>
  • Loading branch information
Devon Bear and calbera authored Jan 16, 2023
1 parent 2edfa85 commit fbed0d1
Show file tree
Hide file tree
Showing 31 changed files with 1,978 additions and 34 deletions.
39 changes: 39 additions & 0 deletions core/evm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2023, Berachain Foundation. All rights reserved.
// See the file LICENSE for licensing terms.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package core

import (
"math/big"

"github.com/berachain/stargazer/core/state"
"github.com/berachain/stargazer/core/vm"
"github.com/berachain/stargazer/lib/common"
)

// Compile-time interface check.
var _ vm.CanTransferFunc = CanTransfer
var _ vm.TransferFunc = Transfer

// `CanTransfer` checks whether there are enough funds in the address' account to make a transfer.
// NOTE: This does not take the necessary gas in to account to make the transfer valid.
func CanTransfer(sdb vm.StateDB, addr common.Address, amount *big.Int) bool {
return sdb.GetBalance(addr).Cmp(amount) >= 0
}

// `Transfer` subtracts amount from sender and adds amount to recipient using the `vm.StateDB`.
func Transfer(sdb vm.StateDB, sender, recipient common.Address, amount *big.Int) {
// We use `TransferBalance` to use the same logic as the native transfer in x/bank.
sdb.(state.ExtStateDB).TransferBalance(sender, recipient, amount)
}
68 changes: 68 additions & 0 deletions core/state/cache_entries.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (C) 2022, Berachain Foundation. All rights reserved.
// See the file LICENSE for licensing terms.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//nolint:ireturn // all `CacheEntries` must adhere to the same interface.
package state

import (
"github.com/berachain/stargazer/core/state/store/journal"
)

var (
_ journal.CacheEntry = &RefundChange{}
_ journal.CacheEntry = &AddLogChange{}
)

type (
AddLogChange struct {
sdb *StateDB
}
RefundChange struct {
sdb *StateDB
prev uint64
}
)

// ==============================================================================
// AddLogChange
// ==============================================================================

// `Revert` implements `journal.CacheEntry`.
func (ce *AddLogChange) Revert() {
ce.sdb.logs = ce.sdb.logs[:len(ce.sdb.logs)-1]
}

// `Clone` implements `journal.CacheEntry`.
func (ce *AddLogChange) Clone() journal.CacheEntry {
return &AddLogChange{
sdb: ce.sdb,
}
}

// ==============================================================================
// RefundChange
// ==============================================================================

// `Revert` implements `journal.CacheEntry`.
func (ce *RefundChange) Revert() {
ce.sdb.refund = ce.prev
}

// `Clone` implements `journal.CacheEntry`.
func (ce *RefundChange) Clone() journal.CacheEntry {
return &RefundChange{
sdb: ce.sdb,
prev: ce.prev,
}
}
86 changes: 86 additions & 0 deletions core/state/cache_entries_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (C) 2023, Berachain Foundation. All rights reserved.
// See the file LICENSE for licensing terms.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package state

import (
"github.com/berachain/stargazer/core/state/store/journal"
coretypes "github.com/berachain/stargazer/core/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("AddLogChange", func() {
var (
ce *AddLogChange
sdb *StateDB
)
BeforeEach(func() {
sdb = &StateDB{
logs: []*coretypes.Log{},
}
ce = &AddLogChange{
sdb: sdb,
}
})
It("implements journal.CacheEntry", func() {
var _ journal.CacheEntry = ce
Expect(ce).To(BeAssignableToTypeOf(&AddLogChange{}))
})
It("Revert should remove the last log", func() {
sdb.logs = append(sdb.logs, &coretypes.Log{})
ce.Revert()
Expect(len(sdb.logs)).To(Equal(0))
})
It("Clone should return a new AddLogChange with the same sdb", func() {
cloned, ok := ce.Clone().(*AddLogChange)
Expect(ok).To(BeTrue())
Expect(cloned.sdb).To(Equal(sdb))
Expect(cloned).ToNot(BeIdenticalTo(ce))
})
})

var _ = Describe("RefundChange", func() {
var (
ce *RefundChange
sdb *StateDB
)

BeforeEach(func() {
sdb = &StateDB{
refund: 0,
}
ce = &RefundChange{
sdb: sdb,
prev: 0,
}
})
It("implements journal.CacheEntry", func() {
var _ journal.CacheEntry = ce
Expect(ce).To(BeAssignableToTypeOf(&RefundChange{}))
})
It("Revert should restore the previous refund value", func() {
sdb.refund = 100
ce.prev = 50
ce.Revert()
Expect(sdb.refund).To(Equal(uint64(50)))
})
It("Clone should return a new RefundChange with the same sdb and prev", func() {
cloned, ok := ce.Clone().(*RefundChange)
Expect(ok).To(BeTrue())
Expect(cloned.sdb).To(Equal(sdb))
Expect(cloned.prev).To(Equal(ce.prev))
Expect(cloned).ToNot(BeIdenticalTo(ce))
})
})
34 changes: 34 additions & 0 deletions core/state/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2023, Berachain Foundation. All rights reserved.
// See the file LICENSE for licensing terms.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package state

import (
"math/big"

"github.com/ethereum/go-ethereum/core/vm"

"github.com/berachain/stargazer/lib/common"
)

type GethStateDB = vm.StateDB

// `StargazerStateDB` defines an extension to the interface provided by go-ethereum to
// support additional state transition functionalities that are useful in a Cosmos SDK context.
type StargazerStateDB interface {
GethStateDB

// TransferBalance transfers the balance from one account to another
TransferBalance(common.Address, common.Address, *big.Int)
}
27 changes: 27 additions & 0 deletions core/state/state_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2023, Berachain Foundation. All rights reserved.
// See the file LICENSE for licensing terms.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package state_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestState(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "core/state")
}
Loading

0 comments on commit fbed0d1

Please sign in to comment.