check block nums are in order

This commit is contained in:
Sina Mahmoodi 2023-06-06 22:41:23 +02:00
parent 922f72c6de
commit 80bcb16e88
2 changed files with 46 additions and 23 deletions

View file

@ -919,7 +919,7 @@ func (diff *StateOverride) Apply(state *state.StateDB) error {
// BlockOverrides is a set of header fields to override. // BlockOverrides is a set of header fields to override.
type BlockOverrides struct { type BlockOverrides struct {
Number *hexutil.Big Number *hexutil.Big
Difficulty *hexutil.Big Difficulty *hexutil.Big // No-op if we're simulating post-merge calls.
Time *hexutil.Uint64 Time *hexutil.Uint64
GasLimit *hexutil.Uint64 GasLimit *hexutil.Uint64
Coinbase *common.Address Coinbase *common.Address
@ -1141,8 +1141,18 @@ func (s *BlockChainAPI) Multicall(ctx context.Context, blocks []CallBatch, block
// 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
globalGasCap = s.b.RPCGasCap() globalGasCap = s.b.RPCGasCap()
gp = new(core.GasPool).AddGas(globalGasCap) gp = new(core.GasPool).AddGas(globalGasCap)
prevNumber = header.Number.Uint64()
) )
for bi, block := range blocks { for bi, block := range blocks {
blockContext := core.NewEVMBlockContext(header, NewChainContext(ctx, s.b), nil)
if block.BlockOverrides != nil {
block.BlockOverrides.Apply(&blockContext)
}
// TODO: Consider hoisting this check up
if blockContext.BlockNumber.Uint64() < prevNumber {
return nil, fmt.Errorf("block numbers must be in order")
}
prevNumber = blockContext.BlockNumber.Uint64()
// State overrides are applied prior to execution of a block // State overrides are applied prior to execution of a block
if err := block.StateOverrides.Apply(state); err != nil { if err := block.StateOverrides.Apply(state); err != nil {
return nil, err return nil, err
@ -1151,10 +1161,6 @@ func (s *BlockChainAPI) Multicall(ctx context.Context, blocks []CallBatch, block
if block.ECRecoverOverride != nil { if block.ECRecoverOverride != nil {
state.SetCode(common.BytesToAddress([]byte{1}), *block.ECRecoverOverride) state.SetCode(common.BytesToAddress([]byte{1}), *block.ECRecoverOverride)
} }
blockContext := core.NewEVMBlockContext(header, NewChainContext(ctx, s.b), nil)
if block.BlockOverrides != nil {
block.BlockOverrides.Apply(&blockContext)
}
results[bi] = make([]callResult, len(block.Calls)) results[bi] = make([]callResult, len(block.Calls))
for i, call := range block.Calls { for i, call := range block.Calls {
// Hack to get logs from statedb which stores logs by txhash. // Hack to get logs from statedb which stores logs by txhash.

View file

@ -758,18 +758,6 @@ func TestMulticall(t *testing.T) {
0x60, 0x20, 0x60, 0x00, 0xf3, 0x60, 0x20, 0x60, 0x00, 0xf3,
}, },
}}, }},
}, {
// No block number override, should use latest
Calls: []TransactionArgs{
{
From: &accounts[0].addr,
Input: &hexutil.Bytes{
0x43, // NUMBER
0x60, 0x00, 0x52, // MSTORE offset 0
0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN
},
},
},
}}, }},
want: [][]res{{ want: [][]res{{
res{ res{
@ -781,13 +769,39 @@ func TestMulticall(t *testing.T) {
ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000c", ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000c",
GasUsed: "0xe891", GasUsed: "0xe891",
}, },
}, {
res{
ReturnValue: "0x000000000000000000000000000000000000000000000000000000000000000a",
GasUsed: "0xe891",
},
}}, }},
}, },
// Block numbers must be in order.
{
tag: latest,
blocks: []CallBatch{{
BlockOverrides: &BlockOverrides{
Number: (*hexutil.Big)(big.NewInt(12)),
},
Calls: []TransactionArgs{{
From: &accounts[1].addr,
Input: &hexutil.Bytes{
0x43, // NUMBER
0x60, 0x00, 0x52, // MSTORE offset 0
0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN
},
}},
}, {
BlockOverrides: &BlockOverrides{
Number: (*hexutil.Big)(big.NewInt(11)),
},
Calls: []TransactionArgs{{
From: &accounts[0].addr,
Input: &hexutil.Bytes{
0x43, // NUMBER
0x60, 0x00, 0x52, // MSTORE offset 0
0x60, 0x20, 0x60, 0x00, 0xf3, // RETURN
},
}},
}},
want: [][]res{},
expectErr: errors.New("block numbers must be in order"),
},
// Test on solidity storage example. Set value in one call, read in next. // Test on solidity storage example. Set value in one call, read in next.
{ {
tag: latest, tag: latest,
@ -915,7 +929,10 @@ func TestMulticall(t *testing.T) {
continue continue
} }
if !errors.Is(err, tc.expectErr) { if !errors.Is(err, tc.expectErr) {
t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err) // Second try
if !reflect.DeepEqual(err, tc.expectErr) {
t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
}
} }
continue continue
} }