From 2663434ea011935e97c07a84091961d36b7c33fe Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 24 Feb 2025 09:28:43 -0500 Subject: [PATCH 1/5] Update ACP-176 math (#827) --- plugin/evm/upgrade/acp176/acp176.go | 47 ++++++++-------- plugin/evm/upgrade/acp176/acp176_test.go | 70 ++++++++++++++++++------ 2 files changed, 76 insertions(+), 41 deletions(-) diff --git a/plugin/evm/upgrade/acp176/acp176.go b/plugin/evm/upgrade/acp176/acp176.go index 88b582749f..c262ab7e79 100644 --- a/plugin/evm/upgrade/acp176/acp176.go +++ b/plugin/evm/upgrade/acp176/acp176.go @@ -25,7 +25,7 @@ const ( TimeToFillCapacity = 10 // in seconds TargetToMax = 2 // multiplier to convert from target per second to max per second - TargetToPriceUpdateConversion = 43 // 43s ~= 30s * ln(2) which makes the price double at most every ~30 seconds + TargetToPriceUpdateConversion = 87 // 87s ~= 60s * ln(2) which makes the price double at most every ~60 seconds MaxTargetChangeRate = 1024 // Controls the rate that the target can change per block. targetToMaxCapacity = TargetToMax * TimeToFillCapacity @@ -52,23 +52,15 @@ func (s *State) Target() gas.Gas { // MaxCapacity returns the maximum possible accrued gas capacity, `C`. func (s *State) MaxCapacity() gas.Gas { targetPerSecond := s.Target() - maxCapacity, err := safemath.Mul(targetToMaxCapacity, targetPerSecond) - if err != nil { - maxCapacity = math.MaxUint64 - } - return maxCapacity + return mulWithUpperBound(targetPerSecond, targetToMaxCapacity) } // GasPrice returns the current required fee per gas. // // GasPrice = MinGasPrice * e^(Excess / (Target() * TargetToPriceUpdateConversion)) func (s *State) GasPrice() gas.Price { - target := s.Target() - priceUpdateConversion, err := safemath.Mul(TargetToPriceUpdateConversion, target) // K - if err != nil { - priceUpdateConversion = math.MaxUint64 - } - + targetPerSecond := s.Target() + priceUpdateConversion := mulWithUpperBound(targetPerSecond, TargetToPriceUpdateConversion) // K return gas.CalculatePrice(MinGasPrice, s.Gas.Excess, priceUpdateConversion) } @@ -76,14 +68,8 @@ func (s *State) GasPrice() gas.Price { // the elapsed seconds. func (s *State) AdvanceTime(seconds uint64) { targetPerSecond := s.Target() - maxPerSecond, err := safemath.Mul(TargetToMax, targetPerSecond) // R - if err != nil { - maxPerSecond = math.MaxUint64 - } - maxCapacity, err := safemath.Mul(TimeToFillCapacity, maxPerSecond) // C - if err != nil { - maxCapacity = math.MaxUint64 - } + maxPerSecond := mulWithUpperBound(targetPerSecond, TargetToMax) // R + maxCapacity := mulWithUpperBound(maxPerSecond, TimeToFillCapacity) // C s.Gas = s.Gas.AdvanceTime( maxCapacity, maxPerSecond, @@ -134,15 +120,18 @@ func (s *State) UpdateTargetExcess(desiredTargetExcess gas.Gas) { newTargetPerSecond, previousTargetPerSecond, ) + + // Ensure the gas capacity does not exceed the maximum capacity. + newMaxCapacity := mulWithUpperBound(newTargetPerSecond, targetToMaxCapacity) // C + s.Gas.Capacity = min(s.Gas.Capacity, newMaxCapacity) } // DesiredTargetExcess calculates the optimal desiredTargetExcess given the // desired target. -// -// This could be solved directly by calculating D * ln(desiredTarget / P) using -// floating point math. However, it introduces inaccuracies. So, we use a binary -// search to find the closest integer solution. func DesiredTargetExcess(desiredTarget gas.Gas) gas.Gas { + // This could be solved directly by calculating D * ln(desiredTarget / P) + // using floating point math. However, it introduces inaccuracies. So, we + // use a binary search to find the closest integer solution. return gas.Gas(sort.Search(maxTargetExcess, func(targetExcessGuess int) bool { state := State{ TargetExcess: gas.Gas(targetExcessGuess), @@ -180,3 +169,13 @@ func scaleExcess( bigExcess.Div(&bigExcess, &bigTarget) return gas.Gas(bigExcess.Uint64()) } + +// mulWithUpperBound multiplies two numbers and returns the result. If the +// result overflows, it returns [math.MaxUint64]. +func mulWithUpperBound(a, b gas.Gas) gas.Gas { + product, err := safemath.Mul(a, b) + if err != nil { + return math.MaxUint64 + } + return product +} diff --git a/plugin/evm/upgrade/acp176/acp176_test.go b/plugin/evm/upgrade/acp176/acp176_test.go index be509292ca..32104f32c9 100644 --- a/plugin/evm/upgrade/acp176/acp176_test.go +++ b/plugin/evm/upgrade/acp176/acp176_test.go @@ -40,7 +40,7 @@ var ( name: "almost_excess_change", state: State{ Gas: gas.State{ - Excess: 29_805_331, // MinTargetPerSecond * ln(2) * TargetToPriceUpdateConversion + Excess: 60_303_808, // MinTargetPerSecond * ln(2) * TargetToPriceUpdateConversion }, TargetExcess: 33, // Largest excess that doesn't increase the target }, @@ -53,7 +53,7 @@ var ( name: "small_excess_change", state: State{ Gas: gas.State{ - Excess: 29_805_362, // (MinTargetPerSecond + 1) * ln(2) * TargetToPriceUpdateConversion + Excess: 60_303_868, // (MinTargetPerSecond + 1) * ln(2) * TargetToPriceUpdateConversion }, TargetExcess: 34, // Smallest excess that increases the target }, @@ -65,7 +65,7 @@ var ( name: "max_initial_excess_change", state: State{ Gas: gas.State{ - Excess: 47_286_485, // (MinTargetPerSecond + 977) * ln(3) * TargetToPriceUpdateConversion + Excess: 95_672_652, // (MinTargetPerSecond + 977) * ln(3) * TargetToPriceUpdateConversion }, TargetExcess: MaxTargetExcessDiff, }, @@ -78,85 +78,85 @@ var ( name: "current_target", state: State{ Gas: gas.State{ - Excess: 1_336_650_647, // 1_500_000 * ln(nAVAX) * TargetToPriceUpdateConversion + Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 13_605_152, // 2^25 * ln(1.5) }, target: 1_500_000, maxCapacity: targetToMaxCapacity * 1_500_000, - gasPrice: (nAVAX + 7) * MinGasPrice, // +7 due to approximation + gasPrice: nAVAX*MinGasPrice + 2, // +2 due to approximation }, { name: "3m_target", state: State{ Gas: gas.State{ - Excess: 3_267_368_247, // 3_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion + Excess: 6_610_721_802, // 3_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 36_863_312, // 2^25 * ln(3) }, target: 3_000_000, maxCapacity: targetToMaxCapacity * 3_000_000, - gasPrice: (100*nAVAX + 31) * MinGasPrice, // +31 due to approximation + gasPrice: 100*nAVAX*MinGasPrice + 4, // +4 due to approximation }, { name: "6m_target", state: State{ Gas: gas.State{ - Excess: 6_534_736_494, // 6_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion + Excess: 13_221_443_604, // 6_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 60_121_472, // 2^25 * ln(6) }, target: 6_000_000, maxCapacity: targetToMaxCapacity * 6_000_000, - gasPrice: (100*nAVAX + 31) * MinGasPrice, // +31 due to approximation + gasPrice: 100*nAVAX*MinGasPrice + 4, // +4 due to approximation }, { name: "10m_target", state: State{ Gas: gas.State{ - Excess: 10_891_227_490, // 10_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion + Excess: 22_035_739_340, // 10_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 77_261_935, // 2^25 * ln(10) }, target: 10_000_000, maxCapacity: targetToMaxCapacity * 10_000_000, - gasPrice: (100*nAVAX + 31) * MinGasPrice, // +31 due to approximation + gasPrice: 100*nAVAX*MinGasPrice + 5, // +5 due to approximation }, { name: "100m_target", state: State{ Gas: gas.State{ - Excess: 108_912_274_899, // 100_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion + Excess: 220_357_393_400, // 100_000_000 * ln(100*nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 154_523_870, // 2^25 * ln(100) }, target: 100_000_000, maxCapacity: targetToMaxCapacity * 100_000_000, - gasPrice: (100*nAVAX + 8) * MinGasPrice, // +8 due to approximation + gasPrice: 100*nAVAX*MinGasPrice + 5, // +5 due to approximation }, { name: "low_1b_target", state: State{ Gas: gas.State{ - Excess: 1_089_122_722_848, // (1_000_000_000 - 24) * ln(100*nAVAX) * TargetToPriceUpdateConversion + Excess: 2_203_573_881_110, // (1_000_000_000 - 24) * ln(100*nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 231_785_804, // 2^25 * ln(1000) }, target: 1_000_000_000 - 24, maxCapacity: targetToMaxCapacity * (1_000_000_000 - 24), - gasPrice: (100*nAVAX + 1) * MinGasPrice, // +1 due to approximation + gasPrice: 100 * nAVAX * MinGasPrice, }, { name: "high_1b_target", state: State{ Gas: gas.State{ - Excess: 1_089_122_755_521, // (1_000_000_000 + 6) * ln(100*nAVAX) * TargetToPriceUpdateConversion + Excess: 2_203_573_947_217, // (1_000_000_000 + 6) * ln(100*nAVAX) * TargetToPriceUpdateConversion }, TargetExcess: 231_785_805, // 2^25 * ln(1000) + 1 }, target: 1_000_000_000 + 6, maxCapacity: targetToMaxCapacity * (1_000_000_000 + 6), - gasPrice: (100 * nAVAX) * MinGasPrice, + gasPrice: 100 * nAVAX * MinGasPrice, }, { name: "largest_max_capacity", @@ -558,6 +558,42 @@ var ( TargetExcess: 2 * MaxTargetExcessDiff, }, }, + { + name: "reduce_capacity", + initial: State{ + Gas: gas.State{ + Capacity: 20_039_100, // MinTargetPerSecond * e^(2*MaxTargetExcessDiff / TargetConversion) + Excess: 2_000_000_000, + }, + TargetExcess: 2 * MaxTargetExcessDiff, + }, + desiredTargetExcess: 0, + expected: State{ + Gas: gas.State{ + Capacity: 20_019_540, // MinTargetPerSecond * e^(MaxTargetExcessDiff / TargetConversion) + Excess: 1_998_047_816, // 2M * NewTarget / OldTarget + }, + TargetExcess: MaxTargetExcessDiff, + }, + }, + { + name: "overflow_max_capacity", + initial: State{ + Gas: gas.State{ + Capacity: math.MaxUint64, + Excess: 2_000_000_000, + }, + TargetExcess: maxTargetExcess, + }, + desiredTargetExcess: 0, + expected: State{ + Gas: gas.State{ + Capacity: math.MaxUint64, + Excess: 1_998_047_867, // 2M * NewTarget / OldTarget + }, + TargetExcess: maxTargetExcess - MaxTargetExcessDiff, + }, + }, } ) From 1cfe453eb0771242eaf1277facb55a21c7030813 Mon Sep 17 00:00:00 2001 From: Quentin Mc Gaw Date: Mon, 24 Feb 2025 19:33:23 +0100 Subject: [PATCH 2/5] Fix merge --- core/evm.go | 9 ++------- predicate/predicate_bytes.go | 8 -------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/core/evm.go b/core/evm.go index 8f9559b44c..8630775370 100644 --- a/core/evm.go +++ b/core/evm.go @@ -27,7 +27,6 @@ package core import ( - "bytes" "math/big" "github.com/ava-labs/coreth/consensus" @@ -126,12 +125,8 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common // in header.Extra. // This function is used to create a BlockContext when the header Extra data is not fully formed yet and it's more efficient to pass in predicateResults // directly rather than re-encode the latest results when executing each individaul transaction. -func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateBytes []byte) vm.BlockContext { - extra := bytes.Clone(header.Extra) - if len(predicateBytes) > 0 { - extra = predicate.SetPredicateResultBytes(extra, predicateBytes) - } - return newEVMBlockContext(header, chain, author, extra) +func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateResults []byte) vm.BlockContext { + return newEVMBlockContext(header, chain, author, predicateResults) } func newEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, extra []byte) vm.BlockContext { diff --git a/predicate/predicate_bytes.go b/predicate/predicate_bytes.go index 9df1f4860e..3f235143c6 100644 --- a/predicate/predicate_bytes.go +++ b/predicate/predicate_bytes.go @@ -66,11 +66,3 @@ func GetPredicateResultBytes(extraData []byte) []byte { // predicate results. return extraData[HeaderFeeWindowSize:] } - -// SetPredicateResultBytes sets the predicate results in the extraData in the -// block header. This is used to set the predicate results in a block header -// without modifying the initial portion of the extra data (dynamic fee window -// rollup). -func SetPredicateResultBytes(extraData []byte, predicateResults []byte) []byte { - return append(extraData[:HeaderFeeWindowSize], predicateResults...) -} From 825929d3717124c467753a5b8851ba1729d9521e Mon Sep 17 00:00:00 2001 From: Darioush Jalali Date: Thu, 27 Feb 2025 14:41:22 -0800 Subject: [PATCH 3/5] refactor(plugin/evm/headers): don't import params --- core/block_validator.go | 9 +- params/config.go | 286 +++------------------------- params/extras/config.go | 82 ++++++++ params/protocol_params.go | 10 +- plugin/evm/header/base_fee_test.go | 39 ++-- plugin/evm/header/extra.go | 11 +- plugin/evm/header/extra_test.go | 29 ++- plugin/evm/header/gas_limit.go | 15 +- plugin/evm/header/gas_limit_test.go | 35 ++-- plugin/evm/imports_test.go | 1 + 10 files changed, 188 insertions(+), 329 deletions(-) diff --git a/core/block_validator.go b/core/block_validator.go index 2c0fdceaf3..f7d026e400 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -34,6 +34,7 @@ import ( "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/libevm/trie" ) @@ -147,10 +148,10 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD // the gas allowance. func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint64 { // contrib = (parentGasUsed * 3 / 2) / 1024 - contrib := (parentGasUsed + parentGasUsed/2) / params.GasLimitBoundDivisor + contrib := (parentGasUsed + parentGasUsed/2) / header.GasLimitBoundDivisor // decay = parentGasLimit / 1024 -1 - decay := parentGasLimit/params.GasLimitBoundDivisor - 1 + decay := parentGasLimit/header.GasLimitBoundDivisor - 1 /* strategy: gasLimit of block-to-mine is set based on parent's @@ -160,8 +161,8 @@ func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint6 from parentGasLimit * (2/3) parentGasUsed is. */ limit := parentGasLimit - decay + contrib - if limit < params.MinGasLimit { - limit = params.MinGasLimit + if limit < header.MinGasLimit { + limit = header.MinGasLimit } // If we're outside our allowed gas range, we try to hone towards them if limit < gasFloor { diff --git a/params/config.go b/params/config.go index 7a783b9231..873e5ebfbb 100644 --- a/params/config.go +++ b/params/config.go @@ -69,23 +69,8 @@ var ( ShanghaiTime: utils.TimeToNewUint64(upgrade.GetConfig(constants.UnitTestID).DurangoTime), CancunTime: utils.TimeToNewUint64(upgrade.GetConfig(constants.UnitTestID).EtnaTime), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: utils.NewUint64(0), - }, - }) + extras.TestChainConfig, + ) TestLaunchConfig = WithExtra( &ChainConfig{ @@ -102,23 +87,8 @@ var ( IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: nil, - ApricotPhase2BlockTimestamp: nil, - ApricotPhase3BlockTimestamp: nil, - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestLaunchConfig, + ) TestApricotPhase1Config = WithExtra( &ChainConfig{ @@ -135,23 +105,8 @@ var ( IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: nil, - ApricotPhase3BlockTimestamp: nil, - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhase1Config, + ) TestApricotPhase2Config = WithExtra( &ChainConfig{ @@ -169,23 +124,8 @@ var ( MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: nil, - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhase2Config, + ) TestApricotPhase3Config = WithExtra( &ChainConfig{ @@ -204,23 +144,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhase3Config, + ) TestApricotPhase4Config = WithExtra( &ChainConfig{ @@ -239,23 +164,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhase4Config, + ) TestApricotPhase5Config = WithExtra( &ChainConfig{ @@ -274,23 +184,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhase5Config, + ) TestApricotPhasePre6Config = WithExtra( &ChainConfig{ @@ -309,23 +204,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhasePre6Config, + ) TestApricotPhase6Config = WithExtra( &ChainConfig{ @@ -344,23 +224,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhase6Config, + ) TestApricotPhasePost6Config = WithExtra( &ChainConfig{ @@ -379,23 +244,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestApricotPhasePost6Config, + ) TestBanffChainConfig = WithExtra( &ChainConfig{ @@ -414,23 +264,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestBanffChainConfig, + ) TestCortinaChainConfig = WithExtra( &ChainConfig{ @@ -449,23 +284,8 @@ var ( BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - }, - }) + extras.TestCortinaChainConfig, + ) TestDurangoChainConfig = WithExtra( &ChainConfig{ @@ -485,23 +305,8 @@ var ( LondonBlock: big.NewInt(0), ShanghaiTime: utils.NewUint64(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: nil, - }, - }) + extras.TestDurangoChainConfig, + ) TestEtnaChainConfig = WithExtra( &ChainConfig{ @@ -522,23 +327,8 @@ var ( ShanghaiTime: utils.NewUint64(0), CancunTime: utils.NewUint64(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: utils.NewUint64(0), - }, - }) + extras.TestEtnaChainConfig, + ) TestFUpgradeChainConfig = WithExtra( &ChainConfig{ @@ -559,24 +349,8 @@ var ( ShanghaiTime: utils.NewUint64(0), CancunTime: utils.NewUint64(0), }, - &extras.ChainConfig{ - AvalancheContext: extras.AvalancheContext{SnowCtx: utils.TestSnowContext()}, - NetworkUpgrades: extras.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: utils.NewUint64(0), - FUpgradeTimestamp: utils.NewUint64(0), - }, - }) + extras.TestFUpgradeChainConfig, + ) TestRules = TestChainConfig.Rules(new(big.Int), IsMergeTODO, 0) ) diff --git a/params/extras/config.go b/params/extras/config.go index 14b17bc56e..8d600093e9 100644 --- a/params/extras/config.go +++ b/params/extras/config.go @@ -14,6 +14,88 @@ import ( ethparams "github.com/ava-labs/libevm/params" ) +var ( + TestChainConfig = &ChainConfig{ + AvalancheContext: AvalancheContext{SnowCtx: utils.TestSnowContext()}, + NetworkUpgrades: NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), + ApricotPhase6BlockTimestamp: utils.NewUint64(0), + ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), + BanffBlockTimestamp: utils.NewUint64(0), + CortinaBlockTimestamp: utils.NewUint64(0), + DurangoBlockTimestamp: utils.NewUint64(0), + EtnaTimestamp: utils.NewUint64(0), + }, + } + + copyAndSet = func(c *ChainConfig, set func(*ChainConfig)) *ChainConfig { + newConfig := *c + set(&newConfig) + return &newConfig + } + + TestLaunchConfig = &ChainConfig{ + AvalancheContext: AvalancheContext{SnowCtx: utils.TestSnowContext()}, + } + + TestApricotPhase1Config = copyAndSet(TestLaunchConfig, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase1BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase2Config = copyAndSet(TestApricotPhase1Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase2BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase3Config = copyAndSet(TestApricotPhase2Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase3BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase4Config = copyAndSet(TestApricotPhase3Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase4BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase5Config = copyAndSet(TestApricotPhase4Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase5BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhasePre6Config = copyAndSet(TestApricotPhase5Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhasePre6BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase6Config = copyAndSet(TestApricotPhasePre6Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase6BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhasePost6Config = copyAndSet(TestApricotPhase6Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhasePost6BlockTimestamp = utils.NewUint64(0) + }) + + TestBanffChainConfig = copyAndSet(TestApricotPhasePost6Config, func(c *ChainConfig) { + c.NetworkUpgrades.BanffBlockTimestamp = utils.NewUint64(0) + }) + + TestCortinaChainConfig = copyAndSet(TestBanffChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.CortinaBlockTimestamp = utils.NewUint64(0) + }) + + TestDurangoChainConfig = copyAndSet(TestCortinaChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.DurangoBlockTimestamp = utils.NewUint64(0) + }) + + TestEtnaChainConfig = copyAndSet(TestDurangoChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.EtnaTimestamp = utils.NewUint64(0) + }) + + TestFUpgradeChainConfig = copyAndSet(TestEtnaChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.FUpgradeTimestamp = utils.NewUint64(0) + }) +) + // UpgradeConfig includes the following configs that may be specified in upgradeBytes: // - Timestamps that enable avalanche network upgrades, // - Enabling or disabling precompiles as network upgrades. diff --git a/params/protocol_params.go b/params/protocol_params.go index 6bdb5893c1..1d8ed7f9e1 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -33,14 +33,8 @@ import ( ) const ( - GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. - MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. - MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). - GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. - - // Note: MaximumExtraDataSize has been reduced to 32 in Geth, but is kept the same in Coreth for - // backwards compatibility. - MaximumExtraDataSize uint64 = 64 // Maximum size extra data may be after Genesis. + GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. + ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero. diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index 0deeb4350e..be78a64468 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" @@ -30,7 +29,7 @@ func TestBaseFee(t *testing.T) { }{ { name: "ap2", - upgrades: params.GetExtra(params.TestApricotPhase2Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, want: nil, wantErr: nil, }, @@ -47,7 +46,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_genesis_block", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -55,7 +54,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_invalid_fee_window", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -63,7 +62,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_invalid_timestamp", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Time: 1, @@ -74,7 +73,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_no_change", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas - ap3.IntrinsicBlockGas, @@ -87,7 +86,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_small_decrease", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: feeWindowBytes(ap3.Window{}), @@ -110,7 +109,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_large_decrease", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: feeWindowBytes(ap3.Window{}), @@ -134,7 +133,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_increase", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: 2 * ap3.TargetGas, @@ -158,7 +157,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_big_1_not_modified", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: 1, @@ -170,7 +169,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap4_genesis_block", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -178,7 +177,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap4_decrease", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: feeWindowBytes(ap3.Window{}), @@ -202,7 +201,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap4_increase", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -228,7 +227,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap5_genesis_block", - upgrades: params.GetExtra(params.TestApricotPhase5Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -236,7 +235,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap5_decrease", - upgrades: params.GetExtra(params.TestApricotPhase5Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: feeWindowBytes(ap3.Window{}), @@ -259,7 +258,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap5_increase", - upgrades: params.GetExtra(params.TestApricotPhase5Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap5.TargetGas, @@ -284,7 +283,7 @@ func TestBaseFee(t *testing.T) { }, { name: "etna_genesis_block", - upgrades: params.GetExtra(params.TestEtnaChainConfig).NetworkUpgrades, + upgrades: extras.TestEtnaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -292,7 +291,7 @@ func TestBaseFee(t *testing.T) { }, { name: "etna_increase", - upgrades: params.GetExtra(params.TestEtnaChainConfig).NetworkUpgrades, + upgrades: extras.TestEtnaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap5.TargetGas, @@ -344,7 +343,7 @@ func TestEstimateNextBaseFee(t *testing.T) { }{ { name: "ap3", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: feeWindowBytes(ap3.Window{}), @@ -367,7 +366,7 @@ func TestEstimateNextBaseFee(t *testing.T) { }, { name: "ap3_not_scheduled", - upgrades: params.GetExtra(params.TestApricotPhase2Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, wantErr: errEstimateBaseFeeWithoutActivation, }, } diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index f3b7d11954..531b0428fb 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -8,10 +8,15 @@ import ( "fmt" "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" ) +const ( + // Note: MaximumExtraDataSize has been reduced to 32 in Geth, but is kept the same in Coreth for + // backwards compatibility. + MaximumExtraDataSize uint64 = 64 // Maximum size extra data may be after Genesis. +) + var errInvalidExtraLength = errors.New("invalid header.Extra length") // ExtraPrefix takes the previous header and the timestamp of its child block @@ -66,11 +71,11 @@ func VerifyExtra(rules extras.AvalancheRules, extra []byte) error { ) } default: - if uint64(extraLen) > params.MaximumExtraDataSize { + if uint64(extraLen) > MaximumExtraDataSize { return fmt.Errorf( "%w: expected <= %d but got %d", errInvalidExtraLength, - params.MaximumExtraDataSize, + MaximumExtraDataSize, extraLen, ) } diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index b7da6f2150..6977a78842 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" @@ -28,7 +27,7 @@ func TestExtraPrefix(t *testing.T) { }{ { name: "ap2", - upgrades: params.GetExtra(params.TestApricotPhase2Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, want: nil, wantErr: nil, }, @@ -45,7 +44,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_genesis_block", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -53,7 +52,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_invalid_fee_window", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -61,7 +60,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_invalid_timestamp", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Time: 1, @@ -72,7 +71,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_normal", - upgrades: params.GetExtra(params.TestApricotPhase3Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -92,7 +91,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_genesis_block", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -100,7 +99,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_no_block_gas_cost", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -116,7 +115,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_with_block_gas_cost", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -136,7 +135,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_with_extra_data_gas", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -156,7 +155,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_normal", - upgrades: params.GetExtra(params.TestApricotPhase4Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -182,7 +181,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap5_no_extra_data_gas", - upgrades: params.GetExtra(params.TestApricotPhase5Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap5.TargetGas, @@ -199,7 +198,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap5_normal", - upgrades: params.GetExtra(params.TestApricotPhase5Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap5.TargetGas, @@ -247,13 +246,13 @@ func TestVerifyExtra(t *testing.T) { { name: "initial_valid", rules: extras.AvalancheRules{}, - extra: make([]byte, params.MaximumExtraDataSize), + extra: make([]byte, MaximumExtraDataSize), expected: nil, }, { name: "initial_invalid", rules: extras.AvalancheRules{}, - extra: make([]byte, params.MaximumExtraDataSize+1), + extra: make([]byte, MaximumExtraDataSize+1), expected: errInvalidExtraLength, }, { diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index 25ee5a8e9c..e9b28c76b3 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -9,12 +9,17 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" ) +const ( + MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. + MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). + GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. +) + var errInvalidGasLimit = errors.New("invalid gas limit") // GasLimit takes the previous header and the timestamp of its child block and @@ -64,18 +69,18 @@ func VerifyGasLimit( ) } default: - if header.GasLimit < params.MinGasLimit || header.GasLimit > params.MaxGasLimit { + if header.GasLimit < MinGasLimit || header.GasLimit > MaxGasLimit { return fmt.Errorf("%w: %d not in range [%d, %d]", errInvalidGasLimit, header.GasLimit, - params.MinGasLimit, - params.MaxGasLimit, + MinGasLimit, + MaxGasLimit, ) } // Verify that the gas limit remains within allowed bounds diff := math.AbsDiff(parent.GasLimit, header.GasLimit) - limit := parent.GasLimit / params.GasLimitBoundDivisor + limit := parent.GasLimit / GasLimitBoundDivisor if diff >= limit { return fmt.Errorf("%w: have %d, want %d += %d", errInvalidGasLimit, diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index 14777035f2..ea2efd048b 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" @@ -24,17 +23,17 @@ func TestGasLimit(t *testing.T) { }{ { name: "cortina", - upgrades: params.GetExtra(params.TestCortinaChainConfig).NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, want: cortina.GasLimit, }, { name: "ap1", - upgrades: params.GetExtra(params.TestApricotPhase1Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase1Config.NetworkUpgrades, want: ap1.GasLimit, }, { name: "launch", - upgrades: params.GetExtra(params.TestLaunchConfig).NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ GasLimit: 1, }, @@ -62,14 +61,14 @@ func TestVerifyGasLimit(t *testing.T) { }{ { name: "cortina_valid", - upgrades: params.GetExtra(params.TestCortinaChainConfig).NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, header: &types.Header{ GasLimit: cortina.GasLimit, }, }, { name: "cortina_invalid", - upgrades: params.GetExtra(params.TestCortinaChainConfig).NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, header: &types.Header{ GasLimit: cortina.GasLimit + 1, }, @@ -77,14 +76,14 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "ap1_valid", - upgrades: params.GetExtra(params.TestApricotPhase1Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase1Config.NetworkUpgrades, header: &types.Header{ GasLimit: ap1.GasLimit, }, }, { name: "ap1_invalid", - upgrades: params.GetExtra(params.TestApricotPhase1Config).NetworkUpgrades, + upgrades: extras.TestApricotPhase1Config.NetworkUpgrades, header: &types.Header{ GasLimit: ap1.GasLimit + 1, }, @@ -92,7 +91,7 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "launch_valid", - upgrades: params.GetExtra(params.TestLaunchConfig).NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ GasLimit: 50_000, }, @@ -102,34 +101,34 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "launch_too_low", - upgrades: params.GetExtra(params.TestLaunchConfig).NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: params.MinGasLimit, + GasLimit: MinGasLimit, }, header: &types.Header{ - GasLimit: params.MinGasLimit - 1, + GasLimit: MinGasLimit - 1, }, want: errInvalidGasLimit, }, { name: "launch_too_high", - upgrades: params.GetExtra(params.TestLaunchConfig).NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: params.MaxGasLimit, + GasLimit: MaxGasLimit, }, header: &types.Header{ - GasLimit: params.MaxGasLimit + 1, + GasLimit: MaxGasLimit + 1, }, want: errInvalidGasLimit, }, { name: "change_too_large", - upgrades: params.GetExtra(params.TestLaunchConfig).NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: params.MinGasLimit, + GasLimit: MinGasLimit, }, header: &types.Header{ - GasLimit: params.MaxGasLimit, + GasLimit: MaxGasLimit, }, want: errInvalidGasLimit, }, diff --git a/plugin/evm/imports_test.go b/plugin/evm/imports_test.go index 5e8021d3e5..5089605493 100644 --- a/plugin/evm/imports_test.go +++ b/plugin/evm/imports_test.go @@ -57,6 +57,7 @@ func TestMustNotImport(t *testing.T) { "plugin/evm/atomic": {"core", "core/vm", "params"}, "plugin/evm/client": {"core", "core/vm", "params"}, "plugin/evm/config": {"core", "core/vm", "params"}, + "plugin/evm/header": {"core", "core/vm", "params"}, } for packageName, forbiddenImports := range mustNotImport { From a82c6bedd1fe36f3c4d37d01770fa740cd5b243c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 25 Feb 2025 00:13:11 -0500 Subject: [PATCH 4/5] Move predicate header parsing (#824) clone header --- core/evm.go | 47 +++++++++++-------------------- params/hooks_libevm.go | 3 +- plugin/evm/block.go | 6 ++-- plugin/evm/header/extra.go | 26 +++++++++++++++++ plugin/evm/header/extra_test.go | 37 ++++++++++++++++++++++++ plugin/evm/vm_warp_test.go | 4 +-- predicate/predicate_bytes.go | 13 --------- predicate/predicate_bytes_test.go | 14 --------- 8 files changed, 86 insertions(+), 64 deletions(-) diff --git a/core/evm.go b/core/evm.go index 8630775370..17a75f199b 100644 --- a/core/evm.go +++ b/core/evm.go @@ -27,6 +27,7 @@ package core import ( + "bytes" "math/big" "github.com/ava-labs/coreth/consensus" @@ -35,11 +36,10 @@ import ( "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/predicate" + customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/libevm/common" ethtypes "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" - "github.com/ava-labs/libevm/log" "github.com/holiman/uint256" ) @@ -103,33 +103,6 @@ type ChainContext interface { // NewEVMBlockContext creates a new context for use in the EVM. func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext { - predicateBytes := predicate.GetPredicateResultBytes(header.Extra) - if len(predicateBytes) == 0 { - return newEVMBlockContext(header, chain, author, nil) - } - // Prior to Durango, the VM enforces the extra data is smaller than or - // equal to this size. After Durango, the VM pre-verifies the extra - // data past the dynamic fee rollup window is valid. - _, err := predicate.ParseResults(predicateBytes) - if err != nil { - log.Error("failed to parse predicate results creating new block context", "err", err, "extra", header.Extra) - // As mentioned above, we pre-verify the extra data to ensure this never happens. - // If we hit an error, construct a new block context rather than use a potentially half initialized value - // as defense in depth. - return newEVMBlockContext(header, chain, author, nil) - } - return newEVMBlockContext(header, chain, author, header.Extra) -} - -// NewEVMBlockContextWithPredicateResults creates a new context for use in the EVM with an override for the predicate results that is not present -// in header.Extra. -// This function is used to create a BlockContext when the header Extra data is not fully formed yet and it's more efficient to pass in predicateResults -// directly rather than re-encode the latest results when executing each individaul transaction. -func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateResults []byte) vm.BlockContext { - return newEVMBlockContext(header, chain, author, predicateResults) -} - -func newEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, extra []byte) vm.BlockContext { var ( beneficiary common.Address baseFee *big.Int @@ -163,11 +136,25 @@ func newEVMBlockContext(header *types.Header, chain ChainContext, author *common Header: ðtypes.Header{ Number: new(big.Int).Set(header.Number), Time: header.Time, - Extra: extra, + Extra: header.Extra, }, } } +// NewEVMBlockContextWithPredicateResults creates a new context for use in the +// EVM with an override for the predicate results. The miner uses this to pass +// predicate results to the EVM when header.Extra is not fully formed yet. +func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateResults []byte) vm.BlockContext { + blockCtx := NewEVMBlockContext(header, chain, author) + // Note this only sets the block context, which is the hand-off point for + // the EVM. The actual header is not modified. + blockCtx.Header.Extra = customheader.SetPredicateBytesInExtra( + bytes.Clone(header.Extra), + predicateResults, + ) + return blockCtx +} + // NewEVMTxContext creates a new transaction context for a single transaction. func NewEVMTxContext(msg *Message) vm.TxContext { ctx := vm.TxContext{ diff --git a/params/hooks_libevm.go b/params/hooks_libevm.go index 8df5c9c5d0..690476c243 100644 --- a/params/hooks_libevm.go +++ b/params/hooks_libevm.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/coreth/nativeasset" "github.com/ava-labs/coreth/params/extras" + customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/precompile/contract" "github.com/ava-labs/coreth/precompile/modules" "github.com/ava-labs/coreth/precompile/precompileconfig" @@ -109,7 +110,7 @@ func makePrecompile(contract contract.StatefulPrecompiledContract) libevm.Precom panic(err) // Should never happen } var predicateResults *predicate.Results - if predicateResultsBytes := predicate.GetPredicateResultBytes(header.Extra); len(predicateResultsBytes) > 0 { + if predicateResultsBytes := customheader.PredicateBytesFromExtra(header.Extra); len(predicateResultsBytes) > 0 { predicateResults, err = predicate.ParseResults(predicateResultsBytes) if err != nil { panic(err) // Should never happen, as results are already validated in block validation diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 766167e21f..37418427f2 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/atomic" + "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/predicate" @@ -384,10 +385,7 @@ func (b *Block) verifyPredicates(predicateContext *precompileconfig.PredicateCon return fmt.Errorf("failed to marshal predicate results: %w", err) } extraData := b.ethBlock.Extra() - headerPredicateResultsBytes := predicate.GetPredicateResultBytes(extraData) - if len(headerPredicateResultsBytes) == 0 { - return fmt.Errorf("failed to find predicate results in extra data: %x", extraData) - } + headerPredicateResultsBytes := header.PredicateBytesFromExtra(extraData) if !bytes.Equal(headerPredicateResultsBytes, predicateResultsBytes) { return fmt.Errorf("%w (remote: %x local: %x)", errInvalidHeaderPredicateResults, headerPredicateResultsBytes, predicateResultsBytes) } diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index 531b0428fb..7c6e3c71d0 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -82,3 +82,29 @@ func VerifyExtra(rules extras.AvalancheRules, extra []byte) error { } return nil } + +// PredicateBytesFromExtra returns the predicate result bytes from the header's +// extra data. If the extra data is not long enough, an empty slice is returned. +func PredicateBytesFromExtra(extra []byte) []byte { + // Prior to Durango, the VM enforces the extra data is smaller than or equal + // to this size. + // After Durango, the VM pre-verifies the extra data past the dynamic fee + // rollup window is valid. + if len(extra) <= FeeWindowSize { + return nil + } + return extra[FeeWindowSize:] +} + +// SetPredicateBytesInExtra sets the predicate result bytes in the header's extra +// data. If the extra data is not long enough (i.e., an incomplete header.Extra +// as built in the miner), it is padded with zeros. +func SetPredicateBytesInExtra(extra []byte, predicateBytes []byte) []byte { + if len(extra) < FeeWindowSize { + // pad extra with zeros + extra = append(extra, make([]byte, FeeWindowSize-len(extra))...) + } + extra = extra[:FeeWindowSize] // truncate extra to FeeWindowSize + extra = append(extra, predicateBytes...) + return extra +} diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index 6977a78842..b5440ac3fb 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -327,3 +327,40 @@ func TestVerifyExtra(t *testing.T) { }) } } + +func TestPredicateBytesFromExtra(t *testing.T) { + tests := []struct { + name string + extra []byte + expected []byte + }{ + { + name: "empty_extra", + extra: nil, + expected: nil, + }, + { + name: "too_short", + extra: make([]byte, FeeWindowSize-1), + expected: nil, + }, + { + name: "empty_predicate", + extra: make([]byte, FeeWindowSize), + expected: nil, + }, + { + name: "non_empty_predicate", + extra: []byte{ + FeeWindowSize: 5, + }, + expected: []byte{5}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := PredicateBytesFromExtra(test.extra) + require.Equal(t, test.expected, got) + }) + } +} diff --git a/plugin/evm/vm_warp_test.go b/plugin/evm/vm_warp_test.go index 2f2e378a16..31c4bbce9b 100644 --- a/plugin/evm/vm_warp_test.go +++ b/plugin/evm/vm_warp_test.go @@ -31,6 +31,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth/tracers" "github.com/ava-labs/coreth/params/extras" + customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/precompile/contract" @@ -652,8 +653,7 @@ func testReceiveWarpMessage( // Require the block was built with a successful predicate result ethBlock := block2.(*chain.BlockWrapper).Block.(*Block).ethBlock - headerPredicateResultsBytes := predicate.GetPredicateResultBytes(ethBlock.Extra()) - require.NotEmpty(headerPredicateResultsBytes) + headerPredicateResultsBytes := customheader.PredicateBytesFromExtra(ethBlock.Extra()) results, err := predicate.ParseResults(headerPredicateResultsBytes) require.NoError(err) diff --git a/predicate/predicate_bytes.go b/predicate/predicate_bytes.go index 3f235143c6..f1baa1a610 100644 --- a/predicate/predicate_bytes.go +++ b/predicate/predicate_bytes.go @@ -53,16 +53,3 @@ func UnpackPredicate(paddedPredicate []byte) ([]byte, error) { return trimmedPredicateBytes[:len(trimmedPredicateBytes)-1], nil } - -// GetPredicateResultBytes returns the predicate result bytes from extraData. If -// extraData is too short to include predicate results, it returns nil. -func GetPredicateResultBytes(extraData []byte) []byte { - // Prior to Durango, the VM enforces the extra data is smaller than or equal - // to this size. - if len(extraData) <= HeaderFeeWindowSize { - return nil - } - // After Durango, the extra data past the dynamic fee rollup window represents - // predicate results. - return extraData[HeaderFeeWindowSize:] -} diff --git a/predicate/predicate_bytes_test.go b/predicate/predicate_bytes_test.go index e680bd07d9..9742ed2858 100644 --- a/predicate/predicate_bytes_test.go +++ b/predicate/predicate_bytes_test.go @@ -48,17 +48,3 @@ func TestUnpackInvalidPredicate(t *testing.T) { } } } - -func TestPredicateResultsBytes(t *testing.T) { - require := require.New(t) - dataTooShort := utils.RandomBytes(HeaderFeeWindowSize - 1) - resultBytes := GetPredicateResultBytes(dataTooShort) - require.Empty(resultBytes) - - preDurangoData := utils.RandomBytes(HeaderFeeWindowSize) - resultBytes = GetPredicateResultBytes(preDurangoData) - require.Empty(resultBytes) - postDurangoData := utils.RandomBytes(HeaderFeeWindowSize + 2) - resultBytes = GetPredicateResultBytes(postDurangoData) - require.Equal(resultBytes, postDurangoData[HeaderFeeWindowSize:]) -} From 6590b6d16fc7d4a0b1aae30150338a9cb9e7ba8a Mon Sep 17 00:00:00 2001 From: Darioush Jalali Date: Thu, 27 Feb 2025 16:46:48 -0800 Subject: [PATCH 5/5] review comments --- core/block_validator.go | 10 +++++----- plugin/evm/header/extra.go | 11 +++-------- plugin/evm/header/extra_test.go | 5 +++-- plugin/evm/header/gas_limit.go | 15 +++++---------- plugin/evm/header/gas_limit_test.go | 13 +++++++------ plugin/evm/upgrade/ap0/params.go | 8 ++++++++ 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/core/block_validator.go b/core/block_validator.go index f7d026e400..8547570848 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -34,7 +34,7 @@ import ( "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/libevm/trie" ) @@ -148,10 +148,10 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD // the gas allowance. func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint64 { // contrib = (parentGasUsed * 3 / 2) / 1024 - contrib := (parentGasUsed + parentGasUsed/2) / header.GasLimitBoundDivisor + contrib := (parentGasUsed + parentGasUsed/2) / ap0.GasLimitBoundDivisor // decay = parentGasLimit / 1024 -1 - decay := parentGasLimit/header.GasLimitBoundDivisor - 1 + decay := parentGasLimit/ap0.GasLimitBoundDivisor - 1 /* strategy: gasLimit of block-to-mine is set based on parent's @@ -161,8 +161,8 @@ func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint6 from parentGasLimit * (2/3) parentGasUsed is. */ limit := parentGasLimit - decay + contrib - if limit < header.MinGasLimit { - limit = header.MinGasLimit + if limit < ap0.MinGasLimit { + limit = ap0.MinGasLimit } // If we're outside our allowed gas range, we try to hone towards them if limit < gasFloor { diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index 7c6e3c71d0..4206e9ae27 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -9,12 +9,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params/extras" -) - -const ( - // Note: MaximumExtraDataSize has been reduced to 32 in Geth, but is kept the same in Coreth for - // backwards compatibility. - MaximumExtraDataSize uint64 = 64 // Maximum size extra data may be after Genesis. + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" ) var errInvalidExtraLength = errors.New("invalid header.Extra length") @@ -71,11 +66,11 @@ func VerifyExtra(rules extras.AvalancheRules, extra []byte) error { ) } default: - if uint64(extraLen) > MaximumExtraDataSize { + if uint64(extraLen) > ap0.MaximumExtraDataSize { return fmt.Errorf( "%w: expected <= %d but got %d", errInvalidExtraLength, - MaximumExtraDataSize, + ap0.MaximumExtraDataSize, extraLen, ) } diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index b5440ac3fb..1ba5bba91f 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" @@ -246,13 +247,13 @@ func TestVerifyExtra(t *testing.T) { { name: "initial_valid", rules: extras.AvalancheRules{}, - extra: make([]byte, MaximumExtraDataSize), + extra: make([]byte, ap0.MaximumExtraDataSize), expected: nil, }, { name: "initial_invalid", rules: extras.AvalancheRules{}, - extra: make([]byte, MaximumExtraDataSize+1), + extra: make([]byte, ap0.MaximumExtraDataSize+1), expected: errInvalidExtraLength, }, { diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index e9b28c76b3..42570caf97 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -10,16 +10,11 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" ) -const ( - MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. - MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). - GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. -) - var errInvalidGasLimit = errors.New("invalid gas limit") // GasLimit takes the previous header and the timestamp of its child block and @@ -69,18 +64,18 @@ func VerifyGasLimit( ) } default: - if header.GasLimit < MinGasLimit || header.GasLimit > MaxGasLimit { + if header.GasLimit < ap0.MinGasLimit || header.GasLimit > ap0.MaxGasLimit { return fmt.Errorf("%w: %d not in range [%d, %d]", errInvalidGasLimit, header.GasLimit, - MinGasLimit, - MaxGasLimit, + ap0.MinGasLimit, + ap0.MaxGasLimit, ) } // Verify that the gas limit remains within allowed bounds diff := math.AbsDiff(parent.GasLimit, header.GasLimit) - limit := parent.GasLimit / GasLimitBoundDivisor + limit := parent.GasLimit / ap0.GasLimitBoundDivisor if diff >= limit { return fmt.Errorf("%w: have %d, want %d += %d", errInvalidGasLimit, diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index ea2efd048b..1887ccd259 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" "github.com/stretchr/testify/require" @@ -103,10 +104,10 @@ func TestVerifyGasLimit(t *testing.T) { name: "launch_too_low", upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: MinGasLimit, + GasLimit: ap0.MinGasLimit, }, header: &types.Header{ - GasLimit: MinGasLimit - 1, + GasLimit: ap0.MinGasLimit - 1, }, want: errInvalidGasLimit, }, @@ -114,10 +115,10 @@ func TestVerifyGasLimit(t *testing.T) { name: "launch_too_high", upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: MaxGasLimit, + GasLimit: ap0.MaxGasLimit, }, header: &types.Header{ - GasLimit: MaxGasLimit + 1, + GasLimit: ap0.MaxGasLimit + 1, }, want: errInvalidGasLimit, }, @@ -125,10 +126,10 @@ func TestVerifyGasLimit(t *testing.T) { name: "change_too_large", upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: MinGasLimit, + GasLimit: ap0.MinGasLimit, }, header: &types.Header{ - GasLimit: MaxGasLimit, + GasLimit: ap0.MaxGasLimit, }, want: errInvalidGasLimit, }, diff --git a/plugin/evm/upgrade/ap0/params.go b/plugin/evm/upgrade/ap0/params.go index 48625ecade..f353bce8ec 100644 --- a/plugin/evm/upgrade/ap0/params.go +++ b/plugin/evm/upgrade/ap0/params.go @@ -19,4 +19,12 @@ const ( // // This value was replaced with the Apricot Phase 3 dynamic fee mechanism. AtomicTxFee = units.MilliAvax + + // Note: MaximumExtraDataSize has been reduced to 32 in Geth, but is kept the same in Coreth for + // backwards compatibility. + MaximumExtraDataSize = 64 // Maximum size extra data may be after Genesis. + + MinGasLimit = 5000 // Minimum the gas limit may ever be. + MaxGasLimit = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). + GasLimitBoundDivisor = 1024 // The bound divisor of the gas limit, used in update calculations. )