Skip to content

Commit 1daec97

Browse files
committed
partial cherry-pick: Coreth/Implement ACP-176 (#815) (b1e098cd)
1 parent d0bb7c6 commit 1daec97

File tree

9 files changed

+245
-56
lines changed

9 files changed

+245
-56
lines changed

consensus/dummy/consensus.go

+17-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package dummy
55

66
import (
7-
"bytes"
87
"errors"
98
"fmt"
109
"math/big"
@@ -46,6 +45,16 @@ type (
4645
}
4746
)
4847

48+
func NewDummyEngine(
49+
mode Mode,
50+
clock *mockable.Clock,
51+
) *DummyEngine {
52+
return &DummyEngine{
53+
clock: clock,
54+
consensusMode: mode,
55+
}
56+
}
57+
4958
func NewETHFaker() *DummyEngine {
5059
return &DummyEngine{
5160
clock: &mockable.Clock{},
@@ -116,7 +125,7 @@ func (eng *DummyEngine) verifyCoinbase(config *params.ChainConfig, header *types
116125
return nil
117126
}
118127

119-
func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header, chain consensus.ChainHeaderReader) error {
128+
func verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header, chain consensus.ChainHeaderReader) error {
120129
// We verify the current block by checking the parent fee config
121130
// this is because the current block cannot set the fee config for itself
122131
// Fee config might depend on the state when precompile is activated
@@ -126,20 +135,14 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header
126135
if err != nil {
127136
return err
128137
}
129-
// Verify that the gasUsed is <= gasLimit
130-
if header.GasUsed > header.GasLimit {
131-
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
138+
if err := customheader.VerifyGasUsed(config, feeConfig, parent, header); err != nil {
139+
return err
132140
}
133141
if err := customheader.VerifyGasLimit(config, feeConfig, parent, header); err != nil {
134142
return err
135143
}
136-
// Verify header.Extra matches the expected value.
137-
expectedExtraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time)
138-
if err != nil {
139-
return fmt.Errorf("failed to calculate extra prefix: %w", err)
140-
}
141-
if !bytes.HasPrefix(header.Extra, expectedExtraPrefix) {
142-
return fmt.Errorf("expected header.Extra to have prefix: %x, found %x", expectedExtraPrefix, header.Extra)
144+
if err := customheader.VerifyExtraPrefix(config, parent, header); err != nil {
145+
return err
143146
}
144147

145148
// Verify header.BaseFee matches the expected value.
@@ -185,7 +188,7 @@ func (eng *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header *
185188
}
186189

187190
// Ensure gas-related header fields are correct
188-
if err := eng.verifyHeaderGasFields(config, header, parent, chain); err != nil {
191+
if err := verifyHeaderGasFields(config, header, parent, chain); err != nil {
189192
return err
190193
}
191194
// Ensure that coinbase is valid
@@ -395,7 +398,7 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h
395398
}
396399

397400
// finalize the header.Extra
398-
extraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time)
401+
extraPrefix, err := customheader.ExtraPrefix(config, parent, header)
399402
if err != nil {
400403
return nil, fmt.Errorf("failed to calculate new header.Extra: %w", err)
401404
}

core/chain_makers.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,10 @@ func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.S
378378
if err != nil {
379379
panic(err)
380380
}
381-
gasLimit := header.GasLimit(cm.config, feeConfig, parent.Header(), time)
381+
gasLimit, err := header.GasLimit(cm.config, feeConfig, parent.Header(), time)
382+
if err != nil {
383+
panic(err)
384+
}
382385
baseFee, err := header.BaseFee(cm.config, feeConfig, parent.Header(), time)
383386
if err != nil {
384387
panic(err)

core/state_processor_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
437437
if err != nil {
438438
panic(err)
439439
}
440+
gasLimit, _ := customheader.GasLimit(config, feeConfig, parent.Header(), time)
440441
baseFee, _ := customheader.BaseFee(config, feeConfig, parent.Header(), time)
441442
header := &types.Header{
442443
ParentHash: parent.Hash(),
@@ -447,7 +448,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
447448
Difficulty: parent.Difficulty(),
448449
UncleHash: parent.UncleHash(),
449450
}),
450-
GasLimit: parent.GasLimit(),
451+
GasLimit: gasLimit,
451452
Number: new(big.Int).Add(parent.Number(), common.Big1),
452453
Time: time,
453454
UncleHash: types.EmptyUncleHash,
@@ -473,7 +474,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
473474
cumulativeGas += tx.Gas()
474475
nBlobs += len(tx.BlobHashes())
475476
}
476-
header.Extra, _ = customheader.ExtraPrefix(config, parent.Header(), time)
477+
header.Extra, _ = customheader.ExtraPrefix(config, parent.Header(), header)
477478
header.Root = common.BytesToHash(hasher.Sum(nil))
478479
if config.IsCancun(header.Number, header.Time) {
479480
var pExcess, pUsed = uint64(0), uint64(0)

eth/gasprice/gasprice_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func newTestBackendFakerEngine(t *testing.T, config *params.ChainConfig, numBloc
109109
engine := dummy.NewETHFaker()
110110

111111
// Generate testing blocks
112-
_, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, 0, genBlocks)
112+
_, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, config.FeeConfig.TargetBlockRate-1, genBlocks)
113113
if err != nil {
114114
t.Fatal(err)
115115
}
@@ -136,7 +136,7 @@ func newTestBackend(t *testing.T, config *params.ChainConfig, numBlocks int, gen
136136
engine := dummy.NewFaker()
137137

138138
// Generate testing blocks
139-
_, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, 1, genBlocks)
139+
_, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, config.FeeConfig.TargetBlockRate-1, genBlocks)
140140
if err != nil {
141141
t.Fatal(err)
142142
}
@@ -257,7 +257,7 @@ func TestSuggestTipCapNetworkUpgrades(t *testing.T) {
257257
}
258258
}
259259

