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).
This commit is contained in:
Felix Lange
2017-06-27 15:57:06 +02:00
committed by GitHub
parent bb366271fe
commit 9e5f03b6c4
49 changed files with 810 additions and 1664 deletions

View File

@ -24,13 +24,13 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
"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/eth/downloader"
"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/light"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
@ -70,12 +70,12 @@ func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
return b.GetBlock(ctx, header.Hash())
}
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (ethapi.State, *types.Header, error) {
func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
header, err := b.HeaderByNumber(ctx, blockNr)
if header == nil || err != nil {
return nil, nil, err
}
return light.NewLightState(light.StateTrieID(header), b.eth.odr), header, nil
return light.NewState(ctx, header, b.eth.odr), header, nil
}
func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
@ -90,18 +90,10 @@ func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(blockHash)
}
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
stateDb := state.(*light.LightState).Copy()
addr := msg.From()
from, err := stateDb.GetOrNewStateObject(ctx, addr)
if err != nil {
return nil, nil, err
}
from.SetBalance(math.MaxBig256)
vmstate := light.NewVMState(ctx, stateDb)
func (b *LesApiBackend) 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)
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
return vm.NewEVM(context, vmstate, b.eth.chainConfig, vmCfg), vmstate.Error, nil
return vm.NewEVM(context, state, b.eth.chainConfig, vmCfg), state.Error, nil
}
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {

View File

@ -75,24 +75,23 @@ func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainCon
dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678")
acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr}
var res []byte
var (
res []byte
st *state.StateDB
err error
)
for _, addr := range acc {
if bc != nil {
header := bc.GetHeaderByHash(bhash)
st, err := state.New(header.Root, db)
if err == nil {
bal := st.GetBalance(addr)
rlp, _ := rlp.EncodeToBytes(bal)
res = append(res, rlp...)
}
st, err = state.New(header.Root, state.NewDatabase(db))
} else {
header := lc.GetHeaderByHash(bhash)
st := light.NewLightState(light.StateTrieID(header), lc.Odr())
bal, err := st.GetBalance(ctx, addr)
if err == nil {
rlp, _ := rlp.EncodeToBytes(bal)
res = append(res, rlp...)
}
st = light.NewState(ctx, header, lc.Odr())
}
if err == nil {
bal := st.GetBalance(addr)
rlp, _ := rlp.EncodeToBytes(bal)
res = append(res, rlp...)
}
}
@ -115,7 +114,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
data[35] = byte(i)
if bc != nil {
header := bc.GetHeaderByHash(bhash)
statedb, err := state.New(header.Root, db)
statedb, err := state.New(header.Root, state.NewDatabase(db))
if err == nil {
from := statedb.GetOrNewStateObject(testBankAddress)
@ -133,23 +132,15 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
}
} else {
header := lc.GetHeaderByHash(bhash)
state := light.NewLightState(light.StateTrieID(header), lc.Odr())
vmstate := light.NewVMState(ctx, state)
from, err := state.GetOrNewStateObject(ctx, testBankAddress)
if err == nil {
from.SetBalance(math.MaxBig256)
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, lc, nil)
vmenv := vm.NewEVM(context, vmstate, config, vm.Config{})
//vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
gp := new(core.GasPool).AddGas(math.MaxBig256)
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
if vmstate.Error() == nil {
res = append(res, ret...)
}
state := light.NewState(ctx, header, lc.Odr())
state.SetBalance(testBankAddress, math.MaxBig256)
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
context := core.NewEVMContext(msg, header, lc, nil)
vmenv := vm.NewEVM(context, state, config, vm.Config{})
gp := new(core.GasPool).AddGas(math.MaxBig256)
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
if state.Error() == nil {
res = append(res, ret...)
}
}
}

View File

@ -62,7 +62,7 @@ func tfCodeAccess(db ethdb.Database, bhash common.Hash, number uint64) light.Odr
return nil
}
sti := light.StateTrieID(header)
ci := light.StorageTrieID(sti, testContractAddr, common.Hash{})
ci := light.StorageTrieID(sti, crypto.Keccak256Hash(testContractAddr[:]), common.Hash{})
return &light.CodeRequest{Id: ci, Hash: crypto.Keccak256Hash(testContractCodeDeployed)}
}