finish renaming to simulate

This commit is contained in:
Sina Mahmoodi 2024-01-17 14:02:35 +03:30
parent df14718291
commit ae335662af
3 changed files with 73 additions and 71 deletions

View file

@ -1244,17 +1244,17 @@ func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrO
// //
// Note, this function doesn't make any changes in the state/blockchain and is // Note, this function doesn't make any changes in the state/blockchain and is
// useful to execute and retrieve values. // useful to execute and retrieve values.
func (s *BlockChainAPI) SimulateV1(ctx context.Context, opts mcOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]mcBlockResult, error) { func (s *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]simBlockResult, error) {
if len(opts.BlockStateCalls) == 0 { if len(opts.BlockStateCalls) == 0 {
return nil, &invalidParamsError{message: "empty input"} return nil, &invalidParamsError{message: "empty input"}
} else if len(opts.BlockStateCalls) > maxMulticallBlocks { } else if len(opts.BlockStateCalls) > maxSimulateBlocks {
return nil, &clientLimitExceededError{message: "too many blocks"} return nil, &clientLimitExceededError{message: "too many blocks"}
} }
if blockNrOrHash == nil { if blockNrOrHash == nil {
n := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) n := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
blockNrOrHash = &n blockNrOrHash = &n
} }
mc := &multicall{b: s.b, blockNrOrHash: *blockNrOrHash} mc := &simulator{b: s.b, blockNrOrHash: *blockNrOrHash}
return mc.execute(ctx, opts) return mc.execute(ctx, opts)
} }

View file