260-
func TestSuggestTipCap(t *testing.T) {
260+
func TestSuggestTipCapSimple(t *testing.T) {
261261
applyGasPriceTest(t, suggestTipCapTest{
262262
chainConfig: params.TestChainConfig,
263263
numBlocks: 3,

miner/worker.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838

3939
"github.com/ava-labs/avalanchego/utils/timer/mockable"
4040
"github.com/ava-labs/avalanchego/utils/units"
41+
"github.com/ava-labs/subnet-evm/commontype"
4142
"github.com/ava-labs/subnet-evm/consensus"
4243
"github.com/ava-labs/subnet-evm/consensus/misc/eip4844"
4344
"github.com/ava-labs/subnet-evm/core"
@@ -46,7 +47,7 @@ import (
4647
"github.com/ava-labs/subnet-evm/core/types"
4748
"github.com/ava-labs/subnet-evm/core/vm"
4849
"github.com/ava-labs/subnet-evm/params"
49-
"github.com/ava-labs/subnet-evm/plugin/evm/header"
50+
customheader "github.com/ava-labs/subnet-evm/plugin/evm/header"
5051
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
5152
"github.com/ava-labs/subnet-evm/predicate"
5253
"github.com/ethereum/go-ethereum/common"
@@ -150,8 +151,11 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte
150151
if err != nil {
151152
return nil, err
152153
}
153-
gasLimit := header.GasLimit(w.chainConfig, feeConfig, parent, timestamp)
154-
baseFee, err := header.BaseFee(w.chainConfig, feeConfig, parent, timestamp)
154+
gasLimit, err := customheader.GasLimit(w.chainConfig, feeConfig, parent, timestamp)
155+
if err != nil {
156+
return nil, fmt.Errorf("calculating new gas limit: %w", err)
157+
}
158+
baseFee, err := customheader.BaseFee(w.chainConfig, feeConfig, parent, timestamp)
155159
if err != nil {
156160
return nil, fmt.Errorf("failed to calculate new base fee: %w", err)
157161
}
@@ -200,7 +204,7 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte
200204
return nil, fmt.Errorf("failed to prepare header for mining: %w", err)
201205
}
202206

203-
env, err := w.createCurrentEnvironment(predicateContext, parent, header, tstart)
207+
env, err := w.createCurrentEnvironment(predicateContext, parent, header, feeConfig, tstart)
204208
if err != nil {
205209
return nil, fmt.Errorf("failed to create new current environment: %w", err)
206210
}
@@ -269,11 +273,15 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte
269273
return w.commit(env)
270274
}
271275

272-
func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.PredicateContext, parent *types.Header, header *types.Header, tstart time.Time) (*environment, error) {
276+
func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.PredicateContext, parent *types.Header, header *types.Header, feeConfig commontype.FeeConfig, tstart time.Time) (*environment, error) {
273277
currentState, err := w.chain.StateAt(parent.Root)
274278
if err != nil {
275279
return nil, err
276280
}
281+
capacity, err := customheader.GasCapacity(w.chainConfig, feeConfig, parent, header.Time)
282+
if err != nil {
283+
return nil, fmt.Errorf("calculating gas capacity: %w", err)
284+
}
277285
numPrefetchers := w.chain.CacheConfig().TriePrefetcherParallelism
278286
currentState.StartPrefetcher("miner", state.WithConcurrentWorkers(numPrefetchers))
279287
return &environment{
@@ -282,7 +290,7 @@ func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.Pre
282290
parent: parent,
283291
header: header,
284292
tcount: 0,
285-
gasPool: new(core.GasPool).AddGas(header.GasLimit),
293+
gasPool: new(core.GasPool).AddGas(capacity),
286294
rules: w.chainConfig.Rules(header.Number, header.Time),
287295
predicateContext: predicateContext,
288296
predicateResults: predicate.NewResults(),

plugin/evm/header/extra.go

+42-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package header
55

66
import (
7+
"bytes"
78
"errors"
89
"fmt"
910

@@ -12,18 +13,21 @@ import (
1213
"github.com/ava-labs/subnet-evm/plugin/evm/upgrade/subnetevm"
1314
)
1415

15-
var errInvalidExtraLength = errors.New("invalid header.Extra length")
16+
var (
17+
errInvalidExtraPrefix = errors.New("invalid header.Extra prefix")
18+
errInvalidExtraLength = errors.New("invalid header.Extra length")
19+
)
1620

1721
// ExtraPrefix takes the previous header and the timestamp of its child
1822
// block and calculates the expected extra prefix for the child block.
1923
func ExtraPrefix(
2024
config *params.ChainConfig,
2125
parent *types.Header,
22-
timestamp uint64,
26+
header *types.Header,
2327
) ([]byte, error) {
2428
switch {
25-
case config.IsSubnetEVM(timestamp):
26-
window, err := feeWindow(config, parent, timestamp)
29+
case config.IsSubnetEVM(header.Time):
30+
window, err := feeWindow(config, parent, header.Time)
2731
if err != nil {
2832
return nil, fmt.Errorf("failed to calculate fee window: %w", err)
2933
}
@@ -34,8 +38,35 @@ func ExtraPrefix(
3438
}
3539
}
3640

41+
// VerifyExtraPrefix verifies that the header's Extra field is correctly
42+
// formatted.
43+
func VerifyExtraPrefix(
44+
config *params.ChainConfig,
45+
parent *types.Header,
46+
header *types.Header,
47+
) error {
48+
switch {
49+
case config.IsSubnetEVM(header.Time):
50+
feeWindow, err := feeWindow(config, parent, header.Time)
51+
if err != nil {
52+
return fmt.Errorf("calculating expected fee window: %w", err)
53+
}
54+
feeWindowBytes := feeWindow.Bytes()
55+
if !bytes.HasPrefix(header.Extra, feeWindowBytes) {
56+
return fmt.Errorf("%w: expected %x as prefix, found %x",
57+
errInvalidExtraPrefix,
58+
feeWindowBytes,
59+
header.Extra,
60+
)
61+
}
62+
}
63+
return nil
64+
}
65+
3766
// VerifyExtra verifies that the header's Extra field is correctly formatted for
38-
// [rules].
67+
// rules.
68+
//
69+
// TODO: Should this be merged with VerifyExtraPrefix?
3970
func VerifyExtra(rules params.AvalancheRules, extra []byte) error {
4071
extraLen := len(extra)
4172
switch {
@@ -72,13 +103,13 @@ func VerifyExtra(rules params.AvalancheRules, extra []byte) error {
72103

73104
// PredicateBytesFromExtra returns the predicate result bytes from the header's
74105
// extra data. If the extra data is not long enough, an empty slice is returned.
75-
func PredicateBytesFromExtra(_ params.AvalancheRules, extra []byte) []byte {
106+
func PredicateBytesFromExtra(rules params.AvalancheRules, extra []byte) []byte {
107+
offset := subnetevm.WindowSize
76108
// Prior to Durango, the VM enforces the extra data is smaller than or equal
77-
// to this size.
78-
// After Durango, the VM pre-verifies the extra data past the dynamic fee
79-
// rollup window is valid.
80-
if len(extra) <= subnetevm.WindowSize {
109+
// to `offset`.
110+
// After Durango, the VM pre-verifies the extra data past `offset` is valid.
111+
if len(extra) <= offset {
81112
return nil
82113
}
83-
return extra[subnetevm.WindowSize:]
114+
return extra[offset:]
84115
}

0 commit comments

Comments
 (0)