Skip to content

Commit 53f6df3

Browse files
committed
feat: Handler.BeforeBlock()
1 parent e26b024 commit 53f6df3

File tree

2 files changed

+53
-27
lines changed

2 files changed

+53
-27
lines changed

libevm/precompiles/parallel/parallel.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
// Scenario (2) allows precompile access to be determined through inspection of
4343
// the [types.Transaction] alone, without the need for execution.
4444
type Handler[Result any] interface {
45+
BeforeBlock(*types.Header)
4546
Gas(*types.Transaction) (gas uint64, process bool)
4647
Process(index int, tx *types.Transaction) Result
4748
}
@@ -109,6 +110,7 @@ func (p *Processor[R]) Close() {
109110
// It MUST be paired with a call to [Processor.FinishBlock], without overlap of
110111
// blocks.
111112
func (p *Processor[R]) StartBlock(b *types.Block, rules params.Rules) error {
113+
p.handler.BeforeBlock(types.CopyHeader(b.Header()))
112114
txs := b.Transactions()
113115
jobs := make([]*job, 0, len(txs))
114116

@@ -202,14 +204,7 @@ func (p *Processor[R]) shouldProcess(tx *types.Transaction, rules params.Rules)
202204
}
203205
}()
204206

205-
spent, err := core.IntrinsicGas(
206-
tx.Data(),
207-
tx.AccessList(),
208-
tx.To() == nil,
209-
rules.IsHomestead,
210-
rules.IsIstanbul, // EIP-2028
211-
rules.IsShanghai, // EIP-3860
212-
)
207+
spent, err := txIntrinsicGas(tx, &rules)
213208
if err != nil {
214209
return false, fmt.Errorf("calculating intrinsic gas of %v: %v", tx.Hash(), err)
215210
}
@@ -220,6 +215,22 @@ func (p *Processor[R]) shouldProcess(tx *types.Transaction, rules params.Rules)
220215
return left >= cost, nil
221216
}
222217

218+
func txIntrinsicGas(tx *types.Transaction, rules *params.Rules) (uint64, error) {
219+
return intrinsicGas(tx.Data(), tx.AccessList(), tx.To(), rules)
220+
}
221+
222+
func intrinsicGas(data []byte, access types.AccessList, txTo *common.Address, rules *params.Rules) (uint64, error) {
223+
create := txTo == nil
224+
return core.IntrinsicGas(
225+
data,
226+
access,
227+
create,
228+
rules.IsHomestead,
229+
rules.IsIstanbul, // EIP-2028
230+
rules.IsShanghai, // EIP-3860
231+
)
232+
}
233+
223234
// ErrTxUnknown is returned by [Processor.PreprocessingGasCharge] if it is
224235
// called with a transaction hash that wasn't in the last block passed to
225236
// [Processor.StartBlock].

libevm/precompiles/parallel/parallel_test.go

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package parallel
1818

