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