good morning!!!!

Skip to content
Snippets Groups Projects
Unverified Commit a65f12b2 authored by Enrique Jose  Avila Asapche's avatar Enrique Jose Avila Asapche Committed by GitHub
Browse files

State override support (#3628)

* added stateOverride type

* solved import cycle

* refactoring

* imported wrong package

* fixed Call arguments

* typo

* override for traceCall
parent cb8aacae
No related branches found
No related tags found
No related merge requests found
...@@ -75,7 +75,7 @@ type EthAPI interface { ...@@ -75,7 +75,7 @@ type EthAPI interface {
GasPrice(_ context.Context) (*hexutil.Big, error) GasPrice(_ context.Context) (*hexutil.Big, error)
// Sending related (see ./eth_call.go) // 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) EstimateGas(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error)
SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error)
SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error)
......
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
) )
// Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain. // 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) tx, err := api.db.BeginRo(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -200,6 +200,12 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA ...@@ -200,6 +200,12 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA
} }
ibs := state.New(stateReader) ibs := state.New(stateReader)
if config != nil && config.StateOverrides != nil {
if err := config.StateOverrides.Override(ibs); err != nil {
return err
}
}
var baseFee *uint256.Int var baseFee *uint256.Int
if header != nil && header.BaseFee != nil { if header != nil && header.BaseFee != nil {
var overflow bool var overflow bool
......
package tracers 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. // TraceConfig holds extra parameters to trace functions.
type TraceConfig struct { type TraceConfig struct {
...@@ -9,4 +12,5 @@ type TraceConfig struct { ...@@ -9,4 +12,5 @@ type TraceConfig struct {
Timeout *string Timeout *string
Reexec *uint64 Reexec *uint64
NoRefunds *bool // Turns off gas refunds when tracing NoRefunds *bool // Turns off gas refunds when tracing
StateOverrides *ethapi.StateOverrides
} }
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
}
...@@ -29,7 +29,7 @@ func DoCall( ...@@ -29,7 +29,7 @@ func DoCall(
ctx context.Context, ctx context.Context,
args ethapi.CallArgs, args ethapi.CallArgs,
tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash,
block *types.Block, overrides *map[common.Address]ethapi.Account, block *types.Block, overrides *ethapi.StateOverrides,
gasCap uint64, gasCap uint64,
chainConfig *params.ChainConfig, chainConfig *params.ChainConfig,
filters *filters.Filters, filters *filters.Filters,
...@@ -53,38 +53,10 @@ func DoCall( ...@@ -53,38 +53,10 @@ func DoCall(
// Override the fields of specified contracts before execution. // Override the fields of specified contracts before execution.
if overrides != nil { if overrides != nil {
for addr, account := range *overrides { if err := overrides.Override(state); err != nil {
// Override account nonce. return nil, err
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)
}
}
} }
} }
// Setup context so it may be cancelled the call has completed // Setup context so it may be cancelled the call has completed
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment