Skip to content

Commit fca9bac

Browse files
author
Darioush Jalali
authored
precompile accepter should take logIdx (#728)
* precompile accepter should take logIdx * minimize mock * copyright yr * add comments
1 parent 484ce17 commit fca9bac

File tree

3 files changed

+155
-13
lines changed

3 files changed

+155
-13
lines changed

plugin/evm/block.go

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/ava-labs/subnet-evm/core"
1616
"github.com/ava-labs/subnet-evm/core/rawdb"
1717
"github.com/ava-labs/subnet-evm/core/types"
18+
"github.com/ava-labs/subnet-evm/params"
1819
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
1920

2021
"github.com/ava-labs/avalanchego/ids"
@@ -64,8 +65,9 @@ func (b *Block) Accept(context.Context) error {
6465

6566
// Call Accept for relevant precompile logs. This should apply DB operations to the VM's versionDB
6667
// to be committed atomically with marking this block as accepted.
68+
rules := b.vm.chainConfig.AvalancheRules(b.ethBlock.Number(), b.ethBlock.Timestamp())
6769
sharedMemoryWriter := NewSharedMemoryWriter()
68-
if err := b.handlePrecompileAccept(sharedMemoryWriter); err != nil {
70+
if err := b.handlePrecompileAccept(&rules, sharedMemoryWriter); err != nil {
6971
return err
7072
}
7173
if err := vm.acceptedBlockDB.Put(lastAcceptedKey, b.id[:]); err != nil {
@@ -89,8 +91,7 @@ func (b *Block) Accept(context.Context) error {
8991
// contract.Accepter
9092
// This function assumes that the Accept function will ONLY operate on state maintained in the VM's versiondb.
9193
// This ensures that any DB operations are performed atomically with marking the block as accepted.
92-
func (b *Block) handlePrecompileAccept(sharedMemoryWriter *sharedMemoryWriter) error {
93-
rules := b.vm.chainConfig.AvalancheRules(b.ethBlock.Number(), b.ethBlock.Timestamp())
94+
func (b *Block) handlePrecompileAccept(rules *params.Rules, sharedMemoryWriter *sharedMemoryWriter) error {
9495
// Short circuit early if there are no precompile accepters to execute
9596
if len(rules.AccepterPrecompiles) == 0 {
9697
return nil
@@ -103,20 +104,18 @@ func (b *Block) handlePrecompileAccept(sharedMemoryWriter *sharedMemoryWriter) e
103104
if len(receipts) == 0 && b.ethBlock.ReceiptHash() != types.EmptyRootHash {
104105
return fmt.Errorf("failed to fetch receipts for accepted block with non-empty root hash (%s) (Block: %s, Height: %d)", b.ethBlock.ReceiptHash(), b.ethBlock.Hash(), b.ethBlock.NumberU64())
105106
}
106-
107-
for txIndex, receipt := range receipts {
108-
for _, log := range receipt.Logs {
107+
acceptCtx := &precompileconfig.AcceptContext{
108+
SnowCtx: b.vm.ctx,
109+
SharedMemory: sharedMemoryWriter,
110+
Warp: b.vm.warpBackend,
111+
}
112+
for _, receipt := range receipts {
113+
for logIdx, log := range receipt.Logs {
109114
accepter, ok := rules.AccepterPrecompiles[log.Address]
110115
if !ok {
111116
continue
112117
}
113-
114-
acceptCtx := &precompileconfig.AcceptContext{
115-
SnowCtx: b.vm.ctx,
116-
SharedMemory: sharedMemoryWriter,
117-
Warp: b.vm.warpBackend,
118-
}
119-
if err := accepter.Accept(acceptCtx, log.TxHash, txIndex, log.Topics, log.Data); err != nil {
118+
if err := accepter.Accept(acceptCtx, log.TxHash, logIdx, log.Topics, log.Data); err != nil {
120119
return err
121120
}
122121
}

plugin/evm/block_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// (c) 2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package evm
5+
6+
import (
7+
"math/big"
8+
"testing"
9+
10+
"github.com/ava-labs/avalanchego/database/memdb"
11+
"github.com/ava-labs/subnet-evm/core/rawdb"
12+
"github.com/ava-labs/subnet-evm/core/types"
13+
"github.com/ava-labs/subnet-evm/params"
14+
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
15+
"github.com/ava-labs/subnet-evm/trie"
16+
"github.com/ethereum/go-ethereum/common"
17+
"github.com/golang/mock/gomock"
18+
"github.com/stretchr/testify/require"
19+
)
20+
21+
func TestHandlePrecompileAccept(t *testing.T) {
22+
require := require.New(t)
23+
ctrl := gomock.NewController(t)
24+
defer ctrl.Finish()
25+
26+
db := memdb.New()
27+
vm := &VM{
28+
chaindb: Database{db},
29+
chainConfig: params.TestChainConfig,
30+
}
31+
32+
precompileAddr := common.Address{0x05}
33+
otherAddr := common.Address{0x06}
34+
35+
// Prepare a receipt with 3 logs, two of which are from the precompile
36+
receipt := &types.Receipt{
37+
Logs: []*types.Log{
38+
{
39+
Address: precompileAddr,
40+
Topics: []common.Hash{{0x01}, {0x02}, {0x03}},
41+
Data: []byte("log1"),
42+
},
43+
{
44+
Address: otherAddr,
45+
Topics: []common.Hash{{0x01}, {0x02}, {0x04}},
46+
Data: []byte("log2"),
47+
},
48+
{
49+
Address: precompileAddr,
50+
Topics: []common.Hash{{0x01}, {0x02}, {0x05}},
51+
Data: []byte("log3"),
52+
},
53+
},
54+
}
55+
ethBlock := types.NewBlock(
56+
&types.Header{Number: big.NewInt(1)},
57+
[]*types.Transaction{types.NewTx(&types.LegacyTx{})},
58+
nil,
59+
[]*types.Receipt{receipt},
60+
trie.NewStackTrie(nil),
61+
)
62+
// Write the block to the db
63+
rawdb.WriteBlock(db, ethBlock)
64+
rawdb.WriteReceipts(db, ethBlock.Hash(), ethBlock.NumberU64(), []*types.Receipt{receipt})
65+
66+
// Set up the mock with the expected calls to Accept
67+
txIndex := 0
68+
mockAccepter := precompileconfig.NewMockAccepter(ctrl)
69+
gomock.InOrder(
70+
mockAccepter.EXPECT().Accept(
71+
gomock.Not(gomock.Nil()), // acceptCtx
72+
ethBlock.Transactions()[txIndex].Hash(), // txHash
73+
0, // logIndex
74+
receipt.Logs[0].Topics, // topics
75+
receipt.Logs[0].Data, // logData
76+
),
77+
mockAccepter.EXPECT().Accept(
78+
gomock.Not(gomock.Nil()), // acceptCtx
79+
ethBlock.Transactions()[txIndex].Hash(), // txHash
80+
2, // logIndex
81+
receipt.Logs[2].Topics, // topics
82+
receipt.Logs[2].Data, // logData
83+
),
84+
)
85+
86+
// Call handlePrecompileAccept
87+
blk := vm.newBlock(ethBlock)
88+
rules := &params.Rules{
89+
AccepterPrecompiles: map[common.Address]precompileconfig.Accepter{
90+
precompileAddr: mockAccepter,
91+
},
92+
}
93+
require.NoError(blk.handlePrecompileAccept(rules, nil))
94+
}

precompile/precompileconfig/test_config.go

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)