diff --git a/ethapi/api.go b/ethapi/api.go index ee769575c..8fb764207 100644 --- a/ethapi/api.go +++ b/ethapi/api.go @@ -20,7 +20,6 @@ import ( "context" "errors" "fmt" - "github.com/ethereum/go-ethereum/eth/tracers" "math/big" "strings" "time" @@ -36,10 +35,10 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus/ethash" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" @@ -50,6 +49,7 @@ import ( "github.com/Fantom-foundation/go-opera/evmcore" "github.com/Fantom-foundation/go-opera/gossip/gasprice" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" "github.com/Fantom-foundation/go-opera/utils/signers/internaltx" @@ -922,7 +922,7 @@ type OverrideAccount struct { type StateOverride map[common.Address]OverrideAccount // Apply overrides the fields of specified accounts into the given state. -func (diff *StateOverride) Apply(state state.StateDbInterface) error { +func (diff *StateOverride) Apply(state state.StateDB) error { if diff == nil { return nil } @@ -2113,7 +2113,7 @@ func (api *PublicDebugAPI) TraceTransaction(ctx context.Context, hash common.Has // traceTx configures a new tracer according to the provided configuration, and // executes the given message in the provided environment. The return value will // be tracer dependent. -func (api *PublicDebugAPI) traceTx(ctx context.Context, message evmcore.Message, txctx *tracers.Context, blockHeader *evmcore.EvmHeader, statedb state.StateDbInterface, config *TraceConfig) (interface{}, error) { +func (api *PublicDebugAPI) traceTx(ctx context.Context, message evmcore.Message, txctx *tracers.Context, blockHeader *evmcore.EvmHeader, statedb state.StateDB, config *TraceConfig) (interface{}, error) { // Assemble the structured logger or the JavaScript tracer var ( tracer vm.Tracer @@ -2280,7 +2280,7 @@ func (api *PublicDebugAPI) traceBlock(ctx context.Context, block *evmcore.EvmBlo } // stateAtTransaction returns the execution environment of a certain transaction. -func (api *PublicDebugAPI) stateAtTransaction(ctx context.Context, block *evmcore.EvmBlock, txIndex int) (evmcore.Message, state.StateDbInterface, error) { +func (api *PublicDebugAPI) stateAtTransaction(ctx context.Context, block *evmcore.EvmBlock, txIndex int) (evmcore.Message, state.StateDB, error) { // Short circuit if it's genesis block. if block.NumberU64() == 0 { return nil, nil, errors.New("no transaction in genesis") diff --git a/ethapi/backend.go b/ethapi/backend.go index 055a5421a..b4934ea89 100644 --- a/ethapi/backend.go +++ b/ethapi/backend.go @@ -26,7 +26,6 @@ import ( "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" notify "github.com/ethereum/go-ethereum/event" @@ -36,6 +35,7 @@ import ( "github.com/Fantom-foundation/go-opera/evmcore" "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/iblockproc" + "github.com/Fantom-foundation/go-opera/inter/state" ) // PeerProgress is synchronization status of a peer @@ -67,12 +67,12 @@ type Backend interface { HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*evmcore.EvmHeader, error) HeaderByHash(ctx context.Context, hash common.Hash) (*evmcore.EvmHeader, error) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*evmcore.EvmBlock, error) - StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (state.StateDbInterface, *evmcore.EvmHeader, error) + StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (state.StateDB, *evmcore.EvmHeader, error) ResolveRpcBlockNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (idx.Block, error) BlockByHash(ctx context.Context, hash common.Hash) (*evmcore.EvmBlock, error) GetReceiptsByNumber(ctx context.Context, number rpc.BlockNumber) (types.Receipts, error) GetTd(hash common.Hash) *big.Int - GetEVM(ctx context.Context, msg evmcore.Message, state state.StateDbInterface, header *evmcore.EvmHeader, vmConfig *vm.Config) (*vm.EVM, func() error, error) + GetEVM(ctx context.Context, msg evmcore.Message, state vm.StateDB, header *evmcore.EvmHeader, vmConfig *vm.Config) (*vm.EVM, func() error, error) MinGasPrice() *big.Int MaxGasLimit() uint64 diff --git a/ethapi/tx_trace.go b/ethapi/tx_trace.go index fbe1a9644..2fa6a04d6 100644 --- a/ethapi/tx_trace.go +++ b/ethapi/tx_trace.go @@ -11,12 +11,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" "github.com/Fantom-foundation/go-opera/evmcore" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/txtrace" "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" @@ -204,7 +204,7 @@ func (s *PublicTxTraceAPI) replayBlock(ctx context.Context, block *evmcore.EvmBl // traceTx trace transaction with EVM replay and return processed result func (s *PublicTxTraceAPI) traceTx( ctx context.Context, b Backend, header *evmcore.EvmHeader, msg types.Message, - state state.StateDbInterface, block *evmcore.EvmBlock, tx *types.Transaction, index uint64, + state state.StateDB, block *evmcore.EvmBlock, tx *types.Transaction, index uint64, status uint64) (*[]txtrace.ActionTrace, error) { // Providing default config with tracer diff --git a/evmcore/apply_fake_genesis.go b/evmcore/apply_fake_genesis.go index c284e95c2..9dd812ae1 100644 --- a/evmcore/apply_fake_genesis.go +++ b/evmcore/apply_fake_genesis.go @@ -19,79 +19,15 @@ package evmcore import ( "crypto/ecdsa" "errors" - "math" - "math/big" "time" - "github.com/ethereum/go-ethereum/common" + "github.com/Fantom-foundation/go-opera/inter" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - - "github.com/Fantom-foundation/go-opera/inter" ) var FakeGenesisTime = inter.Timestamp(1608600000 * time.Second) -// ApplyFakeGenesis writes or updates the genesis block in db. -func ApplyFakeGenesis(statedb state.StateDbInterface, time inter.Timestamp, balances map[common.Address]*big.Int) (*EvmBlock, error) { - for acc, balance := range balances { - statedb.SetBalance(acc, balance) - } - - // initial block - root, err := flush(statedb, true) - if err != nil { - return nil, err - } - block := genesisBlock(time, root) - - return block, nil -} - -func flush(statedb state.StateDbInterface, clean bool) (root common.Hash, err error) { - root, err = statedb.Commit(clean) - if err != nil { - return - } - err = statedb.Database().TrieDB().Commit(root, false, nil) - if err != nil { - return - } - - if !clean { - err = statedb.Database().TrieDB().Cap(0) - } - - return -} - -// genesisBlock makes genesis block with pretty hash. -func genesisBlock(time inter.Timestamp, root common.Hash) *EvmBlock { - block := &EvmBlock{ - EvmHeader: EvmHeader{ - Number: big.NewInt(0), - Time: time, - GasLimit: math.MaxUint64, - Root: root, - TxHash: types.EmptyRootHash, - }, - } - - return block -} - -// MustApplyFakeGenesis writes the genesis block and state to db, panicking on error. -func MustApplyFakeGenesis(statedb state.StateDbInterface, time inter.Timestamp, balances map[common.Address]*big.Int) *EvmBlock { - block, err := ApplyFakeGenesis(statedb, time, balances) - if err != nil { - log.Crit("ApplyFakeGenesis", "err", err) - } - return block -} - // FakeKey gets n-th fake private key. func FakeKey(n uint32) *ecdsa.PrivateKey { var keys = [100]string{ diff --git a/evmcore/bench_test.go b/evmcore/bench_test.go deleted file mode 100644 index d44b7114f..000000000 --- a/evmcore/bench_test.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package evmcore - -import ( - "crypto/ecdsa" - "io/ioutil" - "math/big" - "os" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/params" -) - -func BenchmarkInsertChain_empty_memdb(b *testing.B) { - benchInsertChain(b, false, nil) -} -func BenchmarkInsertChain_empty_diskdb(b *testing.B) { - benchInsertChain(b, true, nil) -} -func BenchmarkInsertChain_valueTx_memdb(b *testing.B) { - benchInsertChain(b, false, genValueTx(0)) -} -func BenchmarkInsertChain_valueTx_diskdb(b *testing.B) { - benchInsertChain(b, true, genValueTx(0)) -} -func BenchmarkInsertChain_valueTx_100kB_memdb(b *testing.B) { - benchInsertChain(b, false, genValueTx(100*1024)) -} -func BenchmarkInsertChain_valueTx_100kB_diskdb(b *testing.B) { - benchInsertChain(b, true, genValueTx(100*1024)) -} -func BenchmarkInsertChain_ring200_memdb(b *testing.B) { - benchInsertChain(b, false, genTxRing(200)) -} -func BenchmarkInsertChain_ring200_diskdb(b *testing.B) { - benchInsertChain(b, true, genTxRing(200)) -} -func BenchmarkInsertChain_ring1000_memdb(b *testing.B) { - benchInsertChain(b, false, genTxRing(1000)) -} -func BenchmarkInsertChain_ring1000_diskdb(b *testing.B) { - benchInsertChain(b, true, genTxRing(1000)) -} - -var ( - // This is the content of the genesis block used by the benchmarks. - benchRootKey = FakeKey(1) - benchRootAddr = crypto.PubkeyToAddress(benchRootKey.PublicKey) - benchRootFunds = math.BigPow(2, 100) -) - -// genValueTx returns a block generator that includes a single -// value-transfer transaction with n bytes of extra data in each -// block. -func genValueTx(nbytes int) func(int, *BlockGen) { - return func(i int, gen *BlockGen) { - toaddr := common.Address{} - data := make([]byte, nbytes) - gas, _ := IntrinsicGas(data, types.AccessList{}, false) - tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey) - gen.AddTx(tx) - } -} - -var ( - ringKeys = make([]*ecdsa.PrivateKey, 1000) - ringAddrs = make([]common.Address, len(ringKeys)) -) - -func init() { - ringKeys[0] = benchRootKey - ringAddrs[0] = benchRootAddr - for i := 1; i < len(ringKeys); i++ { - ringKeys[i], _ = crypto.GenerateKey() - ringAddrs[i] = crypto.PubkeyToAddress(ringKeys[i].PublicKey) - } -} - -// genTxRing returns a block generator that sends ether in a ring -// among n accounts. This is creates n entries in the state database -// and fills the blocks with many small transactions. -func genTxRing(naccounts int) func(int, *BlockGen) { - from := 0 - return func(i int, gen *BlockGen) { - block := gen.PrevBlock(i - 1) - gas := block.GasLimit - for { - gas -= params.TxGas - if gas < params.TxGas { - break - } - to := (from + 1) % naccounts - tx := types.NewTransaction( - gen.TxNonce(ringAddrs[from]), - ringAddrs[to], - benchRootFunds, - params.TxGas, - nil, - nil, - ) - tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from]) - gen.AddTx(tx) - from = to - } - } -} - -func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { - // Create the database in memory or in a temporary directory. - var db ethdb.Database - if !disk { - db = rawdb.NewMemoryDatabase() - } else { - dir, err := ioutil.TempDir("", "eth-core-bench") - if err != nil { - b.Fatalf("cannot create temporary directory: %v", err) - } - defer os.RemoveAll(dir) - db, err = rawdb.NewLevelDBDatabase(dir, 128, 128, "", false) - if err != nil { - b.Fatalf("cannot create temporary database: %v", err) - } - defer db.Close() - } - - // Generate a chain of b.N blocks using the supplied block - // generator function. - // state - statedb, err := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(db), nil, 128) - if err != nil { - b.Fatalf("cannot create statedb: %v", err) - } - genesisBlock := MustApplyFakeGenesis(statedb, FakeGenesisTime, map[common.Address]*big.Int{ - benchRootAddr: benchRootFunds, - }) - genesisBlock.GasLimit = 1000000 - - // Time the insertion of the new chain. - // State and blocks are stored in the same DB. - b.ReportAllocs() - b.ResetTimer() - - _, _, _ = GenerateChain(nil, genesisBlock, db, b.N, gen) -} diff --git a/evmcore/chain_makers.go b/evmcore/chain_makers.go index 09d731681..3e9638092 100644 --- a/evmcore/chain_makers.go +++ b/evmcore/chain_makers.go @@ -18,17 +18,14 @@ package evmcore import ( "fmt" - "math/big" - "time" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" + "math/big" "github.com/Fantom-foundation/go-opera/inter" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" ) @@ -39,7 +36,7 @@ type BlockGen struct { parent *EvmBlock chain []*EvmBlock header *EvmHeader - statedb state.StateDbInterface + statedb state.StateDB gasPool *GasPool txs []*types.Transaction @@ -100,7 +97,7 @@ func (b *BlockGen) AddTxWithChain(bc DummyChain, tx *types.Transaction) { b.statedb.Prepare(tx.Hash(), len(b.txs)) blockContext := NewEVMBlockContext(b.header, bc, nil) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.config, opera.DefaultVMConfig) - receipt, _, _, err := applyTransaction(msg, b.config, b.gasPool, b.statedb, b.header.Number, b.header.Hash, tx, &b.header.GasUsed, vmenv, func(log *types.Log, db state.StateDbInterface) {}) + receipt, _, _, err := applyTransaction(msg, b.config, b.gasPool, b.statedb, b.header.Number, b.header.Hash, tx, &b.header.GasUsed, vmenv, func(log *types.Log) {}) if err != nil { panic(err) } @@ -172,82 +169,3 @@ func (b *BlockGen) OffsetTime(seconds int64) { panic("block time out of range") } } - -// GenerateChain creates a chain of n blocks. The first block's -// parent will be the provided parent. db is used to store -// intermediate states and should contain the parent's state trie. -// -// The generator function is called with a new block generator for -// every block. Any transactions and uncles added to the generator -// become part of the block. If gen is nil, the blocks will be empty -// and their coinbase will be the zero address. -// -// Blocks created by GenerateChain do not contain valid proof of work -// values. Inserting them into BlockChain requires use of FakePow or -// a similar non-validating proof of work implementation. -func GenerateChain(config *params.ChainConfig, parent *EvmBlock, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*EvmBlock, []types.Receipts, DummyChain) { - if config == nil { - config = params.AllEthashProtocolChanges - } - - chain := &TestChain{ - headers: map[common.Hash]*EvmHeader{}, - } - - blocks, receipts := make([]*EvmBlock, n), make([]types.Receipts, n) - genblock := func(i int, parent *EvmBlock, statedb state.StateDbInterface) (*EvmBlock, types.Receipts) { - b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config} - b.header = makeHeader(parent) - - // Execute any user modifications to the block - if gen != nil { - gen(i, b) - } - // Finalize and seal the block - block := &EvmBlock{ - EvmHeader: *b.header, - } - - // Write state changes to db - root, err := flush(statedb, config.IsEIP158(b.header.Number)) - if err != nil { - panic(fmt.Sprintf("state flush error: %v", err)) - } - - b.header = block.Header() - block.Root = root - - return block, b.receipts - } - for i := 0; i < n; i++ { - statedb, err := state.NewLegacyWithSnapLayers(parent.Root, state.NewDatabase(db), nil, 128) - if err != nil { - panic(err) - } - block, receipt := genblock(i, parent, statedb) - blocks[i] = block - receipts[i] = receipt - parent = block - - chain.headers[block.Hash] = block.Header() - } - return blocks, receipts, chain -} - -func makeHeader(parent *EvmBlock) *EvmHeader { - var t inter.Timestamp - if parent.Time == 0 { - t = 10 - } else { - t = parent.Time + inter.Timestamp(10*time.Second) // block time is fixed at 10 seconds - } - header := &EvmHeader{ - ParentHash: parent.Hash, - Coinbase: parent.Coinbase, - GasLimit: parent.GasLimit, - BaseFee: parent.BaseFee, - Number: new(big.Int).Add(parent.Number, common.Big1), - Time: t, - } - return header -} diff --git a/evmcore/state_processor.go b/evmcore/state_processor.go index 0710ba851..322072f2a 100644 --- a/evmcore/state_processor.go +++ b/evmcore/state_processor.go @@ -21,12 +21,12 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/utils/signers/gsignercache" "github.com/Fantom-foundation/go-opera/utils/signers/internaltx" ) @@ -56,7 +56,7 @@ func NewStateProcessor(config *params.ChainConfig, bc DummyChain) *StateProcesso // returns the amount of gas that was used in the process. If any of the // transactions failed to execute due to insufficient gas it will return an error. func (p *StateProcessor) Process( - block *EvmBlock, statedb state.StateDbInterface, cfg vm.Config, usedGas *uint64, onNewLog func(*types.Log, state.StateDbInterface), + block *EvmBlock, statedb state.StateDB, cfg vm.Config, usedGas *uint64, onNewLog func(*types.Log), ) ( receipts types.Receipts, allLogs []*types.Log, skipped []uint32, err error, ) { @@ -99,13 +99,13 @@ func applyTransaction( msg types.Message, config *params.ChainConfig, gp *GasPool, - statedb state.StateDbInterface, + statedb state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, - onNewLog func(*types.Log, state.StateDbInterface), + onNewLog func(*types.Log), ) ( *types.Receipt, uint64, @@ -124,7 +124,7 @@ func applyTransaction( // Notify about logs with potential state changes logs := statedb.GetLogs(tx.Hash(), blockHash) for _, l := range logs { - onNewLog(l, statedb) + onNewLog(l) } // Update the state with pending changes. diff --git a/evmcore/tx_noncer.go b/evmcore/tx_noncer.go index 5b71f6c48..691e4ccbf 100644 --- a/evmcore/tx_noncer.go +++ b/evmcore/tx_noncer.go @@ -20,20 +20,19 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" ) // txNoncer is a tiny virtual state database to manage the executable nonces of // accounts in the pool, falling back to reading from a real state database if // an account is unknown. type txNoncer struct { - fallback state.StateDbInterface + fallback TxPoolStateDB nonces map[common.Address]uint64 lock sync.Mutex } // newTxNoncer creates a new virtual state database to track the pool nonces. -func newTxNoncer(statedb state.StateDbInterface) *txNoncer { +func newTxNoncer(statedb TxPoolStateDB) *txNoncer { return &txNoncer{ fallback: statedb, nonces: make(map[common.Address]uint64), diff --git a/evmcore/tx_pool.go b/evmcore/tx_pool.go index 54b09d582..47efc9161 100644 --- a/evmcore/tx_pool.go +++ b/evmcore/tx_pool.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/consensus/misc" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" notify "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -143,12 +142,18 @@ const ( TxStatusIncluded ) +type TxPoolStateDB interface { + GetNonce(addr common.Address) uint64 + GetBalance(addr common.Address) *big.Int + Release() +} + // StateReader provides the state of blockchain and current gas limit to do // some pre checks in tx pool and event subscribers. type StateReader interface { CurrentBlock() *EvmBlock GetBlock(hash common.Hash, number uint64) *EvmBlock - GetTxPoolStateDB() (state.StateDbInterface, error) + GetTxPoolStateDB() (TxPoolStateDB, error) MinGasPrice() *big.Int EffectiveMinTip() *big.Int MaxGasLimit() uint64 @@ -251,7 +256,7 @@ type TxPool struct { eip2718 bool // Fork indicator whether we are using EIP-2718 type transactions. eip1559 bool // Fork indicator whether we are using EIP-1559 type transactions. - currentState state.StateDbInterface // Current state in the blockchain head + currentState TxPoolStateDB // Current state in the blockchain head pendingNonces *txNoncer // Pending state tracking virtual nonces currentMaxGas uint64 // Current gas limit for transaction caps diff --git a/evmcore/tx_pool_test.go b/evmcore/tx_pool_test.go index 11f88472b..5e1a86ce2 100644 --- a/evmcore/tx_pool_test.go +++ b/evmcore/tx_pool_test.go @@ -28,8 +28,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" @@ -55,8 +53,32 @@ func init() { eip1559Config.LondonBlock = common.Big0 } +type testTxPoolStateDb struct { + balances map[common.Address]*big.Int + nonces map[common.Address]uint64 +} + +func newTestTxPoolStateDb() *testTxPoolStateDb { + return &testTxPoolStateDb{ + balances: make(map[common.Address]*big.Int), + nonces: make(map[common.Address]uint64), + } +} + +func (t testTxPoolStateDb) GetNonce(addr common.Address) uint64 { + return t.nonces[addr] +} + +func (t testTxPoolStateDb) GetBalance(addr common.Address) *big.Int { + return t.balances[addr] +} + +func (t testTxPoolStateDb) Release() { + // no-op +} + type testBlockChain struct { - statedb state.StateDbInterface + statedb *testTxPoolStateDb gasLimit uint64 chainHeadFeed *event.Feed } @@ -96,7 +118,7 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *EvmBlock { return bc.CurrentBlock() } -func (bc *testBlockChain) GetTxPoolStateDB() (state.StateDbInterface, error) { +func (bc *testBlockChain) GetTxPoolStateDB() (TxPoolStateDB, error) { return bc.statedb, nil } @@ -141,8 +163,7 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { } func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) { - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) - blockchain := &testBlockChain{statedb, 10000000, new(event.Feed)} + blockchain := &testBlockChain{newTestTxPoolStateDb(), 10000000, new(event.Feed)} key, _ := crypto.GenerateKey() pool := NewTxPool(testTxPoolConfig, config, blockchain) @@ -228,12 +249,12 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { var ( key, _ = crypto.GenerateKey() address = crypto.PubkeyToAddress(key.PublicKey) - statedb, _ = state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb = newTestTxPoolStateDb() trigger = false ) // setup pool with 2 transaction in it - statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) + statedb.balances[address] = new(big.Int).SetUint64(params.Ether) blockchain := &testChain{&testBlockChain{statedb, 1000000000, new(event.Feed)}, address, &trigger} tx0 := transaction(0, 100000, key) @@ -270,13 +291,18 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { func testAddBalance(pool *TxPool, addr common.Address, amount *big.Int) { pool.mu.Lock() - pool.currentState.AddBalance(addr, amount) + original := pool.currentState.(*testTxPoolStateDb).balances[addr] + if original == nil { + pool.currentState.(*testTxPoolStateDb).balances[addr] = amount + } else { + pool.currentState.(*testTxPoolStateDb).balances[addr] = original.Add(original, amount) + } pool.mu.Unlock() } func testSetNonce(pool *TxPool, addr common.Address, nonce uint64) { pool.mu.Lock() - pool.currentState.SetNonce(addr, nonce) + pool.currentState.(*testTxPoolStateDb).nonces[addr] = nonce pool.mu.Unlock() } @@ -429,8 +455,8 @@ func TestTransactionChainFork(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) - statedb.AddBalance(addr, big.NewInt(100000000000000)) + statedb := newTestTxPoolStateDb() + statedb.balances[addr] = big.NewInt(100000000000000) pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} <-pool.requestReset(nil, nil) @@ -458,8 +484,8 @@ func TestTransactionDoubleNonce(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) - statedb.AddBalance(addr, big.NewInt(100000000000000)) + statedb := newTestTxPoolStateDb() + statedb.balances[addr] = big.NewInt(100000000000000) pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} <-pool.requestReset(nil, nil) @@ -658,8 +684,7 @@ func TestTransactionPostponing(t *testing.T) { t.Parallel() // Create the pool to test the postponing with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{newTestTxPoolStateDb(), 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -871,8 +896,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{newTestTxPoolStateDb(), 1000000, new(event.Feed)} config := testTxPoolConfig config.NoLocals = nolocals @@ -963,7 +987,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { evictionInterval = time.Millisecond * 100 // Create the pool to test the non-expiration enforcement - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1034,8 +1058,8 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { } // remove current transactions and increase nonce to prepare for a reset and cleanup - statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2) - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) + statedb.nonces[crypto.PubkeyToAddress(remote.PublicKey)] = 2 + statedb.nonces[crypto.PubkeyToAddress(local.PublicKey)] = 2 <-pool.requestReset(nil, nil) // make sure queue, pending are cleared @@ -1102,7 +1126,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { func TestTransactionQueueTruncating(t *testing.T) { // Create the pool to test the queue truncation when GlobalQueue is exceeded - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1208,7 +1232,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1310,7 +1334,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1344,7 +1368,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1392,7 +1416,7 @@ func TestTransactionPoolRepricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -1640,7 +1664,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain) @@ -1713,7 +1737,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1819,7 +1843,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -2051,7 +2075,7 @@ func TestTransactionDeduplication(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -2117,7 +2141,7 @@ func TestTransactionReplacement(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -2322,7 +2346,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { os.Remove(journal) // Create the original pool to inject transaction into the journal - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -2364,7 +2388,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { } // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive pool.Stop() - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) + statedb.nonces[crypto.PubkeyToAddress(local.PublicKey)] = 1 blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} pool = NewTxPool(config, params.TestChainConfig, blockchain) @@ -2386,12 +2410,12 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { t.Fatalf("pool internal state corrupted: %v", err) } // Bump the nonce temporarily and ensure the newly invalidated transaction is removed - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) + statedb.nonces[crypto.PubkeyToAddress(local.PublicKey)] = 2 <-pool.requestReset(nil, nil) time.Sleep(2 * config.Rejournal) pool.Stop() - statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) + statedb.nonces[crypto.PubkeyToAddress(local.PublicKey)] = 1 blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} pool = NewTxPool(config, params.TestChainConfig, blockchain) @@ -2420,7 +2444,7 @@ func TestTransactionStatusCheck(t *testing.T) { t.Parallel() // Create the pool to test the status retrievals with - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -2489,7 +2513,7 @@ func TestTransactionSlotCount(t *testing.T) { } func TestSampleHashes(t *testing.T) { - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -2568,7 +2592,7 @@ func TestSampleHashes(t *testing.T) { } func TestSampleHashesManySenders(t *testing.T) { - statedb, _ := state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil, 128) + statedb := newTestTxPoolStateDb() blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) diff --git a/gossip/blockproc/drivermodule/driver_txs.go b/gossip/blockproc/drivermodule/driver_txs.go index 9f0354529..8edd7f485 100644 --- a/gossip/blockproc/drivermodule/driver_txs.go +++ b/gossip/blockproc/drivermodule/driver_txs.go @@ -7,7 +7,6 @@ import ( "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -15,6 +14,7 @@ import ( "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/drivertype" "github.com/Fantom-foundation/go-opera/inter/iblockproc" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/inter/validatorpk" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/opera/contracts/driver" @@ -32,7 +32,7 @@ func NewDriverTxListenerModule() *DriverTxListenerModule { return &DriverTxListenerModule{} } -func (m *DriverTxListenerModule) Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, statedb state.StateDbInterface) blockproc.TxListener { +func (m *DriverTxListenerModule) Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, statedb state.StateDB) blockproc.TxListener { return &DriverTxListener{ block: block, es: es, @@ -45,7 +45,7 @@ type DriverTxListener struct { block iblockproc.BlockCtx es iblockproc.EpochState bs iblockproc.BlockState - statedb state.StateDbInterface + statedb state.StateDB } type DriverTxTransactor struct{} @@ -60,7 +60,7 @@ func NewDriverTxPreTransactor() *DriverTxPreTransactor { return &DriverTxPreTransactor{} } -func InternalTxBuilder(statedb state.StateDbInterface) func(calldata []byte, addr common.Address) *types.Transaction { +func InternalTxBuilder(statedb state.StateDB) func(calldata []byte, addr common.Address) *types.Transaction { nonce := uint64(math.MaxUint64) return func(calldata []byte, addr common.Address) *types.Transaction { if nonce == math.MaxUint64 { @@ -79,7 +79,7 @@ func maxBlockIdx(a, b idx.Block) idx.Block { return b } -func (p *DriverTxPreTransactor) PopInternalTxs(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb state.StateDbInterface) types.Transactions { +func (p *DriverTxPreTransactor) PopInternalTxs(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb state.StateDB) types.Transactions { buildTx := InternalTxBuilder(statedb) internalTxs := make(types.Transactions, 0, 8) @@ -117,7 +117,7 @@ func (p *DriverTxPreTransactor) PopInternalTxs(block iblockproc.BlockCtx, bs ibl return internalTxs } -func (p *DriverTxTransactor) PopInternalTxs(_ iblockproc.BlockCtx, _ iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb state.StateDbInterface) types.Transactions { +func (p *DriverTxTransactor) PopInternalTxs(_ iblockproc.BlockCtx, _ iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb state.StateDB) types.Transactions { buildTx := InternalTxBuilder(statedb) internalTxs := make(types.Transactions, 0, 1) // push data into Driver after epoch sealing diff --git a/gossip/blockproc/evmmodule/evm.go b/gossip/blockproc/evmmodule/evm.go index d483f8bcf..72c4b2b21 100644 --- a/gossip/blockproc/evmmodule/evm.go +++ b/gossip/blockproc/evmmodule/evm.go @@ -5,7 +5,6 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -14,6 +13,7 @@ import ( "github.com/Fantom-foundation/go-opera/gossip/blockproc" "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/iblockproc" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/utils" ) @@ -24,7 +24,7 @@ func New() *EVMModule { return &EVMModule{} } -func (p *EVMModule) Start(block iblockproc.BlockCtx, statedb state.StateDbInterface, reader evmcore.DummyChain, onNewLog func(*types.Log), net opera.Rules, evmCfg *params.ChainConfig) blockproc.EVMProcessor { +func (p *EVMModule) Start(block iblockproc.BlockCtx, statedb state.StateDB, reader evmcore.DummyChain, onNewLog func(*types.Log), net opera.Rules, evmCfg *params.ChainConfig) blockproc.EVMProcessor { var prevBlockHash common.Hash if block.Idx != 0 { prevBlockHash = reader.GetHeader(common.Hash{}, uint64(block.Idx-1)).Hash @@ -48,7 +48,7 @@ func (p *EVMModule) Start(block iblockproc.BlockCtx, statedb state.StateDbInterf type OperaEVMProcessor struct { block iblockproc.BlockCtx reader evmcore.DummyChain - statedb state.StateDbInterface + statedb state.StateDB onNewLog func(*types.Log) net opera.Rules evmCfg *params.ChainConfig @@ -89,7 +89,7 @@ func (p *OperaEVMProcessor) Execute(txs types.Transactions) types.Receipts { // Process txs evmBlock := p.evmBlockWith(txs) - receipts, _, skipped, err := evmProcessor.Process(evmBlock, p.statedb, opera.DefaultVMConfig, &p.gasUsed, func(l *types.Log, _ state.StateDbInterface) { + receipts, _, skipped, err := evmProcessor.Process(evmBlock, p.statedb, opera.DefaultVMConfig, &p.gasUsed, func(l *types.Log) { // Note: l.Index is properly set before l.TxIndex += txsOffset p.onNewLog(l) diff --git a/gossip/blockproc/interface.go b/gossip/blockproc/interface.go index 41df3695f..b11a25a0d 100644 --- a/gossip/blockproc/interface.go +++ b/gossip/blockproc/interface.go @@ -2,13 +2,13 @@ package blockproc import ( "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/Fantom-foundation/go-opera/evmcore" "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/iblockproc" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" ) @@ -20,11 +20,11 @@ type TxListener interface { } type TxListenerModule interface { - Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, statedb state.StateDbInterface) TxListener + Start(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, statedb state.StateDB) TxListener } type TxTransactor interface { - PopInternalTxs(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb state.StateDbInterface) types.Transactions + PopInternalTxs(block iblockproc.BlockCtx, bs iblockproc.BlockState, es iblockproc.EpochState, sealing bool, statedb state.StateDB) types.Transactions } type SealerProcessor interface { @@ -52,5 +52,5 @@ type EVMProcessor interface { } type EVM interface { - Start(block iblockproc.BlockCtx, statedb state.StateDbInterface, reader evmcore.DummyChain, onNewLog func(*types.Log), net opera.Rules, evmCfg *params.ChainConfig) EVMProcessor + Start(block iblockproc.BlockCtx, statedb state.StateDB, reader evmcore.DummyChain, onNewLog func(*types.Log), net opera.Rules, evmCfg *params.ChainConfig) EVMProcessor } diff --git a/gossip/c_block_callbacks.go b/gossip/c_block_callbacks.go index 4354e15b2..72486c55e 100644 --- a/gossip/c_block_callbacks.go +++ b/gossip/c_block_callbacks.go @@ -35,23 +35,7 @@ var ( headHeaderGauge = metrics.GetOrRegisterGauge("chain/head/header", nil) headFastBlockGauge = metrics.GetOrRegisterGauge("chain/head/receipt", nil) - accountReadTimer = metrics.GetOrRegisterTimer("chain/account/reads", nil) - accountHashTimer = metrics.GetOrRegisterTimer("chain/account/hashes", nil) - accountUpdateTimer = metrics.GetOrRegisterTimer("chain/account/updates", nil) - accountCommitTimer = metrics.GetOrRegisterTimer("chain/account/commits", nil) - - storageReadTimer = metrics.GetOrRegisterTimer("chain/storage/reads", nil) - storageHashTimer = metrics.GetOrRegisterTimer("chain/storage/hashes", nil) - storageUpdateTimer = metrics.GetOrRegisterTimer("chain/storage/updates", nil) - storageCommitTimer = metrics.GetOrRegisterTimer("chain/storage/commits", nil) - - snapshotAccountReadTimer = metrics.GetOrRegisterTimer("chain/snapshot/account/reads", nil) - snapshotStorageReadTimer = metrics.GetOrRegisterTimer("chain/snapshot/storage/reads", nil) - snapshotCommitTimer = metrics.GetOrRegisterTimer("chain/snapshot/commits", nil) - - blockInsertTimer = metrics.GetOrRegisterTimer("chain/inserts", nil) blockExecutionTimer = metrics.GetOrRegisterTimer("chain/execution", nil) - blockWriteTimer = metrics.GetOrRegisterTimer("chain/write", nil) blockAgeGauge = metrics.GetOrRegisterGauge("chain/block/age", nil) processedTxsMeter = metrics.GetOrRegisterMeter("chain/txs/processed", nil) @@ -405,18 +389,7 @@ func consensusCallbackBeginBlockFn( updateLowestEpochToFill(es.Epoch, store) // Update the metrics touched during block processing - accountReadTimer.Update(statedb.GetAccountReads()) - storageReadTimer.Update(statedb.GetStorageReads()) - accountUpdateTimer.Update(statedb.GetAccountUpdates()) - storageUpdateTimer.Update(statedb.GetStorageUpdates()) - snapshotAccountReadTimer.Update(statedb.GetSnapshotAccountReads()) - snapshotStorageReadTimer.Update(statedb.GetSnapshotStorageReads()) - accountHashTimer.Update(statedb.GetAccountHashes()) - storageHashTimer.Update(statedb.GetStorageHashes()) - triehash := statedb.GetAccountHashes() + statedb.GetStorageHashes() - trieproc := statedb.GetSnapshotAccountReads() + statedb.GetAccountReads() + statedb.GetAccountUpdates() - trieproc += statedb.GetSnapshotStorageReads() + statedb.GetStorageReads() + statedb.GetStorageUpdates() - blockExecutionTimer.Update(time.Since(executionStart) - trieproc - triehash) + blockExecutionTimer.Update(time.Since(executionStart)) // Update the metrics touched by new block headBlockGauge.Update(int64(blockCtx.Idx)) @@ -435,16 +408,6 @@ func consensusCallbackBeginBlockFn( feed.newLogs.Send(logs) } - commitStart := time.Now() - store.commitEVM() - - // Update the metrics touched during block commit - accountCommitTimer.Update(statedb.GetAccountCommits()) - storageCommitTimer.Update(statedb.GetStorageCommits()) - snapshotCommitTimer.Update(statedb.GetSnapshotCommits()) - blockWriteTimer.Update(time.Since(commitStart) - statedb.GetAccountCommits() - statedb.GetStorageCommits() - statedb.GetSnapshotCommits()) - blockInsertTimer.UpdateSince(start) - now := time.Now() blockAge := now.Sub(block.Time.Time()) log.Info("New block", "index", blockCtx.Idx, "id", block.Atropos, "gas_used", diff --git a/gossip/common_test.go b/gossip/common_test.go index 5bb553892..567050384 100644 --- a/gossip/common_test.go +++ b/gossip/common_test.go @@ -20,7 +20,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -32,6 +31,7 @@ import ( "github.com/Fantom-foundation/go-opera/integration/makefakegenesis" "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/iblockproc" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/inter/validatorpk" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/utils" @@ -376,7 +376,7 @@ func (env *testEnv) ReadOnly() *bind.CallOpts { return &bind.CallOpts{} } -func (env *testEnv) State() state.StateDbInterface { +func (env *testEnv) State() state.StateDB { statedb, err := env.store.evm.GetTxPoolStateDB() if err != nil { panic(err) @@ -436,7 +436,7 @@ func (env *testEnv) HeaderByNumber(ctx context.Context, number *big.Int) (*types // callContract implements common code between normal and pending contract calls. // state is modified during execution, make sure to copy it if necessary. func (env *testEnv) callContract( - ctx context.Context, call ethereum.CallMsg, block *evmcore.EvmBlock, state state.StateDbInterface, + ctx context.Context, call ethereum.CallMsg, block *evmcore.EvmBlock, state state.StateDB, ) ( ret []byte, usedGas uint64, failed bool, err error, ) { diff --git a/gossip/emitter/emitter.go b/gossip/emitter/emitter.go index 36c281338..eed9682d9 100644 --- a/gossip/emitter/emitter.go +++ b/gossip/emitter/emitter.go @@ -32,9 +32,6 @@ const ( ) var ( - emittingTriedCounter = metrics.GetOrRegisterCounter("emitter/tried", nil) // amount of tries to emit an event - emittingTriedTxsCounter = metrics.GetOrRegisterCounter("emitter/triedtxs", nil) // amount of sortedTxs tried to emit - emittingTxsCountHistogram = metrics.GetOrRegisterHistogram("emitter/txscounthistogram", nil, metrics.NewExpDecaySample(1028, 0.015)) emittedEventsCounter = metrics.GetOrRegisterCounter("emitter/events", nil) // amount of emitted events emittedEventsTxsCounter = metrics.GetOrRegisterCounter("emitter/txs", nil) // amount of txs in emitted events emittedGasCounter = metrics.GetOrRegisterCounter("emitter/gas", nil) // consumed validator gas @@ -259,11 +256,6 @@ func (em *Emitter) EmitEvent() (*inter.EventPayload, error) { return nil, nil } - sortedTxsLen := int64(sortedTxs.Len()) - emittingTriedCounter.Inc(1) - emittingTriedTxsCounter.Inc(sortedTxsLen) - emittingTxsCountHistogram.Update(sortedTxsLen) - em.world.Lock() defer em.world.Unlock() diff --git a/gossip/emitter/mock/world.go b/gossip/emitter/mock/world.go index dd36dd1c9..8a8072c76 100644 --- a/gossip/emitter/mock/world.go +++ b/gossip/emitter/mock/world.go @@ -16,9 +16,9 @@ import ( idx "github.com/Fantom-foundation/lachesis-base/inter/idx" pos "github.com/Fantom-foundation/lachesis-base/inter/pos" common "github.com/ethereum/go-ethereum/common" - state "github.com/ethereum/go-ethereum/core/state" types "github.com/ethereum/go-ethereum/core/types" gomock "github.com/golang/mock/gomock" + "github.com/Fantom-foundation/go-opera/inter/state" ) // MockExternal is a mock of External interface. @@ -378,10 +378,10 @@ func (mr *MockExternalMockRecorder) Process(arg0 interface{}) *gomock.Call { } // StateDB mocks base method. -func (m *MockExternal) StateDB() state.StateDbInterface { +func (m *MockExternal) StateDB() state.StateDB { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StateDB") - ret0, _ := ret[0].(state.StateDbInterface) + ret0, _ := ret[0].(state.StateDB) return ret0 } diff --git a/gossip/emitter/txs.go b/gossip/emitter/txs.go index 84e2a2ef4..95323fd59 100644 --- a/gossip/emitter/txs.go +++ b/gossip/emitter/txs.go @@ -154,36 +154,35 @@ func (em *Emitter) addTxs(e *inter.MutableEventPayload, sorted *types.Transactio sender, _ := types.Sender(em.world.TxSigner, tx) // check transaction epoch rules (tx type, gas price) if epochcheck.CheckTxs(types.Transactions{tx}, rules) != nil { - txsSkippedEpochRules.Inc(int64(sorted.GetCountToPop())) + txsSkippedEpochRules.Inc(1) sorted.Pop() continue } // check there's enough gas power to originate the transaction if tx.Gas() >= e.GasPowerLeft().Min() || e.GasPowerUsed()+tx.Gas() >= maxGasUsed { + txsSkippedNoValidatorGas.Inc(1) if params.TxGas >= e.GasPowerLeft().Min() || e.GasPowerUsed()+params.TxGas >= maxGasUsed { // stop if cannot originate even an empty transaction - txsSkippedNoValidatorGas.Inc(int64(sorted.Len())) break } - txsSkippedNoValidatorGas.Inc(int64(sorted.GetCountToPop())) sorted.Pop() continue } // check not conflicted with already originated txs (in any connected event) if em.originatedTxs.TotalOf(sender) != 0 { - txsSkippedConflictingSender.Inc(int64(sorted.GetCountToPop())) + txsSkippedConflictingSender.Inc(1) sorted.Pop() continue } // my turn, i.e. try to not include the same tx simultaneously by different validators if !em.isMyTxTurn(tx.Hash(), sender, tx.Nonce(), time.Now(), em.validators, e.Creator(), em.epoch) { - txsSkippedNotMyTurn.Inc(int64(sorted.GetCountToPop())) + txsSkippedNotMyTurn.Inc(1) sorted.Pop() continue } // check transaction is not outdated if !em.world.TxPool.Has(tx.Hash()) { - txsSkippedOutdated.Inc(int64(sorted.GetCountToPop())) + txsSkippedOutdated.Inc(1) sorted.Pop() continue } diff --git a/gossip/emitter/world.go b/gossip/emitter/world.go index b841a6c3d..be13ef6d5 100644 --- a/gossip/emitter/world.go +++ b/gossip/emitter/world.go @@ -8,10 +8,10 @@ import ( "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/Fantom-foundation/lachesis-base/inter/pos" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/Fantom-foundation/go-opera/inter" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/valkeystore" "github.com/Fantom-foundation/go-opera/vecmt" @@ -37,7 +37,7 @@ type ( IsSynced() bool PeersNum() int - StateDB() state.StateDbInterface + StateDB() state.StateDB } // aliases for mock generator diff --git a/gossip/emitter_world.go b/gossip/emitter_world.go index 9c9ca1b79..78d495243 100644 --- a/gossip/emitter_world.go +++ b/gossip/emitter_world.go @@ -5,11 +5,11 @@ import ( "github.com/Fantom-foundation/lachesis-base/hash" "github.com/Fantom-foundation/lachesis-base/inter/idx" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/Fantom-foundation/go-opera/gossip/emitter" "github.com/Fantom-foundation/go-opera/inter" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/utils/wgmutex" "github.com/Fantom-foundation/go-opera/valkeystore" "github.com/Fantom-foundation/go-opera/vecmt" @@ -61,7 +61,7 @@ func (ew *emitterWorldProc) IsBusy() bool { return atomic.LoadUint32(&ew.s.eventBusyFlag) != 0 || atomic.LoadUint32(&ew.s.blockBusyFlag) != 0 } -func (ew *emitterWorldProc) StateDB() state.StateDbInterface { +func (ew *emitterWorldProc) StateDB() state.StateDB { statedb, err := ew.s.store.evm.GetTxPoolStateDB() if err != nil { return nil diff --git a/gossip/ethapi_backend.go b/gossip/ethapi_backend.go index 72cad7777..fa9ee27a8 100644 --- a/gossip/ethapi_backend.go +++ b/gossip/ethapi_backend.go @@ -12,7 +12,6 @@ import ( "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" notify "github.com/ethereum/go-ethereum/event" @@ -25,6 +24,7 @@ import ( "github.com/Fantom-foundation/go-opera/gossip/evmstore" "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/iblockproc" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/topicsdb" "github.com/Fantom-foundation/go-opera/tracing" @@ -111,7 +111,7 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe } // StateAndHeaderByNumberOrHash returns evm state and block header by block number or block hash, err if not exists. -func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (state.StateDbInterface, *evmcore.EvmHeader, error) { +func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (state.StateDB, *evmcore.EvmHeader, error) { var header *evmcore.EvmHeader if number, ok := blockNrOrHash.Number(); ok && (number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber) { var err error @@ -319,7 +319,7 @@ func (b *EthAPIBackend) GetTd(_ common.Hash) *big.Int { return big.NewInt(0) } -func (b *EthAPIBackend) GetEVM(ctx context.Context, msg evmcore.Message, state state.StateDbInterface, header *evmcore.EvmHeader, vmConfig *vm.Config) (*vm.EVM, func() error, error) { +func (b *EthAPIBackend) GetEVM(ctx context.Context, msg evmcore.Message, state vm.StateDB, header *evmcore.EvmHeader, vmConfig *vm.Config) (*vm.EVM, func() error, error) { vmError := func() error { return nil } if vmConfig == nil { diff --git a/gossip/evm_state_reader.go b/gossip/evm_state_reader.go index a8c95b972..a2a875907 100644 --- a/gossip/evm_state_reader.go +++ b/gossip/evm_state_reader.go @@ -7,12 +7,12 @@ import ( "github.com/Fantom-foundation/lachesis-base/hash" "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/Fantom-foundation/go-opera/evmcore" "github.com/Fantom-foundation/go-opera/gossip/gasprice" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" ) @@ -149,11 +149,11 @@ func (r *EvmStateReader) getBlock(h hash.Event, n idx.Block, readTxs bool) *evmc } // GetTxPoolStateDB obtains StateDB for TxPool -func (r *EvmStateReader) GetTxPoolStateDB() (state.StateDbInterface, error) { +func (r *EvmStateReader) GetTxPoolStateDB() (evmcore.TxPoolStateDB, error) { return r.store.evm.GetTxPoolStateDB() } // GetRpcStateDB obtains archive StateDB for RPC requests evaluation -func (r *EvmStateReader) GetRpcStateDB(blockNum *big.Int, stateRoot common.Hash) (state.StateDbInterface, error) { +func (r *EvmStateReader) GetRpcStateDB(blockNum *big.Int, stateRoot common.Hash) (state.StateDB, error) { return r.store.evm.GetRpcStateDb(blockNum, stateRoot) } diff --git a/gossip/evmstore/carmen.go b/gossip/evmstore/carmen.go index dd1486a98..5ce7a805f 100644 --- a/gossip/evmstore/carmen.go +++ b/gossip/evmstore/carmen.go @@ -1,18 +1,16 @@ package evmstore import ( - "encoding/json" cc "github.com/Fantom-foundation/Carmen/go/common" carmen "github.com/Fantom-foundation/Carmen/go/state" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" + ethstate "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/substate" "math/big" - "time" ) -func CreateCarmenStateDb(carmenStateDb carmen.VmStateDB) state.StateDbInterface { +func CreateCarmenStateDb(carmenStateDb carmen.VmStateDB) state.StateDB { return &CarmenStateDB{ db: carmenStateDb, } @@ -29,14 +27,6 @@ type CarmenStateDB struct { txIndex int } -func (c *CarmenStateDB) StartPrefetcher(namespace string) { - // ignored -} - -func (c *CarmenStateDB) StopPrefetcher() { - // ignored -} - func (c *CarmenStateDB) Error() error { return nil } @@ -78,18 +68,10 @@ func (c *CarmenStateDB) GetLogs(txHash common.Hash, blockHash common.Hash) []*ty return logs } -func (c *CarmenStateDB) Logs() []*types.Log { - panic("not supported") -} - func (c *CarmenStateDB) AddPreimage(hash common.Hash, preimage []byte) { // ignored - preimages of keys hashes are relevant only for geth trie } -func (c *CarmenStateDB) Preimages() map[common.Hash][]byte { - return nil // preimages of keys hashes are relevant only for geth trie -} - func (c *CarmenStateDB) AddRefund(gas uint64) { c.db.AddRefund(gas) } @@ -138,10 +120,6 @@ func (c *CarmenStateDB) GetProof(addr common.Address) ([][]byte, error) { panic("not supported") } -func (c *CarmenStateDB) GetProofByHash(addrHash common.Hash) ([][]byte, error) { - panic("not supported") -} - func (c *CarmenStateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) { panic("not supported") } @@ -150,11 +128,7 @@ func (c *CarmenStateDB) GetCommittedState(addr common.Address, hash common.Hash) return common.Hash(c.db.GetCommittedState(cc.Address(addr), cc.Key(hash))) } -func (c *CarmenStateDB) Database() state.Database { - panic("not supported") -} - -func (c *CarmenStateDB) StorageTrie(addr common.Address) state.Trie { +func (c *CarmenStateDB) StorageTrie(addr common.Address) ethstate.Trie { panic("not supported") } @@ -182,10 +156,6 @@ func (c *CarmenStateDB) SetCode(addr common.Address, code []byte) { c.db.SetCode(cc.Address(addr), code) } -func (c *CarmenStateDB) SetPrehashedCode(addr common.Address, hash common.Hash, code []byte) { - c.db.SetCode(cc.Address(addr), code) -} - func (c *CarmenStateDB) SetState(addr common.Address, key, value common.Hash) { c.db.SetState(cc.Address(addr), cc.Key(key), cc.Value(value)) } @@ -206,7 +176,7 @@ func (c *CarmenStateDB) ForEachStorage(addr common.Address, cb func(key common.H panic("not supported") } -func (c *CarmenStateDB) Copy() state.StateDbInterface { +func (c *CarmenStateDB) Copy() state.StateDB { if db, ok := c.db.(carmen.NonCommittableStateDB); ok { return CreateCarmenStateDb(db.Copy()) } else { @@ -294,86 +264,6 @@ func (c *CarmenStateDB) SlotInAccessList(addr common.Address, slot common.Hash) return c.db.IsSlotInAccessList(cc.Address(addr), cc.Key(slot)) } -func (c *CarmenStateDB) RawDump(opts *state.DumpConfig) state.Dump { - panic("not supported") -} - -func (c *CarmenStateDB) IteratorDump(opts *state.DumpConfig) state.IteratorDump { - panic("not supported") -} - -func (c *CarmenStateDB) IterativeDump(opts *state.DumpConfig, output *json.Encoder) { - panic("not supported") -} - -func (c *CarmenStateDB) Dump(opts *state.DumpConfig) []byte { - panic("not supported") -} - -func (c *CarmenStateDB) DumpToCollector(dc state.DumpCollector, conf *state.DumpConfig) (nextKey []byte) { - panic("not supported") -} - -func (c *CarmenStateDB) GetAccountReads() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetAccountHashes() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetAccountUpdates() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetAccountCommits() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetStorageReads() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetStorageHashes() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetStorageUpdates() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetStorageCommits() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetSnapshotAccountReads() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetSnapshotStorageReads() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetSnapshotCommits() time.Duration { - //TODO implement me - return 0 -} - -func (c *CarmenStateDB) GetSubstatePostAlloc() substate.SubstateAlloc { - //TODO implement me - return nil -} - func (c *CarmenStateDB) Release() { if db, ok := c.db.(carmen.NonCommittableStateDB); ok { db.Release() diff --git a/gossip/evmstore/statedb.go b/gossip/evmstore/statedb.go index 7648ea4bf..abe811893 100644 --- a/gossip/evmstore/statedb.go +++ b/gossip/evmstore/statedb.go @@ -5,15 +5,15 @@ import ( cc "github.com/Fantom-foundation/Carmen/go/common" carmen "github.com/Fantom-foundation/Carmen/go/state" _ "github.com/Fantom-foundation/Carmen/go/state/gostate" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/lachesis-base/hash" "github.com/Fantom-foundation/lachesis-base/inter/idx" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "math/big" ) // GetLiveStateDb obtains StateDB for block processing - the live writable state -func (s *Store) GetLiveStateDb(stateRoot hash.Hash) (state.StateDbInterface, error) { +func (s *Store) GetLiveStateDb(stateRoot hash.Hash) (state.StateDB, error) { if s.liveStateDb == nil { return nil, fmt.Errorf("unable to get live StateDb - EvmStore is not open") } @@ -25,7 +25,7 @@ func (s *Store) GetLiveStateDb(stateRoot hash.Hash) (state.StateDbInterface, err // GetTxPoolStateDB obtains StateDB for TxPool evaluation - the latest finalized, read-only. // It is also used in emitter for emitterdriver contract reading at the start of an epoch. -func (s *Store) GetTxPoolStateDB() (state.StateDbInterface, error) { +func (s *Store) GetTxPoolStateDB() (state.StateDB, error) { // for TxPool and emitter it is ok to provide the newest state (and ignore the expected hash) if s.carmenState == nil { return nil, fmt.Errorf("unable to get TxPool StateDb - EvmStore is not open") @@ -43,7 +43,7 @@ func (s *Store) GetArchiveBlockHeight() (height uint64, empty bool, err error) { } // GetRpcStateDb obtains archive StateDB for RPC requests evaluation -func (s *Store) GetRpcStateDb(blockNum *big.Int, stateRoot common.Hash) (state.StateDbInterface, error) { +func (s *Store) GetRpcStateDb(blockNum *big.Int, stateRoot common.Hash) (state.StateDB, error) { // always use archive state (live state may mix data from various block heights) if s.liveStateDb == nil { return nil, fmt.Errorf("unable to get RPC StateDb - EvmStore is not open") diff --git a/gossip/filters/filter_system_test.go b/gossip/filters/filter_system_test.go index d5c1e1365..608d5806f 100644 --- a/gossip/filters/filter_system_test.go +++ b/gossip/filters/filter_system_test.go @@ -26,7 +26,6 @@ import ( "github.com/Fantom-foundation/lachesis-base/kvdb/memorydb" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" notify "github.com/ethereum/go-ethereum/event" @@ -152,71 +151,6 @@ func (b *testBackend) CalcBlockExtApi() bool { return true } -// TestBlockSubscription tests if a block subscription returns block hashes for posted chain notify. -// It creates multiple subscriptions: -// - one at the start and should receive all posted chain events and a second (blockHashes) -// - one that is created after a cutoff moment and uninstalled after a second cutoff moment (blockHashes[cutoff1:cutoff2]) -// - one that is created after the second cutoff moment (blockHashes[cutoff2:]) -func TestBlockSubscription(t *testing.T) { - t.Parallel() - - var ( - backend = newTestBackend() - api = NewPublicFilterAPI(backend, testConfig()) - - statedb, _ = state.NewLegacyWithSnapLayers(common.Hash{}, state.NewDatabase(backend.db), nil, 128) - genesis = evmcore.MustApplyFakeGenesis(statedb, evmcore.FakeGenesisTime, map[common.Address]*big.Int{}) - chain, _, _ = evmcore.GenerateChain( - params.TestChainConfig, genesis, backend.db, 10, nil) - chainEvents = []evmcore.ChainHeadNotify{} - ) - - for _, blk := range chain { - chainEvents = append(chainEvents, evmcore.ChainHeadNotify{ - Block: &evmcore.EvmBlock{ - EvmHeader: blk.EvmHeader, - Transactions: blk.Transactions, - }, - }) - } - - chan0 := make(chan *types.Header) - sub0 := api.events.SubscribeNewHeads(chan0) - chan1 := make(chan *types.Header) - sub1 := api.events.SubscribeNewHeads(chan1) - - go func() { // simulate client - i1, i2 := 0, 0 - for i1 != len(chainEvents) || i2 != len(chainEvents) { - select { - case header := <-chan0: - got := common.BytesToHash(header.Extra) - if chainEvents[i1].Block.Hash != got { - t.Errorf("sub0 received invalid hash on index %d, want %x, got %x", i1, chainEvents[i1].Block.Hash, got) - } - i1++ - case header := <-chan1: - got := common.BytesToHash(header.Extra) - if chainEvents[i2].Block.Hash != got { - t.Errorf("sub1 received invalid hash on index %d, want %x, got %x", i2, chainEvents[i2].Block.Hash, got) - } - i2++ - } - } - - sub0.Unsubscribe() - sub1.Unsubscribe() - }() - - time.Sleep(1 * time.Second) - for _, e := range chainEvents { - backend.blocksFeed.Send(e) - } - - <-sub0.Err() - <-sub1.Err() -} - // TestPendingTxFilter tests whether pending tx filters retrieve all pending transactions that are posted to the event mux. func TestPendingTxFilter(t *testing.T) { t.Parallel() diff --git a/gossip/store.go b/gossip/store.go index 7db91a7ef..407c8344f 100644 --- a/gossip/store.go +++ b/gossip/store.go @@ -186,11 +186,6 @@ func (s *Store) isCommitNeeded(sc, tc uint64) bool { uint64(s.dbs.NotFlushedSizeEst()) > size } -// commitEVM commits EVM storage -func (s *Store) commitEVM() { - // removed -} - // Commit changes. func (s *Store) Commit() error { s.FlushBlockEpochState() diff --git a/integration/makegenesis/genesis.go b/integration/makegenesis/genesis.go index 2ec163b53..72b9bc9fc 100644 --- a/integration/makegenesis/genesis.go +++ b/integration/makegenesis/genesis.go @@ -4,9 +4,6 @@ import ( "bytes" "errors" "fmt" - carmen "github.com/Fantom-foundation/Carmen/go/state" - mptIo "github.com/Fantom-foundation/Carmen/go/state/mpt/io" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" "io" "math/big" "os" @@ -14,7 +11,6 @@ import ( "github.com/Fantom-foundation/lachesis-base/hash" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" @@ -24,18 +20,23 @@ import ( "github.com/Fantom-foundation/go-opera/gossip/blockproc/eventmodule" "github.com/Fantom-foundation/go-opera/gossip/blockproc/evmmodule" "github.com/Fantom-foundation/go-opera/gossip/blockproc/sealmodule" + "github.com/Fantom-foundation/go-opera/gossip/evmstore" "github.com/Fantom-foundation/go-opera/inter" "github.com/Fantom-foundation/go-opera/inter/iblockproc" "github.com/Fantom-foundation/go-opera/inter/ibr" "github.com/Fantom-foundation/go-opera/inter/ier" + "github.com/Fantom-foundation/go-opera/inter/state" "github.com/Fantom-foundation/go-opera/opera" "github.com/Fantom-foundation/go-opera/opera/genesis" "github.com/Fantom-foundation/go-opera/opera/genesisstore" + + carmen "github.com/Fantom-foundation/Carmen/go/state" + mptIo "github.com/Fantom-foundation/Carmen/go/state/mpt/io" ) type GenesisBuilder struct { - tmpStateDB state.StateDbInterface - carmenDir string + tmpStateDB state.StateDB + carmenDir string carmenStateDb carmen.StateDB totalSupply *big.Int diff --git a/inter/state/adapter.go b/inter/state/adapter.go new file mode 100644 index 000000000..76322cd7b --- /dev/null +++ b/inter/state/adapter.go @@ -0,0 +1,32 @@ +package state + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "math/big" +) + +type StateDB interface { + vm.StateDB + + Error() error + GetLogs(hash common.Hash, blockHash common.Hash) []*types.Log + TxIndex() int + GetProof(addr common.Address) ([][]byte, error) + GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) + StorageTrie(addr common.Address) state.Trie + SetBalance(addr common.Address, amount *big.Int) + SetCode(addr common.Address, code []byte) + SetStorage(addr common.Address, storage map[common.Hash]common.Hash) + Copy() StateDB + Finalise(deleteEmptyObjects bool) + IntermediateRoot(deleteEmptyObjects bool) common.Hash + Prepare(thash common.Hash, ti int) + Commit(deleteEmptyObjects bool) (common.Hash, error) + + BeginBlock(number uint64) + EndBlock(number uint64) + Release() +}