@ -1053,7 +1053,7 @@ func TestSimulateV1(t *testing.T) {
} }
var testSuite = []struct { var testSuite = []struct {
name string name string
blocks []mcBlock blocks []simBlock
tag rpc.BlockNumberOrHash tag rpc.BlockNumberOrHash
includeTransfers *bool includeTransfers *bool
validation *bool validation *bool
@ -1066,7 +1066,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "simple", name: "simple",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))}, randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(1000))},
}, },
@ -1108,7 +1108,7 @@ func TestSimulateV1(t *testing.T) {
// State build-up over blocks. // State build-up over blocks.
name: "simple-multi-block", name: "simple-multi-block",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))}, randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(2000))},
}, },
@ -1167,7 +1167,7 @@ func TestSimulateV1(t *testing.T) {
// insufficient funds // insufficient funds
name: "insufficient-funds", name: "insufficient-funds",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
Calls: []TransactionArgs{{ Calls: []TransactionArgs{{
From: &randomAccounts[0].addr, From: &randomAccounts[0].addr,
To: &randomAccounts[1].addr, To: &randomAccounts[1].addr,
@ -1180,7 +1180,7 @@ func TestSimulateV1(t *testing.T) {
// EVM error // EVM error
name: "evm-error", name: "evm-error",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[2].addr: OverrideAccount{Code: hex2Bytes("f3")}, randomAccounts[2].addr: OverrideAccount{Code: hex2Bytes("f3")},
}, },
@ -1206,7 +1206,7 @@ func TestSimulateV1(t *testing.T) {
// Block overrides should work, each call is simulated on a different block number // Block overrides should work, each call is simulated on a different block number
name: "block-overrides", name: "block-overrides",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
BlockOverrides: &BlockOverrides{ BlockOverrides: &BlockOverrides{
Number: (*hexutil.Big)(big.NewInt(11)), Number: (*hexutil.Big)(big.NewInt(11)),
FeeRecipient: &cac, FeeRecipient: &cac,
@ -1262,7 +1262,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "block-number-order", name: "block-number-order",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
BlockOverrides: &BlockOverrides{ BlockOverrides: &BlockOverrides{
Number: (*hexutil.Big)(big.NewInt(12)), Number: (*hexutil.Big)(big.NewInt(12)),
}, },
@ -1294,7 +1294,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "storage-contract", name: "storage-contract",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[2].addr: OverrideAccount{ randomAccounts[2].addr: OverrideAccount{
Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"), Code: hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220404e37f487a89a932dca5e77faaf6ca2de3b991f93d230604b1b8daaef64766264736f6c63430008070033"),
@ -1335,7 +1335,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "logs", name: "logs",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[2].addr: OverrideAccount{ randomAccounts[2].addr: OverrideAccount{
// Yul code: // Yul code:
@ -1376,7 +1376,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "ecrecover-override", name: "ecrecover-override",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[2].addr: OverrideAccount{ randomAccounts[2].addr: OverrideAccount{
// Yul code that returns ecrecover(0, 0, 0, 0). // Yul code that returns ecrecover(0, 0, 0, 0).
@ -1440,7 +1440,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "precompile-move", name: "precompile-move",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
sha256Address: OverrideAccount{ sha256Address: OverrideAccount{
// Yul code that returns the calldata. // Yul code that returns the calldata.
@ -1494,7 +1494,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "transfer-logs", name: "transfer-logs",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[0].addr: OverrideAccount{ randomAccounts[0].addr: OverrideAccount{
Balance: newRPCBalance(big.NewInt(100)), Balance: newRPCBalance(big.NewInt(100)),
@ -1556,7 +1556,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "selfdestruct", name: "selfdestruct",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
Calls: []TransactionArgs{{ Calls: []TransactionArgs{{
From: &accounts[0].addr, From: &accounts[0].addr,
To: &cac, To: &cac,
@ -1619,7 +1619,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "validation-checks", name: "validation-checks",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
Calls: []TransactionArgs{{ Calls: []TransactionArgs{{
From: &accounts[2].addr, From: &accounts[2].addr,
To: &cac, To: &cac,
@ -1634,7 +1634,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "clear-storage", name: "clear-storage",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
StateOverrides: &StateOverride{ StateOverrides: &StateOverride{
randomAccounts[2].addr: { randomAccounts[2].addr: {
Code: newBytes(genesis.Alloc[bab].Code), Code: newBytes(genesis.Alloc[bab].Code),
@ -1701,7 +1701,7 @@ func TestSimulateV1(t *testing.T) {
{ {
name: "blockhash-opcode", name: "blockhash-opcode",
tag: latest, tag: latest,
blocks: []mcBlock{{ blocks: []simBlock{{
BlockOverrides: &BlockOverrides{ BlockOverrides: &BlockOverrides{
Number: (*hexutil.Big)(big.NewInt(12)), Number: (*hexutil.Big)(big.NewInt(12)),
}, },
@ -1787,7 +1787,7 @@ func TestSimulateV1(t *testing.T) {
for _, tc := range testSuite { for _, tc := range testSuite {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
opts := mcOpts{BlockStateCalls: tc.blocks} opts := simOpts{BlockStateCalls: tc.blocks}
if tc.includeTransfers != nil && *tc.includeTransfers { if tc.includeTransfers != nil && *tc.includeTransfers {
opts.TraceTransfers = true opts.TraceTransfers = true
} }

View file

@ -39,19 +39,19 @@ import (
) )
const ( const (
// maxMulticallBlocks is the maximum number of blocks that can be simulated // maxSimulateBlocks is the maximum number of blocks that can be simulated
// in a single request. // in a single request.
maxMulticallBlocks = 256 maxSimulateBlocks = 256
) )
// mcBlock is a batch of calls to be simulated sequentially. // simBlock is a batch of calls to be simulated sequentially.
type mcBlock struct { type simBlock struct {
BlockOverrides *BlockOverrides BlockOverrides *BlockOverrides
StateOverrides *StateOverride StateOverrides *StateOverride
Calls []TransactionArgs Calls []TransactionArgs
} }
type mcBlockResult struct { type simBlockResult struct {
Number hexutil.Uint64 `json:"number"` Number hexutil.Uint64 `json:"number"`
Hash common.Hash `json:"hash"` Hash common.Hash `json:"hash"`
Time hexutil.Uint64 `json:"timestamp"` Time hexutil.Uint64 `json:"timestamp"`
@ -60,11 +60,11 @@ type mcBlockResult struct {
FeeRecipient common.Address `json:"feeRecipient"` FeeRecipient common.Address `json:"feeRecipient"`
BaseFee *hexutil.Big `json:"baseFeePerGas"` BaseFee *hexutil.Big `json:"baseFeePerGas"`
PrevRandao common.Hash `json:"prevRandao"` PrevRandao common.Hash `json:"prevRandao"`
Calls []mcCallResult `json:"calls"` Calls []simCallResult `json:"calls"`
} }
func mcBlockResultFromHeader(header *types.Header, callResults []mcCallResult) mcBlockResult { func mcBlockResultFromHeader(header *types.Header, callResults []simCallResult) simBlockResult {
return mcBlockResult{ return simBlockResult{
Number: hexutil.Uint64(header.Number.Uint64()), Number: hexutil.Uint64(header.Number.Uint64()),
Hash: header.Hash(), Hash: header.Hash(),
Time: hexutil.Uint64(header.Time), Time: hexutil.Uint64(header.Time),
@ -77,7 +77,7 @@ func mcBlockResultFromHeader(header *types.Header, callResults []mcCallResult) m
} }
} }
type mcCallResult struct { type simCallResult struct {
ReturnValue hexutil.Bytes `json:"returnData"` ReturnValue hexutil.Bytes `json:"returnData"`
Logs []*types.Log `json:"logs"` Logs []*types.Log `json:"logs"`
GasUsed hexutil.Uint64 `json:"gasUsed"` GasUsed hexutil.Uint64 `json:"gasUsed"`
@ -85,8 +85,8 @@ type mcCallResult struct {
Error *callError `json:"error,omitempty"` Error *callError `json:"error,omitempty"`
} }
func (r *mcCallResult) MarshalJSON() ([]byte, error) { func (r *simCallResult) MarshalJSON() ([]byte, error) {
type callResultAlias mcCallResult type callResultAlias simCallResult
// Marshal logs to be an empty array instead of nil when empty // Marshal logs to be an empty array instead of nil when empty
if r.Logs == nil { if r.Logs == nil {
r.Logs = []*types.Log{} r.Logs = []*types.Log{}
@ -94,20 +94,20 @@ func (r *mcCallResult) MarshalJSON() ([]byte, error) {
return json.Marshal((*callResultAlias)(r)) return json.Marshal((*callResultAlias)(r))
} }
type mcOpts struct { type simOpts struct {
BlockStateCalls []mcBlock BlockStateCalls []simBlock
TraceTransfers bool TraceTransfers bool
Validation bool Validation bool
} }
type multicall struct { type simulator struct {
blockNrOrHash rpc.BlockNumberOrHash blockNrOrHash rpc.BlockNumberOrHash
b Backend b Backend
hashes []common.Hash hashes []common.Hash
} }
func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult, error) { func (sim *simulator) execute(ctx context.Context, opts simOpts) ([]simBlockResult, error) {
state, base, err := mc.b.StateAndHeaderByNumberOrHash(ctx, mc.blockNrOrHash) state, base, err := sim.b.StateAndHeaderByNumberOrHash(ctx, sim.blockNrOrHash)
if state == nil || err != nil { if state == nil || err != nil {
return nil, err return nil, err
} }
@ -115,7 +115,7 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
// or, in case of unmetered gas, setup a context with a timeout. // or, in case of unmetered gas, setup a context with a timeout.
var ( var (
cancel context.CancelFunc cancel context.CancelFunc
timeout = mc.b.RPCEVMTimeout() timeout = sim.b.RPCEVMTimeout()
blocks = opts.BlockStateCalls blocks = opts.BlockStateCalls
) )
if timeout > 0 { if timeout > 0 {
@ -126,28 +126,28 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
// Make sure the context is cancelled when the call has completed // Make sure the context is cancelled when the call has completed
// this makes sure resources are cleaned up. // this makes sure resources are cleaned up.
defer cancel() defer cancel()
headers, err := makeHeaders(mc.b.ChainConfig(), blocks, base) headers, err := makeHeaders(sim.b.ChainConfig(), blocks, base)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var ( var (
results = make([]mcBlockResult, len(blocks)) results = make([]simBlockResult, len(blocks))
// Each tx and all the series of txes shouldn't consume more gas than cap // Each tx and all the series of txes shouldn't consume more gas than cap
gp = new(core.GasPool).AddGas(mc.b.RPCGasCap()) gp = new(core.GasPool).AddGas(sim.b.RPCGasCap())
precompiles = mc.activePrecompiles(ctx, base) precompiles = sim.activePrecompiles(ctx, base)
numHashes = headers[len(headers)-1].Number.Uint64() - base.Number.Uint64() + 256 numHashes = headers[len(headers)-1].Number.Uint64() - base.Number.Uint64() + 256
) )
// Cache for the block hashes. // Cache for the block hashes.
mc.hashes = make([]common.Hash, numHashes) sim.hashes = make([]common.Hash, numHashes)
for bi, block := range blocks { for bi, block := range blocks {
header := headers[bi] header := headers[bi]
blockContext := core.NewEVMBlockContext(header, NewChainContext(ctx, mc.b), nil) blockContext := core.NewEVMBlockContext(header, NewChainContext(ctx, sim.b), nil)
if block.BlockOverrides != nil && block.BlockOverrides.BlobGasPrice != nil { if block.BlockOverrides != nil && block.BlockOverrides.BlobGasPrice != nil {
blockContext.BlobBaseFee = block.BlockOverrides.BlobGasPrice.ToInt() blockContext.BlobBaseFee = block.BlockOverrides.BlobGasPrice.ToInt()
} }
// Respond to BLOCKHASH requests. // Respond to BLOCKHASH requests.
blockContext.GetHash = func(n uint64) common.Hash { blockContext.GetHash = func(n uint64) common.Hash {
h, err := mc.getBlockHash(ctx, n, base, headers) h, err := sim.getBlockHash(ctx, n, base, headers)
if err != nil { if err != nil {
log.Warn(err.Error()) log.Warn(err.Error())
return common.Hash{} return common.Hash{}
@ -161,10 +161,10 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
var ( var (
gasUsed uint64 gasUsed uint64
txes = make([]*types.Transaction, len(block.Calls)) txes = make([]*types.Transaction, len(block.Calls))
callResults = make([]mcCallResult, len(block.Calls)) callResults = make([]simCallResult, len(block.Calls))
receipts = make([]*types.Receipt, len(block.Calls)) receipts = make([]*types.Receipt, len(block.Calls))
tracer = newTracer(opts.TraceTransfers, blockContext.BlockNumber.Uint64(), common.Hash{}, common.Hash{}, 0) tracer = newTracer(opts.TraceTransfers, blockContext.BlockNumber.Uint64(), common.Hash{}, common.Hash{}, 0)
config = mc.b.ChainConfig() config = sim.b.ChainConfig()
vmConfig = &vm.Config{ vmConfig = &vm.Config{
NoBaseFee: true, NoBaseFee: true,
// Block hash will be repaired after execution. // Block hash will be repaired after execution.
@ -172,13 +172,15 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
} }
evm = vm.NewEVM(blockContext, vm.TxContext{GasPrice: new(big.Int)}, state, config, *vmConfig) evm = vm.NewEVM(blockContext, vm.TxContext{GasPrice: new(big.Int)}, state, config, *vmConfig)
) )
// It is possible to override precompiles with EVM bytecode, or
// move them to another address.
if precompiles != nil { if precompiles != nil {
evm.SetPrecompiles(precompiles) evm.SetPrecompiles(precompiles)
} }
for i, call := range block.Calls { for i, call := range block.Calls {
// TODO: Pre-estimate nonce and gas // TODO: Pre-estimate nonce and gas
// TODO: Move gas fees sanitizing to beginning of func // TODO: Move gas fees sanitizing to beginning of func
if err := mc.sanitizeCall(&call, state, &gasUsed, blockContext); err != nil { if err := sim.sanitizeCall(&call, state, &gasUsed, blockContext); err != nil {
return nil, err return nil, err
} }
tx := call.ToTransaction() tx := call.ToTransaction()
@ -210,7 +212,7 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
result.Err = newRevertError(result.Revert()) result.Err = newRevertError(result.Revert())
} }
logs := tracer.Logs() logs := tracer.Logs()
callRes := mcCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas)} callRes := simCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas)}
if result.Failed() { if result.Failed() {
callRes.Status = hexutil.Uint64(types.ReceiptStatusFailed) callRes.Status = hexutil.Uint64(types.ReceiptStatusFailed)
if errors.Is(result.Err, vm.ErrExecutionReverted) { if errors.Is(result.Err, vm.ErrExecutionReverted) {
@ -227,7 +229,7 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
parentHash common.Hash parentHash common.Hash
err error err error
) )
parentHash, err = mc.getBlockHash(ctx, header.Number.Uint64()-1, base, headers) parentHash, err = sim.getBlockHash(ctx, header.Number.Uint64()-1, base, headers)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -242,7 +244,7 @@ func (mc *multicall) execute(ctx context.Context, opts mcOpts) ([]mcBlockResult,
return results, nil return results, nil
} }
func (mc *multicall) sanitizeCall(call *TransactionArgs, state *state.StateDB, gasUsed *uint64, blockContext vm.BlockContext) error { func (sim *simulator) sanitizeCall(call *TransactionArgs, state *state.StateDB, gasUsed *uint64, blockContext vm.BlockContext) error {
if call.Nonce == nil { if call.Nonce == nil {
nonce := state.GetNonce(call.from()) nonce := state.GetNonce(call.from())
call.Nonce = (*hexutil.Uint64)(&nonce) call.Nonce = (*hexutil.Uint64)(&nonce)
@ -260,7 +262,7 @@ func (mc *multicall) sanitizeCall(call *TransactionArgs, state *state.StateDB, g
call.Gas = (*hexutil.Uint64)(&remaining) call.Gas = (*hexutil.Uint64)(&remaining)
} }
// TODO: check chainID and against current header for london fees // TODO: check chainID and against current header for london fees
if err := call.validateAll(mc.b); err != nil { if err := call.validateAll(sim.b); err != nil {
return err return err
} }
if call.GasPrice == nil && call.MaxFeePerGas == nil && call.MaxPriorityFeePerGas == nil { if call.GasPrice == nil && call.MaxFeePerGas == nil && call.MaxPriorityFeePerGas == nil {
@ -274,7 +276,7 @@ func (mc *multicall) sanitizeCall(call *TransactionArgs, state *state.StateDB, g
// part of the canonical chain, a simulated block or a phantom block. // part of the canonical chain, a simulated block or a phantom block.
// Note getBlockHash assumes `n` is smaller than the last already simulated block // Note getBlockHash assumes `n` is smaller than the last already simulated block
// and smaller than the last block to be simulated. // and smaller than the last block to be simulated.
func (mc *multicall) getBlockHash(ctx context.Context, n uint64, base *types.Header, headers []*types.Header) (common.Hash, error) { func (sim *simulator) getBlockHash(ctx context.Context, n uint64, base *types.Header, headers []*types.Header) (common.Hash, error) {
// getIndex returns the index of the hash in the hashes cache. // getIndex returns the index of the hash in the hashes cache.
// The cache potentially includes 255 blocks prior to the base. // The cache potentially includes 255 blocks prior to the base.
getIndex := func(n uint64) int { getIndex := func(n uint64) int {
@ -282,24 +284,24 @@ func (mc *multicall) getBlockHash(ctx context.Context, n uint64, base *types.Hea
return int(n - first) return int(n - first)
} }
index := getIndex(n) index := getIndex(n)
if h := mc.hashes[index]; h != (common.Hash{}) { if h := sim.hashes[index]; h != (common.Hash{}) {
return h, nil return h, nil
} }
h, err := mc.computeBlockHash(ctx, n, base, headers) h, err := sim.computeBlockHash(ctx, n, base, headers)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
if h != (common.Hash{}) { if h != (common.Hash{}) {
mc.hashes[index] = h sim.hashes[index] = h
} }
return h, nil return h, nil
} }
func (mc *multicall) computeBlockHash(ctx context.Context, n uint64, base *types.Header, headers []*types.Header) (common.Hash, error) { func (sim *simulator) computeBlockHash(ctx context.Context, n uint64, base *types.Header, headers []*types.Header) (common.Hash, error) {
if n == base.Number.Uint64() { if n == base.Number.Uint64() {
return base.Hash(), nil return base.Hash(), nil
} else if n < base.Number.Uint64() { } else if n < base.Number.Uint64() {
h, err := mc.b.HeaderByNumber(ctx, rpc.BlockNumber(n)) h, err := sim.b.HeaderByNumber(ctx, rpc.BlockNumber(n))
if err != nil { if err != nil {
return common.Hash{}, fmt.Errorf("failed to load block hash for number %d. Err: %v\n", n, err) return common.Hash{}, fmt.Errorf("failed to load block hash for number %d. Err: %v\n", n, err)
} }
@ -315,7 +317,7 @@ func (mc *multicall) computeBlockHash(ctx context.Context, n uint64, base *types
return hash, nil return hash, nil
} else if tmp.Number.Uint64() > n { } else if tmp.Number.Uint64() > n {
// Phantom block. // Phantom block.
lastNonPhantomHash, err := mc.getBlockHash(ctx, h.Number.Uint64(), base, headers) lastNonPhantomHash, err := sim.getBlockHash(ctx, h.Number.Uint64(), base, headers)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -331,10 +333,10 @@ func (mc *multicall) computeBlockHash(ctx context.Context, n uint64, base *types
return common.Hash{}, errors.New("requested block is in future") return common.Hash{}, errors.New("requested block is in future")
} }
func (mc *multicall) activePrecompiles(ctx context.Context, base *types.Header) vm.PrecompiledContracts { func (sim *simulator) activePrecompiles(ctx context.Context, base *types.Header) vm.PrecompiledContracts {
var ( var (
blockContext = core.NewEVMBlockContext(base, NewChainContext(ctx, mc.b), nil) blockContext = core.NewEVMBlockContext(base, NewChainContext(ctx, sim.b), nil)
rules = mc.b.ChainConfig().Rules(blockContext.BlockNumber, blockContext.Random != nil, blockContext.Time) rules = sim.b.ChainConfig().Rules(blockContext.BlockNumber, blockContext.Random != nil, blockContext.Time)
) )
return vm.ActivePrecompiledContracts(rules).Copy() return vm.ActivePrecompiledContracts(rules).Copy()
} }
@ -342,7 +344,7 @@ func (mc *multicall) activePrecompiles(ctx context.Context, base *types.Header)
// repairLogs updates the block hash in the logs present in a multicall // repairLogs updates the block hash in the logs present in a multicall
// result object. This is needed as during execution when logs are collected // result object. This is needed as during execution when logs are collected
// the block hash is not known. // the block hash is not known.
func repairLogs(results []mcBlockResult, blockHash common.Hash) { func repairLogs(results []simBlockResult, blockHash common.Hash) {
for i := range results { for i := range results {
for j := range results[i].Calls { for j := range results[i].Calls {
for k := range results[i].Calls[j].Logs { for k := range results[i].Calls[j].Logs {
@ -352,7 +354,7 @@ func repairLogs(results []mcBlockResult, blockHash common.Hash) {
} }
} }
func makeHeaders(config *params.ChainConfig, blocks []mcBlock, base *types.Header) ([]*types.Header, error) { func makeHeaders(config *params.ChainConfig, blocks []simBlock, base *types.Header) ([]*types.Header, error) {
res := make([]*types.Header, len(blocks)) res := make([]*types.Header, len(blocks))
var ( var (
prevNumber = base.Number.Uint64() prevNumber = base.Number.Uint64()