Skip to content

Commit

Permalink
State override support (#3628)
Browse files Browse the repository at this point in the history
* added stateOverride type

* solved import cycle

* refactoring

* imported wrong package

* fixed Call arguments

* typo

* override for traceCall
  • Loading branch information
enriavil1 authored and Alexey Sharp committed Mar 15, 2022
1 parent 461ac47 commit 3557346
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 39 deletions.
2 changes: 1 addition & 1 deletion cmd/rpcdaemon/commands/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type EthAPI interface {
GasPrice(_ context.Context) (*hexutil.Big, error)

// Sending related (see ./eth_call.go)
Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account) (hexutil.Bytes, error)
Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error)
EstimateGas(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error)
SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error)
SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error)
Expand Down
2 changes: 1 addition & 1 deletion cmd/rpcdaemon/commands/eth_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

// Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain.
func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account) (hexutil.Bytes, error) {
func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
Expand Down
6 changes: 6 additions & 0 deletions cmd/rpcdaemon/commands/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA
}
ibs := state.New(stateReader)

if config != nil && config.StateOverrides != nil {
if err := config.StateOverrides.Override(ibs); err != nil {
return err
}
}

var baseFee *uint256.Int
if header != nil && header.BaseFee != nil {
var overflow bool
Expand Down
14 changes: 9 additions & 5 deletions eth/tracers/api.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package tracers

import "github.com/ledgerwatch/erigon/core/vm"
import (
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/internal/ethapi"
)

// TraceConfig holds extra parameters to trace functions.
type TraceConfig struct {
*vm.LogConfig
Tracer *string
Timeout *string
Reexec *uint64
NoRefunds *bool // Turns off gas refunds when tracing
Tracer *string
Timeout *string
Reexec *uint64
NoRefunds *bool // Turns off gas refunds when tracing
StateOverrides *ethapi.StateOverrides
}
50 changes: 50 additions & 0 deletions internal/ethapi/state_overrides.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ethapi

import (
"fmt"
"math/big"

"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/core/state"
)

type StateOverrides map[common.Address]Account

func (overrides *StateOverrides) Override(state *state.IntraBlockState) error {

for addr, account := range *overrides {
// Override account nonce.
if account.Nonce != nil {
state.SetNonce(addr, uint64(*account.Nonce))
}
// Override account(contract) code.
if account.Code != nil {
state.SetCode(addr, *account.Code)
}
// Override account balance.
if account.Balance != nil {
balance, overflow := uint256.FromBig((*big.Int)(*account.Balance))
if overflow {
return fmt.Errorf("account.Balance higher than 2^256-1")
}
state.SetBalance(addr, balance)
}
if account.State != nil && account.StateDiff != nil {
return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
}
// Replace entire state if caller requires.
if account.State != nil {
state.SetStorage(addr, *account.State)
}
// Apply state diff into specified accounts.
if account.StateDiff != nil {
for key, value := range *account.StateDiff {
key := key
state.SetState(addr, &key, value)
}
}
}

return nil
}
36 changes: 4 additions & 32 deletions turbo/transactions/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func DoCall(
ctx context.Context,
args ethapi.CallArgs,
tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash,
block *types.Block, overrides *map[common.Address]ethapi.Account,
block *types.Block, overrides *ethapi.StateOverrides,
gasCap uint64,
chainConfig *params.ChainConfig,
filters *filters.Filters,
Expand All @@ -53,38 +53,10 @@ func DoCall(

// Override the fields of specified contracts before execution.
if overrides != nil {
for addr, account := range *overrides {
// Override account nonce.
if account.Nonce != nil {
state.SetNonce(addr, uint64(*account.Nonce))
}
// Override account(contract) code.
if account.Code != nil {
state.SetCode(addr, *account.Code)
}
// Override account balance.
if account.Balance != nil {
balance, overflow := uint256.FromBig((*big.Int)(*account.Balance))
if overflow {
return nil, fmt.Errorf("account.Balance higher than 2^256-1")
}
state.SetBalance(addr, balance)
}
if account.State != nil && account.StateDiff != nil {
return nil, fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex())
}
// Replace entire state if caller requires.
if account.State != nil {
state.SetStorage(addr, *account.State)
}
// Apply state diff into specified accounts.
if account.StateDiff != nil {
for key, value := range *account.StateDiff {
key := key
state.SetState(addr, &key, value)
}
}
if err := overrides.Override(state); err != nil {
return nil, err
}

}

// Setup context so it may be cancelled the call has completed
Expand Down

0 comments on commit 3557346

Please sign in to comment.