accounts/abi/bind/backends: add support for historical state (#20644)

This commit is contained in:
Marius van der Wijden 2020-02-12 11:33:17 +01:00 committed by GitHub
parent 1821328162
commit 46c4b699c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 12 deletions

View File

@ -127,15 +127,28 @@ func (b *SimulatedBackend) rollback() {
b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) 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. // 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) { func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { statedb, err := b.stateByBlockNumber(ctx, blockNumber)
return nil, errBlockNumberUnsupported if err != nil {
return nil, err
} }
statedb, _ := b.blockchain.State()
return statedb.GetCode(contract), nil return statedb.GetCode(contract), nil
} }
@ -144,10 +157,11 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { statedb, err := b.stateByBlockNumber(ctx, blockNumber)
return nil, errBlockNumberUnsupported if err != nil {
return nil, err
} }
statedb, _ := b.blockchain.State()
return statedb.GetBalance(contract), nil return statedb.GetBalance(contract), nil
} }
@ -156,10 +170,11 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address,
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { statedb, err := b.stateByBlockNumber(ctx, blockNumber)
return 0, errBlockNumberUnsupported if err != nil {
return 0, err
} }
statedb, _ := b.blockchain.State()
return statedb.GetNonce(contract), nil return statedb.GetNonce(contract), nil
} }
@ -168,10 +183,11 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { statedb, err := b.stateByBlockNumber(ctx, blockNumber)
return nil, errBlockNumberUnsupported if err != nil {
return nil, err
} }
statedb, _ := b.blockchain.State()
val := statedb.GetState(contract, key) val := statedb.GetState(contract, key)
return val[:], nil return val[:], nil
} }