From 46c4b699c8b5b537416d395852a3f44fd7a45f49 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 12 Feb 2020 11:33:17 +0100 Subject: [PATCH] accounts/abi/bind/backends: add support for historical state (#20644) --- accounts/abi/bind/backends/simulated.go | 40 +++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 0b2555c994..f7f3dec839 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -127,15 +127,28 @@ func (b *SimulatedBackend) rollback() { b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) } +// stateByBlockNumber retrieves a state by a given blocknumber. +func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) { + if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 { + return b.blockchain.State() + } + block, err := b.BlockByNumber(ctx, blockNumber) + if err != nil { + return nil, err + } + return b.blockchain.StateAt(block.Hash()) +} + // CodeAt returns the code associated with a certain account in the blockchain. func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return nil, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return nil, err } - statedb, _ := b.blockchain.State() + return statedb.GetCode(contract), nil } @@ -144,10 +157,11 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return nil, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return nil, err } - statedb, _ := b.blockchain.State() + return statedb.GetBalance(contract), nil } @@ -156,10 +170,11 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return 0, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return 0, err } - statedb, _ := b.blockchain.State() + return statedb.GetNonce(contract), nil } @@ -168,10 +183,11 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return nil, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return nil, err } - statedb, _ := b.blockchain.State() + val := statedb.GetState(contract, key) return val[:], nil }