|
|
|
@ -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 |
|
|
|
|
} |
|
|
|
|