diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2017-06-27 21:57:06 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-27 21:57:06 +0800 |
commit | 9e5f03b6c487175cc5aa1224e5e12fd573f483a7 (patch) | |
tree | 475e573ff6c7e77cd069a2f6238afdb27d4bce43 /eth | |
parent | bb366271fe33cf87b462dc5a25ac6c448ac6d2e1 (diff) | |
download | dexon-9e5f03b6c487175cc5aa1224e5e12fd573f483a7.tar.gz dexon-9e5f03b6c487175cc5aa1224e5e12fd573f483a7.tar.zst dexon-9e5f03b6c487175cc5aa1224e5e12fd573f483a7.zip |
core/state: access trie through Database interface, track errors (#14589)
With this commit, core/state's access to the underlying key/value database is
mediated through an interface. Database errors are tracked in StateDB and
returned by CommitTo or the new Error method.
Motivation for this change: We can remove the light client's duplicated copy of
core/state. The light client now supports node iteration, so tracing and storage
enumeration can work with the light client (not implemented in this commit).
Diffstat (limited to 'eth')
-rw-r--r-- | eth/api.go | 2 | ||||
-rw-r--r-- | eth/api_backend.go | 35 | ||||
-rw-r--r-- | eth/api_test.go | 2 | ||||
-rw-r--r-- | eth/bind.go | 6 | ||||
-rw-r--r-- | eth/downloader/downloader_test.go | 2 | ||||
-rw-r--r-- | eth/handler_test.go | 2 |
6 files changed, 12 insertions, 37 deletions
diff --git a/eth/api.go b/eth/api.go index 81570988c..0d90759b6 100644 --- a/eth/api.go +++ b/eth/api.go @@ -637,7 +637,7 @@ func (api *PrivateDebugAPI) StorageRangeAt(ctx context.Context, blockHash common return storageRangeAt(st, keyStart, maxResult), nil } -func storageRangeAt(st *trie.SecureTrie, start []byte, maxResult int) StorageRangeResult { +func storageRangeAt(st state.Trie, start []byte, maxResult int) StorageRangeResult { it := trie.NewIterator(st.NodeIterator(start)) result := StorageRangeResult{Storage: storageMap{}} for i := 0; i < maxResult && it.Next(); i++ { diff --git a/eth/api_backend.go b/eth/api_backend.go index fe108d272..166b5084d 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -81,11 +80,11 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil } -func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (ethapi.State, *types.Header, error) { +func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) { // Pending state is only known by the miner if blockNr == rpc.PendingBlockNumber { block, state := b.eth.miner.Pending() - return EthApiState{state}, block.Header(), nil + return state, block.Header(), nil } // Otherwise resolve the block number and return its state header, err := b.HeaderByNumber(ctx, blockNr) @@ -93,7 +92,7 @@ func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc. return nil, nil, err } stateDb, err := b.eth.BlockChain().StateAt(header.Root) - return EthApiState{stateDb}, header, err + return stateDb, header, err } func (b *EthApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) { @@ -108,14 +107,12 @@ func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int { return b.eth.blockchain.GetTdByHash(blockHash) } -func (b *EthApiBackend) GetEVM(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) { - statedb := state.(EthApiState).state - from := statedb.GetOrNewStateObject(msg.From()) - from.SetBalance(math.MaxBig256) +func (b *EthApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) { + state.SetBalance(msg.From(), math.MaxBig256) vmError := func() error { return nil } context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil) - return vm.NewEVM(context, statedb, b.eth.chainConfig, vmCfg), vmError, nil + return vm.NewEVM(context, state, b.eth.chainConfig, vmCfg), vmError, nil } func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { @@ -200,23 +197,3 @@ func (b *EthApiBackend) EventMux() *event.TypeMux { func (b *EthApiBackend) AccountManager() *accounts.Manager { return b.eth.AccountManager() } - -type EthApiState struct { - state *state.StateDB -} - -func (s EthApiState) GetBalance(ctx context.Context, addr common.Address) (*big.Int, error) { - return s.state.GetBalance(addr), nil -} - -func (s EthApiState) GetCode(ctx context.Context, addr common.Address) ([]byte, error) { - return s.state.GetCode(addr), nil -} - -func (s EthApiState) GetState(ctx context.Context, a common.Address, b common.Hash) (common.Hash, error) { - return s.state.GetState(a, b), nil -} - -func (s EthApiState) GetNonce(ctx context.Context, addr common.Address) (uint64, error) { - return s.state.GetNonce(addr), nil -} diff --git a/eth/api_test.go b/eth/api_test.go index f8d2e9c76..49ce38688 100644 --- a/eth/api_test.go +++ b/eth/api_test.go @@ -32,7 +32,7 @@ func TestStorageRangeAt(t *testing.T) { // Create a state where account 0x010000... has a few storage entries. var ( db, _ = ethdb.NewMemDatabase() - state, _ = state.New(common.Hash{}, db) + state, _ = state.New(common.Hash{}, state.NewDatabase(db)) addr = common.Address{0x01} keys = []common.Hash{ // hashes of Keys of storage common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"), diff --git a/eth/bind.go b/eth/bind.go index e5abd8617..0385db1f9 100644 --- a/eth/bind.go +++ b/eth/bind.go @@ -54,14 +54,12 @@ func NewContractBackend(apiBackend ethapi.Backend) *ContractBackend { // CodeAt retrieves any code associated with the contract from the local API. func (b *ContractBackend) CodeAt(ctx context.Context, contract common.Address, blockNum *big.Int) ([]byte, error) { - out, err := b.bcapi.GetCode(ctx, contract, toBlockNumber(blockNum)) - return common.FromHex(out), err + return b.bcapi.GetCode(ctx, contract, toBlockNumber(blockNum)) } // CodeAt retrieves any code associated with the contract from the local API. func (b *ContractBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { - out, err := b.bcapi.GetCode(ctx, contract, rpc.PendingBlockNumber) - return common.FromHex(out), err + return b.bcapi.GetCode(ctx, contract, rpc.PendingBlockNumber) } // ContractCall implements bind.ContractCaller executing an Ethereum contract diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 267a0def9..1fb5a0910 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -657,7 +657,7 @@ func assertOwnForkedChain(t *testing.T, tester *downloadTester, common int, leng index = len(tester.ownHashes) - lengths[len(lengths)-1] + int(tester.downloader.queue.fastSyncPivot) } if index > 0 { - if statedb, err := state.New(tester.ownHeaders[tester.ownHashes[index]].Root, tester.stateDb); statedb == nil || err != nil { + if statedb, err := state.New(tester.ownHeaders[tester.ownHashes[index]].Root, state.NewDatabase(tester.stateDb)); statedb == nil || err != nil { t.Fatalf("state reconstruction failed: %v", err) } } diff --git a/eth/handler_test.go b/eth/handler_test.go index 413ed2bff..ca9c9e1b4 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -374,7 +374,7 @@ func testGetNodeData(t *testing.T, protocol int) { } accounts := []common.Address{testBank, acc1Addr, acc2Addr} for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ { - trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), statedb) + trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), state.NewDatabase(statedb)) for j, acc := range accounts { state, _ := pm.blockchain.State() |