Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(core/types): Block libevm Body and RLP hooks #750

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions accounts/abi/bind/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,11 @@ func golangBindings(t *testing.T, overload bool) {
if out, err := replacer.CombinedOutput(); err != nil {
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
}
replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/ava-labs/libevm@v0.0.0", "-replace", "github.com/ava-labs/libevm=github.com/ava-labs/libevm@v0.0.0-20250122094956-11c780f117f8")
replacer.Dir = pkg
if out, err := replacer.CombinedOutput(); err != nil {
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
}
tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.22")
tidier.Dir = pkg
if out, err := tidier.CombinedOutput(); err != nil {
Expand Down
44 changes: 23 additions & 21 deletions consensus/dummy/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,13 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header
}

// Verify BlockGasCost, ExtDataGasUsed not present before AP4
headerExtra := types.HeaderExtras(header)
if !configExtra.IsApricotPhase4(header.Time) {
if header.BlockGasCost != nil {
return fmt.Errorf("invalid blockGasCost before fork: have %d, want <nil>", header.BlockGasCost)
if headerExtra.BlockGasCost != nil {
return fmt.Errorf("invalid blockGasCost before fork: have %d, want <nil>", headerExtra.BlockGasCost)
}
if header.ExtDataGasUsed != nil {
return fmt.Errorf("invalid extDataGasUsed before fork: have %d, want <nil>", header.ExtDataGasUsed)
if headerExtra.ExtDataGasUsed != nil {
return fmt.Errorf("invalid extDataGasUsed before fork: have %d, want <nil>", headerExtra.ExtDataGasUsed)
}
return nil
}
Expand All @@ -188,24 +189,24 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header
ApricotPhase4MinBlockGasCost,
ApricotPhase4MaxBlockGasCost,
blockGasCostStep,
parent.BlockGasCost,
types.HeaderExtras(parent).BlockGasCost,
parent.Time, header.Time,
)
if header.BlockGasCost == nil {
if headerExtra.BlockGasCost == nil {
return errBlockGasCostNil
}
if !header.BlockGasCost.IsUint64() {
if !headerExtra.BlockGasCost.IsUint64() {
return errBlockGasCostTooLarge
}
if header.BlockGasCost.Cmp(expectedBlockGasCost) != 0 {
return fmt.Errorf("invalid block gas cost: have %d, want %d", header.BlockGasCost, expectedBlockGasCost)
if headerExtra.BlockGasCost.Cmp(expectedBlockGasCost) != 0 {
return fmt.Errorf("invalid block gas cost: have %d, want %d", headerExtra.BlockGasCost, expectedBlockGasCost)
}
// ExtDataGasUsed correctness is checked during block validation
// (when the validator has access to the block contents)
if header.ExtDataGasUsed == nil {
if headerExtra.ExtDataGasUsed == nil {
return errExtDataGasUsedNil
}
if !header.ExtDataGasUsed.IsUint64() {
if !headerExtra.ExtDataGasUsed.IsUint64() {
return errExtDataGasUsedTooLarge
}
return nil
Expand Down Expand Up @@ -403,7 +404,7 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types
if extDataGasUsed == nil {
extDataGasUsed = new(big.Int).Set(common.Big0)
}
if blockExtDataGasUsed := block.ExtDataGasUsed(); blockExtDataGasUsed == nil || !blockExtDataGasUsed.IsUint64() || blockExtDataGasUsed.Cmp(extDataGasUsed) != 0 {
if blockExtDataGasUsed := types.BlockExtDataGasUsed(block); blockExtDataGasUsed == nil || !blockExtDataGasUsed.IsUint64() || blockExtDataGasUsed.Cmp(extDataGasUsed) != 0 {
return fmt.Errorf("invalid extDataGasUsed: have %d, want %d", blockExtDataGasUsed, extDataGasUsed)
}
blockGasCostStep := ApricotPhase4BlockGasCostStep
Expand All @@ -417,17 +418,17 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types
ApricotPhase4MinBlockGasCost,
ApricotPhase4MaxBlockGasCost,
blockGasCostStep,
parent.BlockGasCost,
types.HeaderExtras(parent).BlockGasCost,
parent.Time, block.Time(),
)
// Verify the BlockGasCost set in the header matches the calculated value.
if blockBlockGasCost := block.BlockGasCost(); blockBlockGasCost == nil || !blockBlockGasCost.IsUint64() || blockBlockGasCost.Cmp(blockGasCost) != 0 {
if blockBlockGasCost := types.BlockGasCost(block); blockBlockGasCost == nil || !blockBlockGasCost.IsUint64() || blockBlockGasCost.Cmp(blockGasCost) != 0 {
return fmt.Errorf("invalid blockGasCost: have %d, want %d", blockBlockGasCost, blockGasCost)
}
// Verify the block fee was paid.
if err := eng.verifyBlockFee(
block.BaseFee(),
block.BlockGasCost(),
types.BlockGasCost(block),
block.Transactions(),
receipts,
contribution,
Expand All @@ -454,28 +455,29 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h
}
}
chainConfigExtra := params.GetExtra(chain.Config())
headerExtra := types.HeaderExtras(header)
if chainConfigExtra.IsApricotPhase4(header.Time) {
header.ExtDataGasUsed = extDataGasUsed
if header.ExtDataGasUsed == nil {
header.ExtDataGasUsed = new(big.Int).Set(common.Big0)
headerExtra.ExtDataGasUsed = extDataGasUsed
if headerExtra.ExtDataGasUsed == nil {
headerExtra.ExtDataGasUsed = new(big.Int).Set(common.Big0)
}
blockGasCostStep := ApricotPhase4BlockGasCostStep
if chainConfigExtra.IsApricotPhase5(header.Time) {
blockGasCostStep = ApricotPhase5BlockGasCostStep
}
// Calculate the required block gas cost for this block.
header.BlockGasCost = calcBlockGasCost(
headerExtra.BlockGasCost = calcBlockGasCost(
ApricotPhase4TargetBlockRate,
ApricotPhase4MinBlockGasCost,
ApricotPhase4MaxBlockGasCost,
blockGasCostStep,
parent.BlockGasCost,
types.HeaderExtras(parent).BlockGasCost,
parent.Time, header.Time,
)
// Verify that this block covers the block fee.
if err := eng.verifyBlockFee(
header.BaseFee,
header.BlockGasCost,
headerExtra.BlockGasCost,
txs,
receipts,
contribution,
Expand Down
20 changes: 11 additions & 9 deletions consensus/dummy/dynamic_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,15 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header, timestamp uin
// gas in.
if roll < rollupWindow {
var blockGasCost, parentExtraStateGasUsed uint64
parentExtra := types.HeaderExtras(parent)
switch {
case isApricotPhase5:
// [blockGasCost] has been removed in AP5, so it is left as 0.

// At the start of a new network, the parent
// may not have a populated [ExtDataGasUsed].
if parent.ExtDataGasUsed != nil {
parentExtraStateGasUsed = parent.ExtDataGasUsed.Uint64()
if parentExtra.ExtDataGasUsed != nil {
parentExtraStateGasUsed = parentExtra.ExtDataGasUsed.Uint64()
}
case isApricotPhase4:
// The [blockGasCost] is paid by the effective tips in the block using
Expand All @@ -107,14 +108,14 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header, timestamp uin
ApricotPhase4MinBlockGasCost,
ApricotPhase4MaxBlockGasCost,
ApricotPhase4BlockGasCostStep,
parent.BlockGasCost,
parentExtra.BlockGasCost,
parent.Time, timestamp,
).Uint64()

// On the boundary of AP3 and AP4 or at the start of a new network, the parent
// may not have a populated [ExtDataGasUsed].
if parent.ExtDataGasUsed != nil {
parentExtraStateGasUsed = parent.ExtDataGasUsed.Uint64()
if parentExtra.ExtDataGasUsed != nil {
parentExtraStateGasUsed = parentExtra.ExtDataGasUsed.Uint64()
}
default:
blockGasCost = ApricotPhase3BlockGasFee
Expand Down Expand Up @@ -339,21 +340,22 @@ func MinRequiredTip(config *params.ChainConfig, header *types.Header) (*big.Int,
if header.BaseFee == nil {
return nil, errBaseFeeNil
}
if header.BlockGasCost == nil {
headerExtra := types.HeaderExtras(header)
if headerExtra.BlockGasCost == nil {
return nil, errBlockGasCostNil
}
if header.ExtDataGasUsed == nil {
if headerExtra.ExtDataGasUsed == nil {
return nil, errExtDataGasUsedNil
}

// minTip = requiredBlockFee/blockGasUsage
requiredBlockFee := new(big.Int).Mul(
header.BlockGasCost,
headerExtra.BlockGasCost,
header.BaseFee,
)
blockGasUsage := new(big.Int).Add(
new(big.Int).SetUint64(header.GasUsed),
header.ExtDataGasUsed,
headerExtra.ExtDataGasUsed,
)
return new(big.Int).Div(requiredBlockFee, blockGasUsage), nil
}
15 changes: 8 additions & 7 deletions consensus/dummy/dynamic_fees_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,14 +425,15 @@ func TestCalcBaseFeeAP4(t *testing.T) {
nextExtraData, nextBaseFee, err = CalcBaseFee(params.TestApricotPhase4Config, extDataHeader, block.timestamp)
assert.NoError(t, err)
log.Info("Update", "baseFee (w/extData)", nextBaseFee)
extDataHeader = &types.Header{
Time: block.timestamp,
GasUsed: block.gasUsed,
Number: big.NewInt(int64(index) + 1),
BaseFee: nextBaseFee,
Extra: nextExtraData,
extDataHeader = types.WithHeaderExtras(&types.Header{
Time: block.timestamp,
GasUsed: block.gasUsed,
Number: big.NewInt(int64(index) + 1),
BaseFee: nextBaseFee,
Extra: nextExtraData,
}, &types.HeaderExtra{
ExtDataGasUsed: block.extDataGasUsed,
}
})

assert.Equal(t, event.extDataFeeGreater, extDataHeader.BaseFee.Cmp(header.BaseFee) == 1, "unexpected cmp for index %d", index)
}
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,7 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error {
"parentHash", block.ParentHash(),
"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
"elapsed", common.PrettyDuration(time.Since(start)),
"root", block.Root(), "baseFeePerGas", block.BaseFee(), "blockGasCost", block.BlockGasCost(),
"root", block.Root(), "baseFeePerGas", block.BaseFee(), "blockGasCost", types.BlockGasCost(block),
)

processedBlockGasUsedCounter.Inc(int64(block.GasUsed()))
Expand Down
3 changes: 2 additions & 1 deletion core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ func (g *Genesis) toBlock(db ethdb.Database, triedb *triedb.Database) *types.Blo
}

// Configure any stateful precompiles that should be enabled in the genesis.
err = ApplyPrecompileActivations(g.Config, nil, types.NewBlockWithHeader(head), statedb)
block := types.NewBlockWithHeader(head)
err = ApplyPrecompileActivations(g.Config, nil, types.WrapWithTimestamp(block), statedb)
if err != nil {
panic(fmt.Sprintf("unable to configure precompiles in genesis block: %v", err))
}
Expand Down
5 changes: 4 additions & 1 deletion core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,10 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
if body == nil {
return nil
}
return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles).WithExtData(body.Version, body.ExtData)
block := types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
bodyExtra := types.GetBodyExtra(body)
block = types.WithBlockExtra(block, bodyExtra.Version, bodyExtra.ExtData, false)
return block
}

// WriteBlock serializes a block into the database, header and body separately.
Expand Down
2 changes: 1 addition & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state
)

// Configure any upgrades that should go into effect during this block.
err := ApplyUpgrades(p.config, &parent.Time, block, statedb)
err := ApplyUpgrades(p.config, &parent.Time, types.WrapWithTimestamp(block), statedb)
if err != nil {
log.Error("failed to configure precompiles processing block", "hash", block.Hash(), "number", block.NumberU64(), "timestamp", block.Time(), "err", err)
return nil, nil, 0, err
Expand Down
4 changes: 2 additions & 2 deletions core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
header.Extra, header.BaseFee, _ = dummy.CalcBaseFee(config, parent.Header(), header.Time)
}
if params.GetExtra(config).IsApricotPhase4(header.Time) {
header.BlockGasCost = big.NewInt(0)
header.ExtDataGasUsed = big.NewInt(0)
types.HeaderExtras(header).BlockGasCost = big.NewInt(0)
types.HeaderExtras(header).ExtDataGasUsed = big.NewInt(0)
}
var receipts []*types.Receipt
// The post-state result doesn't need to be correct (this is a bad block), but we do need something there
Expand Down
Loading
Loading