1919
import (
20-
"crypto/sha256"
20+
"bytes"
2121
"encoding/binary"
2222
"math"
23+
"math/big"
2324
"math/rand/v2"
25+
"slices"
2426
"testing"
2527

2628
"github.com/google/go-cmp/cmp"
@@ -46,25 +48,36 @@ func TestMain(m *testing.M) {
4648
goleak.VerifyTestMain(m, goleak.IgnoreCurrent())
4749
}
4850

49-
type shaHandler struct {
50-
addr common.Address
51-
gas uint64
51+
type reverser struct {
52+
extra []byte
53+
addr common.Address
54+
gas uint64
5255
}
5356

54-
func (h *shaHandler) Gas(tx *types.Transaction) (uint64, bool) {
55-
if to := tx.To(); to == nil || *to != h.addr {
57+
func (r *reverser) BeforeBlock(h *types.Header) {
58+
r.extra = h.Extra
59+
}
60+
61+
func (r *reverser) Gas(tx *types.Transaction) (uint64, bool) {
62+
if to := tx.To(); to == nil || *to != r.addr {
5663
return 0, false
5764
}
58-
return h.gas, true
65+
return r.gas, true
66+
}
67+
68+
func reverserOutput(data, extra []byte) []byte {
69+
out := append(data, extra...)
70+
slices.Reverse(out)
71+
return out
5972
}
6073

61-
func (*shaHandler) Process(i int, tx *types.Transaction) [sha256.Size]byte {
62-
return sha256.Sum256(tx.Data())
74+
func (r *reverser) Process(i int, tx *types.Transaction) []byte {
75+
return reverserOutput(tx.Data(), r.extra)
6376
}
6477

6578
func TestProcessor(t *testing.T) {
66-
handler := &shaHandler{
67-
addr: common.Address{'s', 'h', 'a', 2, 5, 6},
79+
handler := &reverser{
80+
addr: common.Address{'r', 'e', 'v', 'e', 'r', 's', 'e'},
6881
gas: 1e6,
6982
}
7083
p := New(handler, 8)
@@ -141,7 +154,7 @@ func TestProcessor(t *testing.T) {
141154
}
142155

143156
data := binary.BigEndian.AppendUint64(nil, uint64(i))
144-
gas, err := core.IntrinsicGas(data, nil, false, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai)
157+
gas, err := intrinsicGas(data, types.AccessList{}, &handler.addr, &rules)
145158
require.NoError(t, err, "core.IntrinsicGas(%#x, nil, false, true, true, true)", data)
146159

147160
txs[i] = types.NewTx(&types.LegacyTx{
@@ -151,20 +164,21 @@ func TestProcessor(t *testing.T) {
151164
})
152165
}
153166

154-
block := types.NewBlock(&types.Header{}, txs, nil, nil, trie.NewStackTrie(nil))
167+
extra := []byte("extra")
168+
block := types.NewBlock(&types.Header{Extra: extra}, txs, nil, nil, trie.NewStackTrie(nil))
155169
require.NoError(t, p.StartBlock(block, rules), "StartBlock()")
156170
defer p.FinishBlock(block)
157171

158172
for i, tx := range txs {
159173
wantOK := wantProcessed[i]
160174

161-
var want [sha256.Size]byte
175+
var want []byte
162176
if wantOK {
163-
want = handler.Process(i, tx)
177+
want = reverserOutput(tx.Data(), extra)
164178
}
165179

166180
got, gotOK := p.Result(i)
167-
if got != want || gotOK != wantOK {
181+
if !bytes.Equal(got, want) || gotOK != wantOK {
168182
t.Errorf("Result(%d) got (%#x, %t); want (%#x, %t)", i, got, gotOK, want, wantOK)
169183
}
170184
}
@@ -193,8 +207,8 @@ type vmHooks struct {
193207

194208
func TestIntegration(t *testing.T) {
195209
const handlerGas = 500
196-
handler := &shaHandler{
197-
addr: common.Address{'s', 'h', 'a', 2, 5, 6},
210+
handler := &reverser{
211+
addr: common.Address{'r', 'e', 'v', 'e', 'r', 's', 'e'},
198212
gas: handlerGas,
199213
}
200214
sut := New(handler, 8)
@@ -254,7 +268,8 @@ func TestIntegration(t *testing.T) {
254268

255269
// Having all arguments `false` is equivalent to what
256270
// [core.ApplyTransaction] will do.
257-
gas, err := core.IntrinsicGas(data, types.AccessList{}, false, false, false, false)
271+
rules := evm.ChainConfig().Rules(big.NewInt(0), false, 0)
272+
gas, err := intrinsicGas(data, types.AccessList{}, &addr, &rules)
258273
require.NoError(t, err, "core.IntrinsicGas(%#x, nil, false, false, false, false)", data)
259274
if addr == handler.addr {
260275
gas += handlerGas

0 commit comments

Comments
 (0)