From 5ce5ff58d346e94cffb6ba56a1dfed2b05b0f6fa Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Wed, 20 Aug 2025 16:49:26 -0400 Subject: [PATCH 1/8] Pull in ACP-176 implementation --- consensus/dummy/consensus.go | 21 +- core/chain_makers.go | 6 +- core/evm.go | 9 +- core/state_processor.go | 3 +- core/state_processor_test.go | 17 +- eth/api_backend.go | 3 +- eth/gasestimator/gasestimator.go | 3 +- eth/gasprice/gasprice.go | 3 +- eth/gasprice/gasprice_test.go | 82 +------ eth/state_accessor.go | 4 +- eth/tracers/api.go | 40 ++-- ethclient/simulated/options_test.go | 5 +- go.mod | 2 + go.sum | 2 - internal/ethapi/api.go | 3 +- .../testdata/eth_getBlockByHash-hash-1.json | 2 +- ...h_getBlockByHash-hash-latest-1-fullTx.json | 2 +- .../eth_getBlockByHash-hash-latest.json | 2 +- .../eth_getBlockByNumber-number-1.json | 2 +- .../eth_getBlockByNumber-number-latest-1.json | 2 +- .../eth_getBlockByNumber-tag-latest.json | 2 +- ...h_getBlockReceipts-block-with-blob-tx.json | 38 +-- ...eceipts-block-with-contract-create-tx.json | 34 +-- ...ockReceipts-block-with-dynamic-fee-tx.json | 34 +-- ...ts-block-with-legacy-contract-call-tx.json | 2 +- ...eceipts-block-with-legacy-transfer-tx.json | 34 +-- .../eth_getBlockReceipts-tag-latest.json | 38 +-- .../testdata/eth_getHeaderByHash-hash-1.json | 2 +- .../eth_getHeaderByHash-hash-latest-1.json | 2 +- .../eth_getHeaderByHash-hash-latest.json | 2 +- .../eth_getHeaderByNumber-number-1.json | 2 +- ...eth_getHeaderByNumber-number-latest-1.json | 2 +- .../eth_getHeaderByNumber-tag-latest.json | 2 +- .../eth_getTransactionReceipt-blob-tx.json | 2 +- ...TransactionReceipt-create-contract-tx.json | 8 +- ...eipt-create-contract-with-access-list.json | 2 +- ...ansactionReceipt-dynamic-tx-with-logs.json | 2 +- ...TransactionReceipt-normal-transfer-tx.json | 2 +- .../eth_getTransactionReceipt-with-logs.json | 2 +- miner/worker.go | 10 +- params/hooks_libevm.go | 3 +- plugin/evm/block.go | 3 +- plugin/evm/config/config.go | 6 + plugin/evm/header/base_fee.go | 9 + plugin/evm/header/base_fee_test.go | 70 ++++++ plugin/evm/header/dynamic_fee_state.go | 74 ++++++ plugin/evm/header/extra.go | 63 ++++- plugin/evm/header/extra_test.go | 222 +++++++++++++++++- plugin/evm/header/gas_limit.go | 42 +++- plugin/evm/header/gas_limit_test.go | 146 +++++++++++- plugin/evm/vm.go | 26 +- plugin/evm/vm_warp_test.go | 3 +- 52 files changed, 840 insertions(+), 262 deletions(-) create mode 100644 plugin/evm/header/dynamic_fee_state.go diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index e403c879c8..9e7bcad25b 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -10,6 +10,7 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/timer/mockable" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/state" "github.com/ava-labs/libevm/core/types" @@ -42,18 +43,21 @@ type Mode struct { type ( DummyEngine struct { - clock *mockable.Clock - consensusMode Mode + clock *mockable.Clock + consensusMode Mode + desiredTargetExcess *gas.Gas } ) func NewDummyEngine( mode Mode, clock *mockable.Clock, + desiredTargetExcess *gas.Gas, ) *DummyEngine { return &DummyEngine{ - clock: clock, - consensusMode: mode, + clock: clock, + consensusMode: mode, + desiredTargetExcess: desiredTargetExcess, } } @@ -127,7 +131,12 @@ func (eng *DummyEngine) verifyCoinbase(header *types.Header, parent *types.Heade return nil } -func verifyHeaderGasFields(config *extras.ChainConfig, header *types.Header, parent *types.Header, chain consensus.ChainHeaderReader) error { +func verifyHeaderGasFields( + config *extras.ChainConfig, + header *types.Header, + parent *types.Header, + chain consensus.ChainHeaderReader, +) error { // We verify the current block by checking the parent fee config // this is because the current block cannot set the fee config for itself // Fee config might depend on the state when precompile is activated @@ -395,7 +404,7 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h } // finalize the header.Extra - extraPrefix, err := customheader.ExtraPrefix(config, parent, header) + extraPrefix, err := customheader.ExtraPrefix(config, parent, header, eng.desiredTargetExcess) if err != nil { return nil, fmt.Errorf("failed to calculate new header.Extra: %w", err) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 130218ca61..af51b32a8b 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -110,8 +110,9 @@ func (b *BlockGen) Difficulty() *big.Int { // block. func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { b.header.ParentBeaconRoot = &root + rulesExtra := params.GetRulesExtra(b.cm.config.Rules(b.header.Number, params.IsMergeTODO, b.header.Time)) var ( - blockContext = NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) + blockContext = NewEVMBlockContext(rulesExtra.AvalancheRules, b.header, b.cm, &b.header.Coinbase) vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.cm.config, vm.Config{}) ) ProcessBeaconBlockRoot(root, vmenv, b.statedb) @@ -129,7 +130,8 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti b.SetCoinbase(common.Address{}) } b.statedb.SetTxContext(tx.Hash(), len(b.txs)) - blockContext := NewEVMBlockContext(b.header, bc, &b.header.Coinbase) + rulesExtra := params.GetRulesExtra(b.cm.config.Rules(b.header.Number, params.IsMergeTODO, b.header.Time)) + blockContext := NewEVMBlockContext(rulesExtra.AvalancheRules, b.header, bc, &b.header.Coinbase) receipt, err := ApplyTransaction(b.cm.config, bc, blockContext, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig) if err != nil { panic(err) diff --git a/core/evm.go b/core/evm.go index fecb5ff9a1..e6660cdf05 100644 --- a/core/evm.go +++ b/core/evm.go @@ -40,6 +40,7 @@ import ( "github.com/ava-labs/subnet-evm/consensus/misc/eip4844" "github.com/ava-labs/subnet-evm/core/extstate" "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/params/extras" customheader "github.com/ava-labs/subnet-evm/plugin/evm/header" "github.com/ava-labs/subnet-evm/predicate" "github.com/holiman/uint256" @@ -92,8 +93,8 @@ 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 := customheader.PredicateBytesFromExtra(header.Extra) +func NewEVMBlockContext(rules extras.AvalancheRules, header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext { + predicateBytes := customheader.PredicateBytesFromExtra(rules, header.Extra) if len(predicateBytes) == 0 { return newEVMBlockContext(header, chain, author, nil) } @@ -115,8 +116,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 individual transaction. -func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateBytes []byte) vm.BlockContext { - blockCtx := NewEVMBlockContext(header, chain, author) +func NewEVMBlockContextWithPredicateResults(rules extras.AvalancheRules, header *types.Header, chain ChainContext, author *common.Address, predicateBytes []byte) vm.BlockContext { + blockCtx := NewEVMBlockContext(rules, 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( diff --git a/core/state_processor.go b/core/state_processor.go index 88c8d5b594..347a609f4f 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -87,8 +87,9 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state return nil, nil, 0, err } + rulesExtra := params.GetRulesExtra(p.config.Rules(blockNumber, params.IsMergeTODO, block.Time())) var ( - context = NewEVMBlockContext(header, p.bc, nil) + context = NewEVMBlockContext(rulesExtra.AvalancheRules, header, p.bc, nil) vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) signer = types.MakeSigner(p.config, header.Number, header.Time) ) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index e201e327e3..f7cc0f16c6 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -33,6 +33,7 @@ import ( "testing" "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/core/types" @@ -154,9 +155,10 @@ func TestStateProcessorErrors(t *testing.T) { }, { // ErrGasLimitReached txs: []*types.Transaction{ - makeTx(key1, 0, common.Address{}, big.NewInt(0), 15000001, big.NewInt(225000000000), nil), + // This test was modified to account for ACP-176 gas limits + makeTx(key1, 0, common.Address{}, big.NewInt(0), acp176.MinMaxCapacity+1, big.NewInt(acp176.MinGasPrice), nil), }, - want: "could not apply tx 0 [0x1354370681d2ab68247073d889736f8be4a8d87e35956f0c02658d3670803a66]: gas limit reached", + want: "could not apply tx 0 [0x6c95e59678246e8b44a1d9382a9cc6589684298b32b7aaf640e8b6fc75ce3dfc]: gas limit reached", }, { // ErrInsufficientFundsForTransfer txs: []*types.Transaction{ @@ -182,15 +184,16 @@ func TestStateProcessorErrors(t *testing.T) { }, { // ErrGasLimitReached txs: []*types.Transaction{ - makeTx(key1, 0, common.Address{}, big.NewInt(0), ethparams.TxGas*762, big.NewInt(225000000000), nil), + // This test was modified to account for ACP-176 gas limits + makeTx(key1, 0, common.Address{}, big.NewInt(0), ethparams.TxGas*953, big.NewInt(acp176.MinGasPrice), nil), }, - want: "could not apply tx 0 [0x76c07cc2b32007eb1a9c3fa066d579a3d77ec4ecb79bbc266624a601d7b08e46]: gas limit reached", + want: "could not apply tx 0 [0xcd46718c1af6fd074deb6b036d34c1cb499517bf90d93df74dcfaba25fdf34af]: gas limit reached", }, { // ErrFeeCapTooLow txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, ethparams.TxGas, big.NewInt(0), big.NewInt(0)), }, - want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 0, baseFee: 225000000000", + want: "could not apply tx 0 [0xc4ab868fef0c82ae0387b742aee87907f2d0fc528fc6ea0a021459fb0fc4a4a8]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 0, baseFee: 1", }, { // ErrTipVeryHigh txs: []*types.Transaction{ @@ -243,7 +246,7 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkBlobTx(0, common.Address{}, ethparams.TxGas, big.NewInt(1), big.NewInt(1), big.NewInt(0), []common.Hash{(common.Hash{1})}), }, - want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1, baseFee: 225000000000", + want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per blob gas less than block blob gas fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7 blobGasFeeCap: 0, blobBaseFee: 1", }, } { block := GenerateBadBlock(gspec.ToBlock(), dummy.NewCoinbaseFaker(), tt.txs, gspec.Config) @@ -402,7 +405,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr cumulativeGas += tx.Gas() nBlobs += len(tx.BlobHashes()) } - header.Extra, _ = customheader.ExtraPrefix(configExtra, parent.Header(), header) + header.Extra, _ = customheader.ExtraPrefix(configExtra, parent.Header(), header, nil) header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { var pExcess, pUsed = uint64(0), uint64(0) diff --git a/eth/api_backend.go b/eth/api_backend.go index 9bcf716d21..fdf5c64bfa 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -313,7 +313,8 @@ func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *st if blockCtx != nil { context = *blockCtx } else { - context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil) + rulesExtra := params.GetRulesExtra(b.ChainConfig().Rules(header.Number, params.IsMergeTODO, header.Time)) + context = core.NewEVMBlockContext(rulesExtra.AvalancheRules, header, b.eth.BlockChain(), nil) } return vm.NewEVM(context, txContext, state, b.ChainConfig(), *vmConfig) } diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index 9ff4b8e4c6..581eba12f7 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -218,9 +218,10 @@ func execute(ctx context.Context, call *core.Message, opts *Options, gasLimit ui // call invocation. func run(ctx context.Context, call *core.Message, opts *Options) (*core.ExecutionResult, error) { // Assemble the call and the call context + rulesExtra := params.GetRulesExtra(opts.Config.Rules(opts.Header.Number, params.IsMergeTODO, opts.Header.Time)) var ( msgContext = core.NewEVMTxContext(call) - evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil) + evmContext = core.NewEVMBlockContext(rulesExtra.AvalancheRules, opts.Header, opts.Chain, nil) dirtyState = opts.State.Copy() evm = vm.NewEVM(evmContext, msgContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true}) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index f57c8becab..231968f21b 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -33,6 +33,7 @@ import ( "sync" "github.com/ava-labs/avalanchego/utils/timer/mockable" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/common/lru" "github.com/ava-labs/libevm/core/types" @@ -68,7 +69,7 @@ var ( DefaultMaxPrice = big.NewInt(150 * params.GWei) DefaultMinPrice = big.NewInt(0 * params.GWei) DefaultMinBaseFee = big.NewInt(legacy.BaseFee) - DefaultMinGasUsed = big.NewInt(6_000_000) // block gas limit is 8,000,000 + DefaultMinGasUsed = big.NewInt(acp176.MinTargetPerSecond) DefaultMaxLookbackSeconds = uint64(80) ) diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 05316e7f50..34e93c03c8 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -44,12 +44,9 @@ import ( "github.com/ava-labs/subnet-evm/consensus/dummy" "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/params/extras" customheader "github.com/ava-labs/subnet-evm/plugin/evm/header" "github.com/ava-labs/subnet-evm/plugin/evm/upgrade/legacy" - "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" "github.com/ava-labs/subnet-evm/rpc" - "github.com/ava-labs/subnet-evm/utils" "github.com/stretchr/testify/require" ) @@ -292,7 +289,7 @@ func TestSuggestTipCapSmallTips(t *testing.T) { signer := types.LatestSigner(params.TestChainConfig) baseFee := b.BaseFee() feeCap := new(big.Int).Add(baseFee, tip) - for j := 0; j < 185; j++ { + for j := 0; j < 40; j++ { tx := types.NewTx(&types.DynamicFeeTx{ ChainID: params.TestChainConfig.ChainID, Nonce: b.TxNonce(addr), @@ -383,72 +380,19 @@ func TestSuggestTipCapMaxBlocksSecondsLookback(t *testing.T) { applyGasPriceTest(t, suggestTipCapTest{ chainConfig: params.TestChainConfig, numBlocks: 20, - genBlock: testGenBlock(t, 550, 370), - expectedTip: big.NewInt(10_384_877_852), + genBlock: testGenBlock(t, 550, 80), + expectedTip: big.NewInt(1), }, timeCrunchOracleConfig()) } -// Regression test to ensure the last estimation of base fee is not used -// for the block immediately following a fee configuration update. -func TestSuggestGasPriceAfterFeeConfigUpdate(t *testing.T) { - require := require.New(t) - config := Config{ - Blocks: 20, - Percentile: 60, - } - - // create a chain config with fee manager enabled at genesis with [addr] as the admin - chainConfig := params.Copy(params.TestChainConfig) - chainConfigExtra := params.GetExtra(&chainConfig) - chainConfigExtra.GenesisPrecompiles = extras.Precompiles{ - feemanager.ConfigKey: feemanager.NewConfig(utils.NewUint64(0), []common.Address{addr}, nil, nil, nil), - } - - // create a fee config with higher MinBaseFee and prepare it for inclusion in a tx - signer := types.LatestSigner(params.TestChainConfig) - highFeeConfig := chainConfigExtra.FeeConfig - highFeeConfig.MinBaseFee = big.NewInt(28_000_000_000) - data, err := feemanager.PackSetFeeConfig(highFeeConfig) - require.NoError(err) - - // before issuing the block changing the fee into the chain, the fee estimation should - // follow the fee config in genesis. - backend := newTestBackend(t, &chainConfig, 0, func(i int, b *core.BlockGen) {}) - defer backend.teardown() - oracle, err := NewOracle(backend, config) - require.NoError(err) - got, err := oracle.SuggestPrice(context.Background()) - require.NoError(err) - require.Equal(chainConfigExtra.FeeConfig.MinBaseFee, got) - - // issue the block with tx that changes the fee - genesis := backend.chain.Genesis() - engine := backend.chain.Engine() - db := rawdb.NewDatabase(backend.chain.StateCache().DiskDB()) - blocks, _, err := core.GenerateChain(&chainConfig, genesis, engine, db, 1, 0, func(i int, b *core.BlockGen) { - b.SetCoinbase(common.Address{1}) - - // admin issues tx to change fee config to higher MinBaseFee - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: chainConfig.ChainID, - Nonce: b.TxNonce(addr), - To: &feemanager.ContractAddress, - Gas: chainConfigExtra.FeeConfig.GasLimit.Uint64(), - Value: common.Big0, - GasFeeCap: chainConfigExtra.FeeConfig.MinBaseFee, // give low fee, it should work since we still haven't applied high fees - GasTipCap: common.Big0, - Data: data, - }) - tx, err = types.SignTx(tx, signer, key) - require.NoError(err, "failed to create tx") - b.AddTx(tx) - }) - require.NoError(err) - _, err = backend.chain.InsertChain(blocks) - require.NoError(err) - - // verify the suggested price follows the new fee config. - got, err = oracle.SuggestPrice(context.Background()) - require.NoError(err) - require.Equal(highFeeConfig.MinBaseFee, got) +func TestSuggestTipCapIncludesExtraDataGas(t *testing.T) { + applyGasPriceTest(t, suggestTipCapTest{ + chainConfig: params.TestChainConfig, + numBlocks: 1000, + // The tip on the transaction is very large to pay the block gas cost. + genBlock: testGenBlock(t, 100_000, 1), + // The actual tip doesn't matter, we just want to ensure that the tip is + // non-zero when almost all the gas is coming from the extDataGasUsage. + expectedTip: big.NewInt(44_252), + }, defaultOracleConfig()) } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index f4c290cf32..5ed69f4408 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -44,6 +44,7 @@ import ( "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/core/extstate" "github.com/ava-labs/subnet-evm/eth/tracers" + "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/plugin/evm/customrawdb" ) @@ -261,7 +262,8 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil) + rulesExtra := params.GetRulesExtra(eth.blockchain.Config().Rules(block.Number(), params.IsMergeTODO, block.Time())) + context := core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), eth.blockchain, nil) if idx == txIndex { return msg, context, statedb, release, nil } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 30e50f769e..01f58faf66 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -298,8 +298,9 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed // Fetch and execute the block trace taskCh for task := range taskCh { var ( - signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time()) - blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil) + rulesExtra = params.GetRulesExtra(api.backend.ChainConfig().Rules(task.block.Number(), params.IsMergeTODO, task.block.Time())) + signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time()) + blockCtx = core.NewEVMBlockContext(rulesExtra.AvalancheRules, task.block.Header(), api.chainContext(ctx), nil) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { @@ -562,7 +563,8 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config roots []common.Hash signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) chainConfig = api.backend.ChainConfig() - vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + rulesExtra = params.GetRulesExtra(chainConfig.Rules(block.Number(), params.IsMergeTODO, block.Time())) + vmctx = core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), api.chainContext(ctx), nil) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) ) for i, tx := range block.Transactions() { @@ -645,12 +647,13 @@ func (api *baseAPI) traceBlock(ctx context.Context, block *types.Block, config * } // Native tracers have low overhead var ( - txs = block.Transactions() - blockHash = block.Hash() - is158 = api.backend.ChainConfig().IsEIP158(block.Number()) - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) - signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) - results = make([]*txTraceResult, len(txs)) + txs = block.Transactions() + blockHash = block.Hash() + is158 = api.backend.ChainConfig().IsEIP158(block.Number()) + rulesExtra = params.GetRulesExtra(api.backend.ChainConfig().Rules(block.Number(), params.IsMergeTODO, block.Time())) + blockCtx = core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), api.chainContext(ctx), nil) + signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) + results = make([]*txTraceResult, len(txs)) ) for i, tx := range txs { // Generate the next state snapshot fast without tracing @@ -679,12 +682,13 @@ func (api *baseAPI) traceBlock(ctx context.Context, block *types.Block, config * func (api *baseAPI) traceBlockParallel(ctx context.Context, block *types.Block, statedb *state.StateDB, config *TraceConfig) ([]*txTraceResult, error) { // Execute all the transaction contained within the block concurrently var ( - txs = block.Transactions() - blockHash = block.Hash() - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) - signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) - results = make([]*txTraceResult, len(txs)) - pend sync.WaitGroup + txs = block.Transactions() + blockHash = block.Hash() + rulesExtra = params.GetRulesExtra(api.backend.ChainConfig().Rules(block.Number(), params.IsMergeTODO, block.Time())) + blockCtx = core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), api.chainContext(ctx), nil) + signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) + results = make([]*txTraceResult, len(txs)) + pend sync.WaitGroup ) threads := runtime.NumCPU() if threads > len(txs) { @@ -793,7 +797,8 @@ func (api *FileTracerAPI) standardTraceBlockToFile(ctx context.Context, block *t dumps []string signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) chainConfig = api.backend.ChainConfig() - vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + rulesExtra = params.GetRulesExtra(chainConfig.Rules(block.Number(), params.IsMergeTODO, block.Time())) + vmctx = core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), api.chainContext(ctx), nil) canon = true ) // Check if there are any overrides: the caller may wish to enable a future @@ -959,7 +964,8 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc } defer release() - vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + rulesExtra := params.GetRulesExtra(api.backend.ChainConfig().Rules(block.Number(), params.IsMergeTODO, block.Time())) + vmctx := core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), api.chainContext(ctx), nil) // Apply the customization rules if required. if config != nil { diff --git a/ethclient/simulated/options_test.go b/ethclient/simulated/options_test.go index fc5b6cfcee..14d9b35b66 100644 --- a/ethclient/simulated/options_test.go +++ b/ethclient/simulated/options_test.go @@ -33,6 +33,7 @@ import ( "strings" "testing" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" ethereum "github.com/ava-labs/libevm" "github.com/ava-labs/libevm/core/types" ethparams "github.com/ava-labs/libevm/params" @@ -60,8 +61,8 @@ func TestWithBlockGasLimitOption(t *testing.T) { if err != nil { t.Fatalf("failed to retrieve head block: %v", err) } - if head.GasLimit() != 12_345_678 { - t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), 12_345_678) + if head.GasLimit() != acp176.MinMaxCapacity { + t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), acp176.MinMaxCapacity) } } diff --git a/go.mod b/go.mod index 6452f6a475..a12f187076 100644 --- a/go.mod +++ b/go.mod @@ -177,3 +177,5 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace github.com/ava-labs/avalanchego => ../avalanchego diff --git a/go.sum b/go.sum index f8d76b4c3e..decb654835 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/avalanchego v1.13.4 h1:H7bI1qx9qaOddJ3E2J9KkLvTe7d613K821eST6VGXEU= -github.com/ava-labs/avalanchego v1.13.4/go.mod h1:pMPIH9KeyXFsdxuF6sy06sztq3p2rI4XeePXvGeg9Ew= github.com/ava-labs/coreth v0.15.3-rc.5 h1:zGk1LaFeZOEkA6uPF1g9BNCjbZOrONx9fm5WtiH5NWg= github.com/ava-labs/coreth v0.15.3-rc.5/go.mod h1:sEqzSu2f4FJEGFL7CP3zNOQtQ0MupWJdzTp7W65EDf8= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.9 h1:zw0g+cUbZDsGdWx1PKmBChkpy+ixL3QgiI86DUOuXvo= diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index faaaa699e7..d536bfe71a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1095,7 +1095,8 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S defer cancel() // Get a new instance of the EVM. - blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + rulesExtra := params.GetRulesExtra(b.ChainConfig().Rules(header.Number, params.IsMergeTODO, header.Time)) + blockCtx := core.NewEVMBlockContext(rulesExtra.AvalancheRules, header, NewChainContext(ctx, b), nil) if blockOverrides != nil { blockOverrides.Apply(&blockCtx) } diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json index 3835567741..1d30a13f1c 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json @@ -23,4 +23,4 @@ ], "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json index 8f55c154c0..d173d474ee 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json @@ -39,4 +39,4 @@ ], "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json index 02d29dd90b..0e8e038251 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json @@ -23,4 +23,4 @@ ], "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json index 3835567741..1d30a13f1c 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json @@ -23,4 +23,4 @@ ], "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json index 8f55c154c0..d173d474ee 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json @@ -39,4 +39,4 @@ ], "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json index 02d29dd90b..0e8e038251 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json @@ -23,4 +23,4 @@ ], "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json index 24afbebc14..12ca695538 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json @@ -1,20 +1,20 @@ [ - { - "blobGasPrice": "0x1", - "blobGasUsed": "0x20000", - "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", - "blockNumber": "0x6", - "contractAddress": null, - "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba01", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x5208", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", - "transactionIndex": "0x0", - "type": "0x3" - } -] \ No newline at end of file + { + "blobGasPrice": "0x1", + "blobGasUsed": "0x20000", + "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", + "blockNumber": "0x6", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x5d21dba01", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", + "transactionIndex": "0x0", + "type": "0x3" + } +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json index 84f48f0ea5..b843dacf9d 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json @@ -1,18 +1,18 @@ [ - { - "blockHash": "0xdcba2f7c99ad0f58002737f1393578f1b72aca3270c1722d9d0fbdc2439b0484", - "blockNumber": "0x2", - "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", - "cumulativeGasUsed": "0xcf50", - "effectiveGasPrice": "0x5d21dba00", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0xcf50", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": null, - "transactionHash": "0x22aa617165f83a9f8c191c2b7724ae43eeb1249bee06c98c03c7624c21d27dc8", - "transactionIndex": "0x0", - "type": "0x0" - } -] \ No newline at end of file + { + "blockHash": "0xdcba2f7c99ad0f58002737f1393578f1b72aca3270c1722d9d0fbdc2439b0484", + "blockNumber": "0x2", + "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", + "cumulativeGasUsed": "0xcf50", + "effectiveGasPrice": "0x5d21dba00", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0xcf50", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": null, + "transactionHash": "0x22aa617165f83a9f8c191c2b7724ae43eeb1249bee06c98c03c7624c21d27dc8", + "transactionIndex": "0x0", + "type": "0x0" + } +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json index 977cbe81df..ad294280cc 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json @@ -1,18 +1,18 @@ [ - { - "blockHash": "0xfa29fee1c5195fda47b23d3ce5259e314eb7578d18b76b36068d0e321db024e1", - "blockNumber": "0x4", - "contractAddress": null, - "cumulativeGasUsed": "0x538d", - "effectiveGasPrice": "0x5d21dbbf4", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x538d", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x0", - "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x4e1e9194ca6f9d4e1736e9e441f66104f273548ed6d91b236a5f9c2ea10fa06d", - "transactionIndex": "0x0", - "type": "0x2" - } -] \ No newline at end of file + { + "blockHash": "0xfa29fee1c5195fda47b23d3ce5259e314eb7578d18b76b36068d0e321db024e1", + "blockNumber": "0x4", + "contractAddress": null, + "cumulativeGasUsed": "0x538d", + "effectiveGasPrice": "0x5d21dbbf4", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x538d", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x0", + "to": "0x0000000000000000000000000000000000031ec7", + "transactionHash": "0x4e1e9194ca6f9d4e1736e9e441f66104f273548ed6d91b236a5f9c2ea10fa06d", + "transactionIndex": "0x0", + "type": "0x2" + } +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json index 78bec365a3..c60bf1cec1 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json @@ -31,4 +31,4 @@ "transactionIndex": "0x0", "type": "0x0" } -] \ No newline at end of file +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json index e4c599bf22..81d857254e 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json @@ -1,18 +1,18 @@ [ - { - "blockHash": "0xf9081fe79fcdfd6a743577cc42fa17bec5e6cc1ebf5807b771724bf88b454b71", - "blockNumber": "0x1", - "contractAddress": null, - "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba00", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x5208", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26", - "transactionIndex": "0x0", - "type": "0x0" - } -] \ No newline at end of file + { + "blockHash": "0xf9081fe79fcdfd6a743577cc42fa17bec5e6cc1ebf5807b771724bf88b454b71", + "blockNumber": "0x1", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x5d21dba00", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26", + "transactionIndex": "0x0", + "type": "0x0" + } +] diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json index 24afbebc14..12ca695538 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json @@ -1,20 +1,20 @@ [ - { - "blobGasPrice": "0x1", - "blobGasUsed": "0x20000", - "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", - "blockNumber": "0x6", - "contractAddress": null, - "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba01", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x5208", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", - "transactionIndex": "0x0", - "type": "0x3" - } -] \ No newline at end of file + { + "blobGasPrice": "0x1", + "blobGasUsed": "0x20000", + "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", + "blockNumber": "0x6", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x5d21dba01", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", + "transactionIndex": "0x0", + "type": "0x3" + } +] diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json index b400b4ef33..43394c3914 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json @@ -18,4 +18,4 @@ "timestamp": "0xa", "totalDifficulty": "0x1", "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json index ed8758d9a0..6882e2389e 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json @@ -18,4 +18,4 @@ "timestamp": "0x5a", "totalDifficulty": "0x9", "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json index 1ac22e8b43..5141e897aa 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json @@ -18,4 +18,4 @@ "timestamp": "0x64", "totalDifficulty": "0xa", "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json index b400b4ef33..43394c3914 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json @@ -18,4 +18,4 @@ "timestamp": "0xa", "totalDifficulty": "0x1", "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json index ed8758d9a0..6882e2389e 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json @@ -18,4 +18,4 @@ "timestamp": "0x5a", "totalDifficulty": "0x9", "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json index 1ac22e8b43..5141e897aa 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json @@ -18,4 +18,4 @@ "timestamp": "0x64", "totalDifficulty": "0xa", "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json index 674b7e4f28..84be5d1a9a 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json @@ -15,4 +15,4 @@ "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", "transactionIndex": "0x0", "type": "0x3" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json index 0345b77cef..e9e995f839 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json @@ -1,16 +1,16 @@ { - "blockHash": "0xdcba2f7c99ad0f58002737f1393578f1b72aca3270c1722d9d0fbdc2439b0484", + "blockHash": "0x08bd14928be51a5496c0bdcccfc53184052485fa3bb8fa7b74f2ce7897036a0c", "blockNumber": "0x2", "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", "cumulativeGasUsed": "0xcf50", - "effectiveGasPrice": "0x5d21dba00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0xcf50", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": null, - "transactionHash": "0x22aa617165f83a9f8c191c2b7724ae43eeb1249bee06c98c03c7624c21d27dc8", + "transactionHash": "0x3b727d5e08e2176d96ee1bea244f772b592acd2cda1acc3d822c8b7f3de362f9", "transactionIndex": "0x0", "type": "0x0" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json index 2d68a68bd9..fc633368be 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json @@ -13,4 +13,4 @@ "transactionHash": "0x8afe030574f663fe5096371d6f58a6287bfb3e0c73a5050220f5775a08e7abc9", "transactionIndex": "0x0", "type": "0x1" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json b/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json index 6b558601b2..885e9f0b3d 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json @@ -13,4 +13,4 @@ "transactionHash": "0x4e1e9194ca6f9d4e1736e9e441f66104f273548ed6d91b236a5f9c2ea10fa06d", "transactionIndex": "0x0", "type": "0x2" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json index 8411f0b255..80be7cb97e 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json @@ -13,4 +13,4 @@ "transactionHash": "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26", "transactionIndex": "0x0", "type": "0x0" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json b/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json index 6aebc6190b..3fea31ef63 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json @@ -29,4 +29,4 @@ "transactionHash": "0x7366a7738f47e32f5b6d292ca064b6b66f295d3931533a3745975be1191fccdf", "transactionIndex": "0x0", "type": "0x0" -} \ No newline at end of file +} diff --git a/miner/worker.go b/miner/worker.go index 52cb32446f..358b1ada49 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -214,7 +214,8 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte return nil, fmt.Errorf("failed to create new current environment: %w", err) } if header.ParentBeaconRoot != nil { - context := core.NewEVMBlockContext(header, w.chain, nil) + rulesExtra := params.GetRulesExtra(env.rules) + context := core.NewEVMBlockContext(rulesExtra.AvalancheRules, header, w.chain, nil) vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{}) core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state) } @@ -351,7 +352,8 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, coinb blockContext vm.BlockContext ) - if params.GetRulesExtra(env.rules).IsDurango { + rulesExtra := params.GetRulesExtra(env.rules) + if rulesExtra.IsDurango { results, err := core.CheckPredicates(env.rules, env.predicateContext, tx) if err != nil { log.Debug("Transaction predicate failed verification in miner", "tx", tx.Hash(), "err", err) @@ -363,9 +365,9 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, coinb if err != nil { return nil, fmt.Errorf("failed to marshal predicate results: %w", err) } - blockContext = core.NewEVMBlockContextWithPredicateResults(env.header, w.chain, &coinbase, predicateResultsBytes) + blockContext = core.NewEVMBlockContextWithPredicateResults(rulesExtra.AvalancheRules, env.header, w.chain, &coinbase, predicateResultsBytes) } else { - blockContext = core.NewEVMBlockContext(env.header, w.chain, &coinbase) + blockContext = core.NewEVMBlockContext(rulesExtra.AvalancheRules, env.header, w.chain, &coinbase) } receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, blockContext, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, *w.chain.GetVMConfig()) diff --git a/params/hooks_libevm.go b/params/hooks_libevm.go index 9e3e7e2a7d..0f6ec1d4e4 100644 --- a/params/hooks_libevm.go +++ b/params/hooks_libevm.go @@ -72,7 +72,8 @@ func makePrecompile(contract contract.StatefulPrecompiledContract) libevm.Precom panic(err) // Should never happen } var predicateResults *predicate.Results - if predicateResultsBytes := customheader.PredicateBytesFromExtra(header.Extra); len(predicateResultsBytes) > 0 { + rules := GetRulesExtra(env.Rules()).AvalancheRules + if predicateResultsBytes := customheader.PredicateBytesFromExtra(rules, 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 1a8dbb2d49..225adfe10d 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -256,7 +256,8 @@ func (b *Block) verifyPredicates(predicateContext *precompileconfig.PredicateCon return fmt.Errorf("failed to marshal predicate results: %w", err) } extraData := b.ethBlock.Extra() - headerPredicateResultsBytes := header.PredicateBytesFromExtra(extraData) + avalancheRules := rulesExtra.AvalancheRules + headerPredicateResultsBytes := header.PredicateBytesFromExtra(avalancheRules, extraData) if !bytes.Equal(headerPredicateResultsBytes, predicateResultsBytes) { return fmt.Errorf("%w (remote: %x local: %x)", errInvalidHeaderPredicateResults, headerPredicateResultsBytes, predicateResultsBytes) } diff --git a/plugin/evm/config/config.go b/plugin/evm/config/config.go index 5a42032f7b..ae17007a63 100644 --- a/plugin/evm/config/config.go +++ b/plugin/evm/config/config.go @@ -9,6 +9,7 @@ import ( "time" "github.com/ava-labs/avalanchego/database/pebbledb" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/common/hexutil" "github.com/spf13/cast" @@ -90,6 +91,11 @@ type Duration struct { // Config ... type Config struct { + // GasTarget is the target gas per second that this node will attempt to use + // when creating blocks. If this config is not specified, the node will + // default to use the parent block's target gas per second. + GasTarget *gas.Gas `json:"gas-target,omitempty"` + // Airdrop AirdropFile string `json:"airdrop"` diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index fd399b834d..ec54c795a7 100644 --- a/plugin/evm/header/base_fee.go +++ b/plugin/evm/header/base_fee.go @@ -5,6 +5,7 @@ package header import ( "errors" + "fmt" "math/big" "github.com/ava-labs/libevm/core/types" @@ -24,7 +25,15 @@ func BaseFee( parent *types.Header, timestamp uint64, ) (*big.Int, error) { + // TODO: XXX Handle feeConfig with Fortuna here switch { + case config.IsFortuna(timestamp): + state, err := feeStateBeforeBlock(config, parent, timestamp) + if err != nil { + return nil, fmt.Errorf("calculating initial fee state: %w", err) + } + price := state.GasPrice() + return new(big.Int).SetUint64(uint64(price)), nil case config.IsSubnetEVM(timestamp): return baseFeeFromWindow(config, feeConfig, parent, timestamp) default: diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index 1f13449798..a486be3f8d 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -7,6 +7,8 @@ import ( "math/big" "testing" + "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/subnet-evm/commontype" @@ -178,6 +180,74 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { timestamp: 2 * subnetevm.WindowLen, want: big.NewInt(feeConfig.MinBaseFee.Int64()), }, + { + name: "fortuna_invalid_timestamp", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Time: 1, + Extra: (&acp176.State{}).Bytes(), + }, + timestamp: 0, + wantErr: errInvalidTimestamp, + }, + { + name: "fortuna_first_block", + upgrades: extras.NetworkUpgrades{ + FortunaTimestamp: utils.NewUint64(1), + }, + parent: &types.Header{ + Number: big.NewInt(1), + }, + timestamp: 1, + want: big.NewInt(acp176.MinGasPrice), + }, + { + name: "fortuna_genesis_block", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + want: big.NewInt(acp176.MinGasPrice), + }, + { + name: "fortuna_invalid_fee_state", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: make([]byte, acp176.StateSize-1), + }, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_current", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: (&acp176.State{ + Gas: gas.State{ + Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * [acp176.TargetToPriceUpdateConversion] + }, + TargetExcess: 13_605_152, // 2^25 * ln(1.5) + }).Bytes(), + }, + want: big.NewInt(1_000_000_002), // nAVAX + 2 due to rounding + }, + { + name: "fortuna_decrease", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: (&acp176.State{ + Gas: gas.State{ + Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * [acp176.TargetToPriceUpdateConversion] + }, + TargetExcess: 13_605_152, // 2^25 * ln(1.5) + }).Bytes(), + }, + timestamp: 1, + want: big.NewInt(988_571_555), // e^((2_704_386_192 - 1_500_000) / 1_500_000 / [acp176.TargetToPriceUpdateConversion]) + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/plugin/evm/header/dynamic_fee_state.go b/plugin/evm/header/dynamic_fee_state.go new file mode 100644 index 0000000000..5c2b1372c3 --- /dev/null +++ b/plugin/evm/header/dynamic_fee_state.go @@ -0,0 +1,74 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package header + +import ( + "fmt" + + "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/subnet-evm/params/extras" +) + +// feeStateBeforeBlock takes the previous header and the timestamp of its child +// block and calculates the fee state before the child block is executed. +func feeStateBeforeBlock( + config *extras.ChainConfig, + parent *types.Header, + timestamp uint64, +) (acp176.State, error) { + if timestamp < parent.Time { + return acp176.State{}, fmt.Errorf("%w: timestamp %d prior to parent timestamp %d", + errInvalidTimestamp, + timestamp, + parent.Time, + ) + } + + var state acp176.State + if config.IsFortuna(parent.Time) && parent.Number.Cmp(common.Big0) != 0 { + // If the parent block was running with ACP-176, we start with the + // resulting fee state from the parent block. It is assumed that the + // parent has been verified, so the claimed fee state equals the actual + // fee state. + var err error + state, err = acp176.ParseState(parent.Extra) + if err != nil { + return acp176.State{}, fmt.Errorf("parsing parent fee state: %w", err) + } + } + + state.AdvanceTime(timestamp - parent.Time) + return state, nil +} + +// feeStateAfterBlock takes the previous header and returns the fee state after +// the execution of the provided child. +func feeStateAfterBlock( + config *extras.ChainConfig, + parent *types.Header, + header *types.Header, + desiredTargetExcess *gas.Gas, +) (acp176.State, error) { + // Calculate the gas state after the parent block + state, err := feeStateBeforeBlock(config, parent, header.Time) + if err != nil { + return acp176.State{}, fmt.Errorf("calculating initial fee state: %w", err) + } + + // Consume the gas used by the block + // There is never any extra gas used in subnet-evm because there are no atomic transactions. + if err := state.ConsumeGas(header.GasUsed, common.Big0); err != nil { + return acp176.State{}, fmt.Errorf("advancing the fee state: %w", err) + } + + // If the desired target excess is specified, move the target excess as much + // as possible toward that desired value. + if desiredTargetExcess != nil { + state.UpdateTargetExcess(*desiredTargetExcess) + } + return state, nil +} diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index 0ba1f53dcd..41c35ab9df 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -8,6 +8,8 @@ import ( "errors" "fmt" + "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/upgrade/subnetevm" @@ -19,17 +21,32 @@ const ( var ( errInvalidExtraPrefix = errors.New("invalid header.Extra prefix") + errIncorrectFeeState = errors.New("incorrect fee state") errInvalidExtraLength = errors.New("invalid header.Extra length") ) -// ExtraPrefix takes the previous header and the timestamp of its child -// block and calculates the expected extra prefix for the child block. +// ExtraPrefix returns what the prefix of the header's Extra field should be +// based on the desired target excess. +// +// If the `desiredTargetExcess` is nil, the parent's target excess is used. func ExtraPrefix( config *extras.ChainConfig, parent *types.Header, header *types.Header, + desiredTargetExcess *gas.Gas, ) ([]byte, error) { switch { + case config.IsFortuna(header.Time): + state, err := feeStateAfterBlock( + config, + parent, + header, + desiredTargetExcess, + ) + if err != nil { + return nil, fmt.Errorf("calculating fee state: %w", err) + } + return state.Bytes(), nil case config.IsSubnetEVM(header.Time): window, err := feeWindow(config, parent, header.Time) if err != nil { @@ -50,6 +67,34 @@ func VerifyExtraPrefix( header *types.Header, ) error { switch { + case config.IsFortuna(header.Time): + remoteState, err := acp176.ParseState(header.Extra) + if err != nil { + return fmt.Errorf("parsing remote fee state: %w", err) + } + + // By passing in the claimed target excess, we ensure that the expected + // target excess is equal to the claimed target excess if it is possible + // to have correctly set it to that value. Otherwise, the resulting + // value will be as close to the claimed value as possible, but would + // not be equal. + expectedState, err := feeStateAfterBlock( + config, + parent, + header, + &remoteState.TargetExcess, + ) + if err != nil { + return fmt.Errorf("calculating expected fee state: %w", err) + } + + if remoteState != expectedState { + return fmt.Errorf("%w: expected %+v, found %+v", + errIncorrectFeeState, + expectedState, + remoteState, + ) + } case config.IsSubnetEVM(header.Time): feeWindow, err := feeWindow(config, parent, header.Time) if err != nil { @@ -74,6 +119,15 @@ func VerifyExtraPrefix( func VerifyExtra(rules extras.AvalancheRules, extra []byte) error { extraLen := len(extra) switch { + case rules.IsFortuna: + if extraLen < acp176.StateSize { + return fmt.Errorf( + "%w: expected >= %d but got %d", + errInvalidExtraLength, + acp176.StateSize, + extraLen, + ) + } case rules.IsDurango: if extraLen < subnetevm.WindowSize { return fmt.Errorf( @@ -107,8 +161,11 @@ func VerifyExtra(rules extras.AvalancheRules, extra []byte) error { // 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 { +func PredicateBytesFromExtra(rules extras.AvalancheRules, extra []byte) []byte { offset := subnetevm.WindowSize + if rules.IsFortuna { + offset = acp176.StateSize + } // Prior to Durango, the VM enforces the extra data is smaller than or equal // to `offset`. // After Durango, the VM pre-verifies the extra data past `offset` is valid. diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index 12031f55b1..2e703e0afa 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -7,6 +7,8 @@ import ( "math/big" "testing" + "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/customtypes" @@ -22,12 +24,13 @@ const ( func TestExtraPrefix(t *testing.T) { tests := []struct { - name string - upgrades extras.NetworkUpgrades - parent *types.Header - header *types.Header - want []byte - wantErr error + name string + upgrades extras.NetworkUpgrades + parent *types.Header + header *types.Header + desiredTargetExcess *gas.Gas + want []byte + wantErr error }{ { name: "pre_subnet_evm", @@ -107,6 +110,91 @@ func TestExtraPrefix(t *testing.T) { return window.Bytes() }(), }, + { + name: "fortuna_first_block", + upgrades: extras.NetworkUpgrades{ + FortunaTimestamp: utils.NewUint64(1), + }, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{ + Time: 1, + GasUsed: 1, + }, + want: (&acp176.State{ + Gas: gas.State{ + Capacity: acp176.MinMaxPerSecond - 6, + Excess: 6, + }, + TargetExcess: 0, + }).Bytes(), + }, + { + name: "fortuna_genesis_block", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: 2, + }, + desiredTargetExcess: (*gas.Gas)(utils.NewUint64(3)), + want: (&acp176.State{ + Gas: gas.State{ + Capacity: acp176.MinMaxPerSecond - 3, + Excess: 3, + }, + TargetExcess: 3, + }).Bytes(), + }, + { + name: "fortuna_invalid_fee_state", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_invalid_gas_used", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: (&acp176.State{}).Bytes(), + }, + header: &types.Header{ + GasUsed: 1, + }, + wantErr: gas.ErrInsufficientCapacity, + }, + { + name: "fortuna_reduce_capacity", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: (&acp176.State{ + Gas: gas.State{ + Capacity: 20_039_100, // [acp176.MinTargetPerSecond] * e^(2*[acp176.MaxTargetExcessDiff] / [acp176.TargetConversion]) + Excess: 2_000_000_000 - 3, + }, + TargetExcess: 2 * acp176.MaxTargetExcessDiff, + }).Bytes(), + }, + header: &types.Header{ + GasUsed: 2, + }, + desiredTargetExcess: (*gas.Gas)(utils.NewUint64(0)), + want: (&acp176.State{ + Gas: gas.State{ + Capacity: 20_019_540, // [acp176.MinTargetPerSecond] * e^([acp176.MaxTargetExcessDiff] / [acp176.TargetConversion]) + Excess: 1_998_047_816, // 2M * NewTarget / OldTarget + }, + TargetExcess: acp176.MaxTargetExcessDiff, + }).Bytes(), + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -115,7 +203,7 @@ func TestExtraPrefix(t *testing.T) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := ExtraPrefix(config, test.parent, test.header) + got, err := ExtraPrefix(config, test.parent, test.header, test.desiredTargetExcess) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) @@ -165,6 +253,62 @@ func TestVerifyExtraPrefix(t *testing.T) { }, wantErr: nil, }, + { + name: "fortuna_invalid_header", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + header: &types.Header{}, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_invalid_gas_consumed", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasUsed: 1, + Extra: (&acp176.State{}).Bytes(), + }, + wantErr: gas.ErrInsufficientCapacity, + }, + { + name: "fortuna_wrong_fee_state", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: 1, + Extra: (&acp176.State{ + Gas: gas.State{ + Capacity: acp176.MinMaxPerSecond - 1, + Excess: 1, + }, + TargetExcess: acp176.MaxTargetExcessDiff + 1, // Too much of a diff + }).Bytes(), + }, + wantErr: errIncorrectFeeState, + }, + { + name: "fortuna_valid", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: 1, + Extra: (&acp176.State{ + Gas: gas.State{ + Capacity: acp176.MinMaxPerSecond - 1, + Excess: 1, + }, + TargetExcess: acp176.MaxTargetExcessDiff, + }).Bytes(), + }, + wantErr: nil, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -244,6 +388,30 @@ func TestVerifyExtra(t *testing.T) { extra: make([]byte, subnetevm.WindowSize-1), expected: errInvalidExtraLength, }, + { + name: "fortuna_valid_min", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: make([]byte, acp176.StateSize), + expected: nil, + }, + { + name: "fortuna_valid_extra", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: make([]byte, acp176.StateSize+1), + expected: nil, + }, + { + name: "fortuna_invalid", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: make([]byte, acp176.StateSize-1), + expected: errInvalidExtraLength, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -257,6 +425,7 @@ func TestPredicateBytesFromExtra(t *testing.T) { tests := []struct { name string extra []byte + rules extras.AvalancheRules expected []byte }{ { @@ -281,10 +450,44 @@ func TestPredicateBytesFromExtra(t *testing.T) { }, expected: []byte{5}, }, + { + name: "fortuna_empty_extra", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: nil, + expected: nil, + }, + { + name: "fortuna_too_short", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: make([]byte, acp176.StateSize-1), + expected: nil, + }, + { + name: "fortuna_empty_predicate", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: make([]byte, acp176.StateSize), + expected: nil, + }, + { + name: "fortuna_non_empty_predicate", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: []byte{ + acp176.StateSize: 5, + }, + expected: []byte{5}, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got := PredicateBytesFromExtra(test.extra) + got := PredicateBytesFromExtra(test.rules, test.extra) require.Equal(t, test.expected, got) }) } @@ -334,6 +537,7 @@ func TestPredicateBytesExtra(t *testing.T) { name string extra []byte predicate []byte + rules extras.AvalancheRules wantExtraWithPredicate []byte wantPredicateBytes []byte }{ @@ -362,7 +566,7 @@ func TestPredicateBytesExtra(t *testing.T) { t.Run(test.name, func(t *testing.T) { gotExtra := SetPredicateBytesInExtra(test.extra, test.predicate) require.Equal(t, test.wantExtraWithPredicate, gotExtra) - gotPredicateBytes := PredicateBytesFromExtra(gotExtra) + gotPredicateBytes := PredicateBytesFromExtra(test.rules, gotExtra) require.Equal(t, test.wantPredicateBytes, gotPredicateBytes) }) } diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index f1203c43f2..98214571e1 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -15,12 +15,11 @@ import ( ) var ( - errInvalidGasUsed = errors.New("invalid gas used") - errInvalidGasLimit = errors.New("invalid gas limit") + errInvalidExtraDataGasUsed = errors.New("invalid extra data gas used") + errInvalidGasUsed = errors.New("invalid gas used") + errInvalidGasLimit = errors.New("invalid gas limit") ) -type CalculateGasLimitFunc func(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint64 - // GasLimit takes the previous header and the timestamp of its child block and // calculates the gas limit for the child block. func GasLimit( @@ -29,7 +28,18 @@ func GasLimit( parent *types.Header, timestamp uint64, ) (uint64, error) { + // TODO: XXX Handle feeConfig with Fortuna here switch { + case config.IsFortuna(timestamp): + state, err := feeStateBeforeBlock(config, parent, timestamp) + if err != nil { + return 0, fmt.Errorf("calculating initial fee state: %w", err) + } + // The gas limit is set to the maximum capacity, rather than the current + // capacity, to minimize the differences with upstream geth. During + // block building and gas usage calculations, the gas limit is checked + // against the current capacity. + return uint64(state.MaxCapacity()), nil case config.IsSubnetEVM(timestamp): return feeConfig.GasLimit.Uint64(), nil default: @@ -72,6 +82,19 @@ func VerifyGasLimit( header *types.Header, ) error { switch { + case config.IsFortuna(header.Time): + state, err := feeStateBeforeBlock(config, parent, header.Time) + if err != nil { + return fmt.Errorf("calculating initial fee state: %w", err) + } + maxCapacity := state.MaxCapacity() + if header.GasLimit != uint64(maxCapacity) { + return fmt.Errorf("%w: have %d, want %d", + errInvalidGasLimit, + header.GasLimit, + maxCapacity, + ) + } case config.IsSubnetEVM(header.Time): expectedGasLimit := feeConfig.GasLimit.Uint64() if header.GasLimit != expectedGasLimit { @@ -114,5 +137,14 @@ func GasCapacity( parent *types.Header, timestamp uint64, ) (uint64, error) { - return GasLimit(config, feeConfig, parent, timestamp) + // Prior to the F upgrade, the gas capacity is equal to the gas limit. + if !config.IsFortuna(timestamp) { + return GasLimit(config, feeConfig, parent, timestamp) + } + + state, err := feeStateBeforeBlock(config, parent, timestamp) + if err != nil { + return 0, fmt.Errorf("calculating initial fee state: %w", err) + } + return uint64(state.Gas.Capacity), nil } diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index 29549fb114..e851329a27 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -4,8 +4,12 @@ package header import ( + "math/big" "testing" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" + "github.com/ava-labs/libevm/core/types" ethparams "github.com/ava-labs/libevm/params" "github.com/ava-labs/subnet-evm/commontype" @@ -36,6 +40,22 @@ func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { upgrades: extras.TestSubnetEVMChainConfig.NetworkUpgrades, want: feeConfig.GasLimit.Uint64(), }, + { + name: "fortuna_invalid_parent_header", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_initial_max_capacity", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + want: acp176.MinMaxCapacity, + }, { name: "pre_subnet_evm", upgrades: extras.TestPreSubnetEVMChainConfig.NetworkUpgrades, @@ -59,6 +79,71 @@ func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { } } +func TestVerifyGasUsed(t *testing.T) { + tests := []struct { + name string + feeConfig commontype.FeeConfig + upgrades extras.NetworkUpgrades + parent *types.Header + header *types.Header + want error + }{ + { + name: "fortuna_gas_used_overflow", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + header: &types.Header{ + GasUsed: math.MaxUint[uint64](), + }, + want: math.ErrOverflow, + }, + { + name: "fortuna_invalid_capacity", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + want: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_invalid_usage", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + // The maximum allowed gas used is: + // (header.Time - parent.Time) * [acp176.MinMaxPerSecond] + // which is equal to [acp176.MinMaxPerSecond]. + GasUsed: acp176.MinMaxPerSecond + 1, + }, + want: errInvalidGasUsed, + }, + { + name: "fortuna_max_consumption", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: acp176.MinMaxPerSecond, + }, + want: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + config := &extras.ChainConfig{ + NetworkUpgrades: test.upgrades, + } + err := VerifyGasUsed(config, test.feeConfig, test.parent, test.header) + require.ErrorIs(t, err, test.want) + }) + } +} + func TestVerifyGasLimit(t *testing.T) { t.Run("normal", func(t *testing.T) { VerifyGasLimitTest(t, testFeeConfig) @@ -76,6 +161,36 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { header *types.Header want error }{ + { + name: "fortuna_invalid_header", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + want: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_invalid", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasLimit: acp176.MinMaxCapacity + 1, + }, + want: errInvalidGasLimit, + }, + { + name: "fortuna_valid", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasLimit: acp176.MinMaxCapacity, + }, + }, { name: "subnet_evm_valid", upgrades: extras.TestSubnetEVMChainConfig.NetworkUpgrades, @@ -147,17 +262,9 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { } func TestGasCapacity(t *testing.T) { - t.Run("normal", func(t *testing.T) { - GasCapacityTest(t, testFeeConfig) - }) - t.Run("double", func(t *testing.T) { - GasCapacityTest(t, testFeeConfigDouble) - }) -} - -func GasCapacityTest(t *testing.T, feeConfig commontype.FeeConfig) { tests := []struct { name string + feeConfig commontype.FeeConfig upgrades extras.NetworkUpgrades parent *types.Header timestamp uint64 @@ -167,7 +274,24 @@ func GasCapacityTest(t *testing.T, feeConfig commontype.FeeConfig) { { name: "subnet_evm", upgrades: extras.TestSubnetEVMChainConfig.NetworkUpgrades, - want: feeConfig.GasLimit.Uint64(), + want: 0, // TODO: XXX Handle feeConfig with Fortuna here + }, + { + name: "fortuna_invalid_header", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fortuna_after_1s", + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + timestamp: 1, + want: acp176.MinMaxPerSecond, }, } for _, test := range tests { @@ -177,7 +301,7 @@ func GasCapacityTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := GasCapacity(config, feeConfig, test.parent, test.timestamp) + got, err := GasCapacity(config, test.feeConfig, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 4754439e03..e734694f88 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/network/p2p/acp118" "github.com/ava-labs/avalanchego/network/p2p/gossip" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/firewood-go-ethhash/ffi" "github.com/prometheus/client_golang/prometheus" @@ -87,6 +88,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/chain" + "github.com/ava-labs/avalanchego/vms/components/gas" commonEng "github.com/ava-labs/avalanchego/snow/engine/common" @@ -116,6 +118,14 @@ const ( ethMetricsPrefix = "eth" sdkMetricsPrefix = "sdk" chainStateMetricsPrefix = "chain_state" + + // gossip constants + pushGossipDiscardedElements = 16_384 + txGossipTargetMessageSize = 20 * units.KiB + maxValidatorSetStaleness = time.Minute + txGossipThrottlingPeriod = 10 * time.Second + txGossipThrottlingLimit = 2 + txGossipPollSize = 1 ) // Define the API endpoints for the VM @@ -613,6 +623,15 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash, ethConfig ethconfig. if err != nil { return err } + + // If the gas target is specified, calculate the desired target excess and + // use it during block creation. + var desiredTargetExcess *gas.Gas + if vm.config.GasTarget != nil { + desiredTargetExcess = new(gas.Gas) + *desiredTargetExcess = acp176.DesiredTargetExcess(*vm.config.GasTarget) + } + vm.eth, err = eth.New( node, &vm.ethConfig, @@ -620,7 +639,11 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash, ethConfig ethconfig. vm.chaindb, eth.Settings{MaxBlocksPerRequest: vm.config.MaxBlocksPerRequest}, lastAcceptedHash, - dummy.NewFakerWithClock(&vm.clock), + dummy.NewDummyEngine( + dummy.Mode{}, + &vm.clock, + desiredTargetExcess, + ), &vm.clock, ) if err != nil { @@ -637,6 +660,7 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash, ethConfig ethconfig. } vm.txPool.SetMinFee(feeConfig.MinBaseFee) vm.txPool.SetGasTip(big.NewInt(0)) + vm.txPool.SetMinFee(big.NewInt(acp176.MinGasPrice)) vm.eth.Start() return vm.initChainState(lastAccepted) diff --git a/plugin/evm/vm_warp_test.go b/plugin/evm/vm_warp_test.go index 0e7285e944..43989ffb02 100644 --- a/plugin/evm/vm_warp_test.go +++ b/plugin/evm/vm_warp_test.go @@ -740,7 +740,8 @@ func testReceiveWarpMessage( // Require the block was built with a successful predicate result ethBlock := block2.(*chain.BlockWrapper).Block.(*Block).ethBlock - headerPredicateResultsBytes := customheader.PredicateBytesFromExtra(ethBlock.Extra()) + rules := params.GetExtra(vm.chainConfig).GetAvalancheRules(ethBlock.Time()) + headerPredicateResultsBytes := customheader.PredicateBytesFromExtra(rules, ethBlock.Extra()) results, err := predicate.ParseResults(headerPredicateResultsBytes) require.NoError(err) From c540032d057a6f405c00abd87611ac141194f1f3 Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Thu, 28 Aug 2025 09:42:25 -0400 Subject: [PATCH 2/8] ACP-176 Spike --- eth/tracers/api_test.go | 3 ++- go.mod | 4 +--- go.sum | 2 ++ internal/ethapi/api_test.go | 3 ++- tests/state_test_util.go | 3 ++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 124b8d6211..83afe1c1d1 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -219,7 +219,8 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block for idx, tx := range block.Transactions() { msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), b.chain, nil) + rulesExtra := params.GetRulesExtra(b.ChainConfig().Rules(block.Number(), params.IsMergeTODO, block.Time())) + context := core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), b.chain, nil) if idx == txIndex { return msg, context, statedb, release, nil } diff --git a/go.mod b/go.mod index a12f187076..0461e41663 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.9 require ( github.com/VictoriaMetrics/fastcache v1.12.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/avalanchego v1.13.4 + github.com/ava-labs/avalanchego v1.13.4-rc.2.0.20250820204950-f5e3cc7eb474 github.com/ava-labs/firewood-go-ethhash/ffi v0.0.9 github.com/ava-labs/libevm v1.13.14-0.3.0.rc.6 github.com/davecgh/go-spew v1.1.1 @@ -177,5 +177,3 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) - -replace github.com/ava-labs/avalanchego => ../avalanchego diff --git a/go.sum b/go.sum index decb654835..b2dd13b171 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/ava-labs/avalanchego v1.13.4-rc.2.0.20250820204950-f5e3cc7eb474 h1:HXBBQcGdRjA+xefmj4o/kBATrgoznffQEjPLBrDb4U4= +github.com/ava-labs/avalanchego v1.13.4-rc.2.0.20250820204950-f5e3cc7eb474/go.mod h1:8jIANfIkhclLiExO2b8Pc/o/gAWBC7gaDjOmUTjogQs= github.com/ava-labs/coreth v0.15.3-rc.5 h1:zGk1LaFeZOEkA6uPF1g9BNCjbZOrONx9fm5WtiH5NWg= github.com/ava-labs/coreth v0.15.3-rc.5/go.mod h1:sEqzSu2f4FJEGFL7CP3zNOQtQ0MupWJdzTp7W65EDf8= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.9 h1:zw0g+cUbZDsGdWx1PKmBChkpy+ixL3QgiI86DUOuXvo= diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index cc812772ca..9ebd0bf2cc 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -567,7 +567,8 @@ func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state vmConfig = b.chain.GetVMConfig() } txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(header, b.chain, nil) + rulesExtra := params.GetRulesExtra(b.ChainConfig().Rules(header.Number, params.IsMergeTODO, header.Time)) + context := core.NewEVMBlockContext(rulesExtra.AvalancheRules, header, b.chain, nil) if blockContext != nil { context = *blockContext } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 512c73bd51..0736775cde 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -307,7 +307,8 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + rulesExtra := params.GetRulesExtra(config.Rules(block.Number(), params.IsMergeTODO, block.Time())) + context := core.NewEVMBlockContext(rulesExtra.AvalancheRules, block.Header(), nil, &t.json.Env.Coinbase) context.GetHash = vmTestBlockHash context.BaseFee = baseFee context.Random = nil From 365897a511be55a927f2c9eb831112e918007b62 Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Tue, 9 Sep 2025 13:48:01 -0400 Subject: [PATCH 3/8] Continue acp224 config piping --- consensus/dummy/consensus.go | 12 +++++++++++- core/chain_makers.go | 10 +++++++++- plugin/evm/header/base_fee.go | 4 +++- plugin/evm/header/base_fee_test.go | 16 ++++++++-------- plugin/evm/header/block_gas_cost.go | 1 + plugin/evm/header/block_gas_cost_test.go | 19 ++++++++++++++++--- plugin/evm/header/gas_limit.go | 2 ++ .../contracts/acp224feemanager/config_test.go | 8 ++++---- 8 files changed, 54 insertions(+), 18 deletions(-) diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index 692883e217..ba2d30bfca 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -154,7 +154,7 @@ func verifyHeaderGasFields( if err := customheader.VerifyGasLimit(config, feeConfig, acp224FeeConfig, parent, header); err != nil { return err } - if err := customheader.VerifyExtraPrefix(config, parent, acp224FeeConfig, header); err != nil { + if err := customheader.VerifyExtraPrefix(config, parent, header); err != nil { return err } @@ -349,11 +349,16 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types if err != nil { return err } + acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) + if err != nil { + return err + } // Verify the BlockGasCost set in the header matches the expected value. blockGasCost := customtypes.BlockGasCost(block) expectedBlockGasCost := customheader.BlockGasCost( config, feeConfig, + acp224FeeConfig, parent, timestamp, ) @@ -384,6 +389,10 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h if err != nil { return nil, err } + acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) + if err != nil { + return nil, err + } config := params.GetExtra(chain.Config()) // Calculate the required block gas cost for this block. @@ -391,6 +400,7 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h headerExtra.BlockGasCost = customheader.BlockGasCost( config, feeConfig, + acp224FeeConfig, parent, header.Time, ) diff --git a/core/chain_makers.go b/core/chain_makers.go index af51b32a8b..e32194554e 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -383,12 +383,16 @@ func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.S if err != nil { panic(err) } + acp224FeeConfig, _, err := cm.GetACP224FeeConfigAt(parent.Header()) + if err != nil { + panic(err) + } config := params.GetExtra(cm.config) gasLimit, err := header.GasLimit(config, feeConfig, parent.Header(), time) if err != nil { panic(err) } - baseFee, err := header.BaseFee(config, feeConfig, parent.Header(), time) + baseFee, err := header.BaseFee(config, feeConfig, acp224FeeConfig, parent.Header(), time) if err != nil { panic(err) } @@ -505,6 +509,10 @@ func (cm *chainMaker) GetFeeConfigAt(parent *types.Header) (commontype.FeeConfig return params.GetExtra(cm.config).FeeConfig, nil, nil } +func (cm *chainMaker) GetACP224FeeConfigAt(parent *types.Header) (commontype.ACP224FeeConfig, *big.Int, error) { + return params.GetExtra(cm.config).ACP224FeeConfig, nil, nil +} + func (cm *chainMaker) GetCoinbaseAt(parent *types.Header) (common.Address, bool, error) { return constants.BlackholeAddr, params.GetExtra(cm.config).AllowFeeRecipients, nil } diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index 4676618832..6362a919a2 100644 --- a/plugin/evm/header/base_fee.go +++ b/plugin/evm/header/base_fee.go @@ -23,6 +23,7 @@ var errEstimateBaseFeeWithoutActivation = errors.New("cannot estimate base fee f func BaseFee( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, timestamp uint64, ) (*big.Int, error) { @@ -54,6 +55,7 @@ func BaseFee( func EstimateNextBaseFee( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, timestamp uint64, ) (*big.Int, error) { @@ -62,5 +64,5 @@ func EstimateNextBaseFee( } timestamp = max(timestamp, parent.Time, *config.SubnetEVMTimestamp) - return BaseFee(config, feeConfig, parent, timestamp) + return BaseFee(config, feeConfig, acp224FeeConfig, parent, timestamp) } diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index e087d171aa..84b02e4557 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -25,14 +25,14 @@ const ( func TestBaseFee(t *testing.T) { t.Run("normal", func(t *testing.T) { - BaseFeeTest(t, testFeeConfig) + BaseFeeTest(t, testFeeConfig, testACP224FeeConfig) }) t.Run("double", func(t *testing.T) { - BaseFeeTest(t, testFeeConfigDouble) + BaseFeeTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) }) } -func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { +func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { tests := []struct { name string upgrades extras.NetworkUpgrades @@ -257,7 +257,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := BaseFee(config, feeConfig, test.parent, test.timestamp) + got, err := BaseFee(config, feeConfig, acp224FeeConfig, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) @@ -269,14 +269,14 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { func TestEstimateNextBaseFee(t *testing.T) { t.Run("normal", func(t *testing.T) { - BlockGasCostTest(t, testFeeConfig) + EstimateNextBaseFeeTest(t, testFeeConfig, testACP224FeeConfig) }) t.Run("double", func(t *testing.T) { - BlockGasCostTest(t, testFeeConfigDouble) + EstimateNextBaseFeeTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) }) } -func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { +func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { testBaseFee := uint64(225 * utils.GWei) nilUpgrade := extras.NetworkUpgrades{} tests := []struct { @@ -323,7 +323,7 @@ func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := EstimateNextBaseFee(config, feeConfig, test.parent, test.timestamp) + got, err := EstimateNextBaseFee(config, feeConfig, acp224FeeConfig, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) diff --git a/plugin/evm/header/block_gas_cost.go b/plugin/evm/header/block_gas_cost.go index 023ed05b0e..17e3bb0140 100644 --- a/plugin/evm/header/block_gas_cost.go +++ b/plugin/evm/header/block_gas_cost.go @@ -28,6 +28,7 @@ var ( func BlockGasCost( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, timestamp uint64, ) *big.Int { diff --git a/plugin/evm/header/block_gas_cost_test.go b/plugin/evm/header/block_gas_cost_test.go index 275333312c..6c57375b6e 100644 --- a/plugin/evm/header/block_gas_cost_test.go +++ b/plugin/evm/header/block_gas_cost_test.go @@ -28,6 +28,12 @@ var ( MinBaseFee: big.NewInt(25 * utils.GWei), GasLimit: big.NewInt(12_000_000), } + testACP224FeeConfig = commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(1_000_000), + MinGasPrice: big.NewInt(1), + MaxCapacityFactor: big.NewInt(5), + TimeToDouble: big.NewInt(60), + } testFeeConfigDouble = commontype.FeeConfig{ MinBlockGasCost: big.NewInt(2), @@ -39,18 +45,24 @@ var ( MinBaseFee: big.NewInt(50 * utils.GWei), GasLimit: big.NewInt(24_000_000), } + testACP224FeeConfigDouble = commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(2_000_000), + MinGasPrice: big.NewInt(2), + MaxCapacityFactor: big.NewInt(10), + TimeToDouble: big.NewInt(120), + } ) func TestBlockGasCost(t *testing.T) { t.Run("normal", func(t *testing.T) { - BlockGasCostTest(t, testFeeConfig) + BlockGasCostTest(t, testFeeConfig, testACP224FeeConfig) }) t.Run("double", func(t *testing.T) { - BlockGasCostTest(t, testFeeConfigDouble) + BlockGasCostTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) }) } -func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig) { +func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { maxBlockGasCostBig := feeConfig.MaxBlockGasCost maxBlockGasCost := feeConfig.MaxBlockGasCost.Uint64() blockGasCostStep := feeConfig.BlockGasCostStep.Uint64() @@ -108,6 +120,7 @@ func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig) { assert.Equal(t, test.expected, BlockGasCost( config, feeConfig, + acp224FeeConfig, parent, test.timestamp, )) diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index b3032d1ade..1167f9d656 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -58,6 +58,7 @@ func GasLimit( func VerifyGasUsed( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, ) error { @@ -80,6 +81,7 @@ func VerifyGasUsed( func VerifyGasLimit( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, ) error { diff --git a/precompile/contracts/acp224feemanager/config_test.go b/precompile/contracts/acp224feemanager/config_test.go index 532d2a791f..04c94fda4b 100644 --- a/precompile/contracts/acp224feemanager/config_test.go +++ b/precompile/contracts/acp224feemanager/config_test.go @@ -1,8 +1,8 @@ -// // Code generated -// // This file is a generated precompile config test with the skeleton of test functions. -// // The file is generated by a template. Please inspect every code and comment in this file before use. +// Code generated +// This file is a generated precompile config test with the skeleton of test functions. +// The file is generated by a template. Please inspect every code and comment in this file before use. -// package acp224feemanager +package acp224feemanager // import ( // "testing" From 3b80d822d49564ccd41aeb3a8751dbd06bc8bee2 Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Tue, 9 Sep 2025 18:11:11 -0400 Subject: [PATCH 4/8] Add precompile target gas state to block building and verification --- cmd/evm/internal/t8ntool/transition.go | 4 +- commontype/fee_config.go | 47 ++++++++++++++++++++++-- consensus/dummy/consensus.go | 40 ++++++++++---------- core/chain_makers.go | 6 +-- core/state_processor_test.go | 12 +++--- core/txpool/blobpool/blobpool.go | 12 ------ core/txpool/blobpool/blobpool_test.go | 2 +- core/txpool/legacypool/legacypool.go | 6 +-- eth/gasprice/gasprice.go | 6 +-- go.mod | 2 +- go.sum | 4 +- miner/worker.go | 6 +-- plugin/evm/header/base_fee.go | 4 +- plugin/evm/header/base_fee_test.go | 16 ++++---- plugin/evm/header/block_gas_cost.go | 1 - plugin/evm/header/block_gas_cost_test.go | 1 - plugin/evm/header/dynamic_fee_state.go | 15 +++++++- plugin/evm/header/extra.go | 11 ++++++ plugin/evm/header/gas_limit.go | 2 - plugin/evm/header/gas_limit_test.go | 10 ++--- precompile/precompileconfig/mocks.go | 14 +++++++ 21 files changed, 129 insertions(+), 92 deletions(-) diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 5633ae289d..44d5f62e58 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -226,15 +226,13 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { Extra: make([]byte, subnetevm.WindowSize), // TODO: consider passing extra through env } feeConfig := params.DefaultFeeConfig - acp224FeeConfig := params.DefaultACP224FeeConfig if env.MinBaseFee != nil { // Override the default min base fee if it's set in the env feeConfig.MinBaseFee = env.MinBaseFee - acp224FeeConfig.MinGasPrice = env.MinBaseFee } configExtra := params.GetExtra(chainConfig) var err error - env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, acp224FeeConfig, parent, env.Timestamp) + env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, parent, env.Timestamp) if err != nil { return NewError(ErrorConfig, fmt.Errorf("failed calculating base fee: %v", err)) } diff --git a/commontype/fee_config.go b/commontype/fee_config.go index 6a515a9e4f..35f4cf94fa 100644 --- a/commontype/fee_config.go +++ b/commontype/fee_config.go @@ -24,17 +24,56 @@ type ACP224FeeConfig struct { var EmptyACP224FeeConfig = ACP224FeeConfig{} func (f *ACP224FeeConfig) Verify() error { - // TODO: XXX Add the verification for the ACP224FeeManager - return nil + switch { + case f.TargetGas == nil: + return errors.New("targetGas cannot be nil") + case f.MinGasPrice == nil: + return errors.New("minGasPrice cannot be nil") + case f.MaxCapacityFactor == nil: + return errors.New("maxCapacityFactor cannot be nil") + case f.TimeToDouble == nil: + return errors.New("timeToDouble cannot be nil") + } + + switch { + case f.TargetGas.Cmp(common.Big0) != 1: + return fmt.Errorf("targetGas = %d cannot be less than or equal to 0", f.TargetGas) + case f.MinGasPrice.Cmp(common.Big0) != 1: + return fmt.Errorf("minGasPrice = %d cannot be less than or equal to 0", f.MinGasPrice) + case f.MaxCapacityFactor.Cmp(common.Big0) == -1: + return fmt.Errorf("maxCapacityFactor = %d cannot be less than 0", f.MaxCapacityFactor) + case f.TimeToDouble.Cmp(common.Big0) == -1: + return fmt.Errorf("timeToDouble = %d cannot be less than 0", f.TimeToDouble) + } + return f.checkByteLens() } func (f *ACP224FeeConfig) Equal(other *ACP224FeeConfig) bool { - // TODO: XXX Add the equality check for the ACP224FeeManager if other == nil { return false } - return true + return utils.BigNumEqual(f.TargetGas, other.TargetGas) && + utils.BigNumEqual(f.MinGasPrice, other.MinGasPrice) && + utils.BigNumEqual(f.MaxCapacityFactor, other.MaxCapacityFactor) && + utils.BigNumEqual(f.TimeToDouble, other.TimeToDouble) +} + +// checkByteLens checks byte lengths against common.HashLen (32 bytes) and returns error +func (f *ACP224FeeConfig) checkByteLens() error { + if isBiggerThanHashLen(f.TargetGas) { + return fmt.Errorf("targetGas exceeds %d bytes", common.HashLength) + } + if isBiggerThanHashLen(f.MinGasPrice) { + return fmt.Errorf("minGasPrice exceeds %d bytes", common.HashLength) + } + if isBiggerThanHashLen(f.MaxCapacityFactor) { + return fmt.Errorf("maxCapacityFactor exceeds %d bytes", common.HashLength) + } + if isBiggerThanHashLen(f.TimeToDouble) { + return fmt.Errorf("timeToDouble exceeds %d bytes", common.HashLength) + } + return nil } // FeeConfig specifies the parameters for the dynamic fee algorithm, which determines the gas limit, base fee, and block gas cost of blocks diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index 46a774d888..fd021d10c9 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -138,28 +138,34 @@ func verifyHeaderGasFields( parent *types.Header, chain consensus.ChainHeaderReader, ) error { - // We verify the current block by checking the parent fee config - // this is because the current block cannot set the fee config for itself + // We verify the current block by checking the parent fee configs + // because the current block cannot set the fee config for itself. // Fee config might depend on the state when precompile is activated // but we don't know the final state while forming the block. // See worker package for more details. feeConfig, _, err := chain.GetFeeConfigAt(parent) - acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) if err != nil { return err } - if err := customheader.VerifyGasUsed(config, feeConfig, acp224FeeConfig, parent, header); err != nil { + + if err := customheader.VerifyGasUsed(config, feeConfig, parent, header); err != nil { return err } - if err := customheader.VerifyGasLimit(config, feeConfig, acp224FeeConfig, parent, header); err != nil { + if err := customheader.VerifyGasLimit(config, feeConfig, parent, header); err != nil { + return err + } + + acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) + if err != nil { return err } - if err := customheader.VerifyExtraPrefix(config, parent, header); err != nil { + + if err := customheader.VerifyExtraPrefix(config, acp224FeeConfig, parent, header); err != nil { return err } // Verify header.BaseFee matches the expected value. - expectedBaseFee, err := customheader.BaseFee(config, feeConfig, acp224FeeConfig, parent, header.Time) + expectedBaseFee, err := customheader.BaseFee(config, feeConfig, parent, header.Time) if err != nil { return fmt.Errorf("failed to calculate base fee: %w", err) } @@ -171,7 +177,6 @@ func verifyHeaderGasFields( expectedBlockGasCost := customheader.BlockGasCost( config, feeConfig, - acp224FeeConfig, parent, header.Time, ) @@ -349,16 +354,11 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types if err != nil { return err } - acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) - if err != nil { - return err - } // Verify the BlockGasCost set in the header matches the expected value. blockGasCost := customtypes.BlockGasCost(block) expectedBlockGasCost := customheader.BlockGasCost( config, feeConfig, - acp224FeeConfig, parent, timestamp, ) @@ -389,10 +389,6 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h if err != nil { return nil, err } - acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) - if err != nil { - return nil, err - } config := params.GetExtra(chain.Config()) // Calculate the required block gas cost for this block. @@ -400,7 +396,6 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h headerExtra.BlockGasCost = customheader.BlockGasCost( config, feeConfig, - acp224FeeConfig, parent, header.Time, ) @@ -416,11 +411,14 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h } } - // TODO: XXX Determine the proper target excess based on whether or not the ACP224 precompile is active - // prior to the block being finalized. + // Get the ACP224 fee config at the parent since the current block has not been finalized yet. + acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) + if err != nil { + return nil, err + } // finalize the header.Extra - extraPrefix, err := customheader.ExtraPrefix(config, parent, header, eng.desiredTargetExcess) + extraPrefix, err := customheader.ExtraPrefix(config, acp224FeeConfig, parent, header, eng.desiredTargetExcess) if err != nil { return nil, fmt.Errorf("failed to calculate new header.Extra: %w", err) } diff --git a/core/chain_makers.go b/core/chain_makers.go index e32194554e..36c97381c5 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -383,16 +383,12 @@ func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.S if err != nil { panic(err) } - acp224FeeConfig, _, err := cm.GetACP224FeeConfigAt(parent.Header()) - if err != nil { - panic(err) - } config := params.GetExtra(cm.config) gasLimit, err := header.GasLimit(config, feeConfig, parent.Header(), time) if err != nil { panic(err) } - baseFee, err := header.BaseFee(config, feeConfig, acp224FeeConfig, parent.Header(), time) + baseFee, err := header.BaseFee(config, feeConfig, parent.Header(), time) if err != nil { panic(err) } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index d994151aec..27a614f754 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -365,13 +365,9 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr if err != nil { panic(err) } - acp224FeeConfig, _, err := fakeChainReader.GetACP224FeeConfigAt(parent.Header()) - if err != nil { - panic(err) - } configExtra := params.GetExtra(config) gasLimit, _ := customheader.GasLimit(configExtra, feeConfig, parent.Header(), time) - baseFee, _ := customheader.BaseFee(configExtra, feeConfig, acp224FeeConfig, parent.Header(), time) + baseFee, _ := customheader.BaseFee(configExtra, feeConfig, parent.Header(), time) header := &types.Header{ ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), @@ -409,7 +405,11 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr cumulativeGas += tx.Gas() nBlobs += len(tx.BlobHashes()) } - header.Extra, _ = customheader.ExtraPrefix(configExtra, parent.Header(), header, nil) + acp224FeeConfig, _, err := fakeChainReader.GetACP224FeeConfigAt(parent.Header()) + if err != nil { + panic(err) + } + header.Extra, _ = customheader.ExtraPrefix(configExtra, acp224FeeConfig, parent.Header(), header, nil) header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { var pExcess, pUsed = uint64(0), uint64(0) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 7c56632110..bc76282455 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -417,15 +417,9 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres p.Close() return err } - acp224FeeConfig, _, err := p.chain.GetACP224FeeConfigAt(p.head) - if err != nil { - p.Close() - return err - } baseFee, err := header.EstimateNextBaseFee( params.GetExtra(p.chain.Config()), feeConfig, - acp224FeeConfig, p.head, uint64(time.Now().Unix()), ) @@ -859,15 +853,9 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) { log.Error("Failed to get fee config to reset blobpool fees", "err", err) return } - acp224FeeConfig, _, err := p.chain.GetACP224FeeConfigAt(p.head) - if err != nil { - log.Error("Failed to get ACP224 fee config to reset blobpool fees", "err", err) - return - } baseFeeBig, err := header.EstimateNextBaseFee( params.GetExtra(p.chain.Config()), feeConfig, - acp224FeeConfig, p.head, uint64(time.Now().Unix()), ) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index e3e58d7083..3c5642fed5 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -122,7 +122,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { } config := params.GetExtra(bc.config) baseFee, err := header.BaseFee( - config, config.FeeConfig, config.ACP224FeeConfig, parent, blockTime, + config, config.FeeConfig, parent, blockTime, ) if err != nil { panic(err) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 64c79e4282..14ca5de820 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1852,12 +1852,8 @@ func (pool *LegacyPool) updateBaseFeeAt(head *types.Header) error { if err != nil { return err } - acp224FeeConfig, _, err := pool.chain.GetACP224FeeConfigAt(head) - if err != nil { - return err - } chainConfig := params.GetExtra(pool.chainconfig) - baseFeeEstimate, err := header.EstimateNextBaseFee(chainConfig, feeConfig, acp224FeeConfig, head, uint64(time.Now().Unix())) + baseFeeEstimate, err := header.EstimateNextBaseFee(chainConfig, feeConfig, head, uint64(time.Now().Unix())) if err != nil { return err } diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index ff9730beb5..3bf6cf4843 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -233,10 +233,6 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) if err != nil { return nil, err } - acp224FeeConfig, _, err := oracle.backend.GetACP224FeeConfigAt(header) - if err != nil { - return nil, err - } // If the fetched block does not have a base fee, return nil as the base fee if header.BaseFee == nil { return nil, nil @@ -246,7 +242,7 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) // based on the current time and add it to the tip to estimate the // total gas price estimate. chainConfig := params.GetExtra(oracle.backend.ChainConfig()) - return customheader.EstimateNextBaseFee(chainConfig, feeConfig, acp224FeeConfig, header, oracle.clock.Unix()) + return customheader.EstimateNextBaseFee(chainConfig, feeConfig, header, oracle.clock.Unix()) } // SuggestPrice returns an estimated price for legacy transactions. diff --git a/go.mod b/go.mod index 92364d8ee3..7110e62c51 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.9 require ( github.com/VictoriaMetrics/fastcache v1.12.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/avalanchego v1.13.6-0.20250909200034-40da9b25fb98 + github.com/ava-labs/avalanchego v1.13.6-0.20250909214751-efec0dce8364 github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 github.com/ava-labs/libevm v1.13.14-0.3.0.rc.6 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index 121faeda3b..724bdc783d 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/avalanchego v1.13.6-0.20250909200034-40da9b25fb98 h1:bWGubmWZ9nt351Qtllc0yHQu3VxmQpdE3kRWh75vj9w= -github.com/ava-labs/avalanchego v1.13.6-0.20250909200034-40da9b25fb98/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= +github.com/ava-labs/avalanchego v1.13.6-0.20250909214751-efec0dce8364 h1:5X5HCLEZM1tceK13bUYymVcKGsV44FTvye7E9nOPHrM= +github.com/ava-labs/avalanchego v1.13.6-0.20250909214751-efec0dce8364/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= github.com/ava-labs/coreth v0.15.4-rc.3 h1:v33OOerxpGIKa1MpljXMBB3Yljy23xzsez3E/dn7TzY= github.com/ava-labs/coreth v0.15.4-rc.3/go.mod h1:Esb0FK+KJr6co7rrhtBWsmSMXEL5JWelEsijlqAHdq0= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 h1:aMcrLbpJ/dyu2kZDf/Di/4JIWsUcYPyTDKymiHpejt0= diff --git a/miner/worker.go b/miner/worker.go index f9c9d7e6f0..1000522ae1 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -154,16 +154,12 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte if err != nil { return nil, err } - acp224FeeConfig, _, err := w.chain.GetACP224FeeConfigAt(parent) - if err != nil { - return nil, err - } chainConfig := params.GetExtra(w.chainConfig) gasLimit, err := customheader.GasLimit(chainConfig, feeConfig, parent, timestamp) if err != nil { return nil, fmt.Errorf("calculating new gas limit: %w", err) } - baseFee, err := customheader.BaseFee(chainConfig, feeConfig, acp224FeeConfig, parent, timestamp) + baseFee, err := customheader.BaseFee(chainConfig, feeConfig, parent, timestamp) if err != nil { return nil, fmt.Errorf("failed to calculate new base fee: %w", err) } diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index 6362a919a2..4676618832 100644 --- a/plugin/evm/header/base_fee.go +++ b/plugin/evm/header/base_fee.go @@ -23,7 +23,6 @@ var errEstimateBaseFeeWithoutActivation = errors.New("cannot estimate base fee f func BaseFee( config *extras.ChainConfig, feeConfig commontype.FeeConfig, - acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, timestamp uint64, ) (*big.Int, error) { @@ -55,7 +54,6 @@ func BaseFee( func EstimateNextBaseFee( config *extras.ChainConfig, feeConfig commontype.FeeConfig, - acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, timestamp uint64, ) (*big.Int, error) { @@ -64,5 +62,5 @@ func EstimateNextBaseFee( } timestamp = max(timestamp, parent.Time, *config.SubnetEVMTimestamp) - return BaseFee(config, feeConfig, acp224FeeConfig, parent, timestamp) + return BaseFee(config, feeConfig, parent, timestamp) } diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index 84b02e4557..26ad59a2b0 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -25,14 +25,14 @@ const ( func TestBaseFee(t *testing.T) { t.Run("normal", func(t *testing.T) { - BaseFeeTest(t, testFeeConfig, testACP224FeeConfig) + BaseFeeTest(t, testFeeConfig) }) t.Run("double", func(t *testing.T) { - BaseFeeTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) + BaseFeeTest(t, testFeeConfigDouble) }) } -func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { +func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { tests := []struct { name string upgrades extras.NetworkUpgrades @@ -257,7 +257,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig c config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := BaseFee(config, feeConfig, acp224FeeConfig, test.parent, test.timestamp) + got, err := BaseFee(config, feeConfig, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) @@ -269,14 +269,14 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig c func TestEstimateNextBaseFee(t *testing.T) { t.Run("normal", func(t *testing.T) { - EstimateNextBaseFeeTest(t, testFeeConfig, testACP224FeeConfig) + EstimateNextBaseFeeTest(t, testFeeConfig) }) t.Run("double", func(t *testing.T) { - EstimateNextBaseFeeTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) + EstimateNextBaseFeeTest(t, testFeeConfigDouble) }) } -func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { +func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { testBaseFee := uint64(225 * utils.GWei) nilUpgrade := extras.NetworkUpgrades{} tests := []struct { @@ -323,7 +323,7 @@ func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp22 config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := EstimateNextBaseFee(config, feeConfig, acp224FeeConfig, test.parent, test.timestamp) + got, err := EstimateNextBaseFee(config, feeConfig, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) diff --git a/plugin/evm/header/block_gas_cost.go b/plugin/evm/header/block_gas_cost.go index 17e3bb0140..023ed05b0e 100644 --- a/plugin/evm/header/block_gas_cost.go +++ b/plugin/evm/header/block_gas_cost.go @@ -28,7 +28,6 @@ var ( func BlockGasCost( config *extras.ChainConfig, feeConfig commontype.FeeConfig, - acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, timestamp uint64, ) *big.Int { diff --git a/plugin/evm/header/block_gas_cost_test.go b/plugin/evm/header/block_gas_cost_test.go index 6c57375b6e..c0e31d3873 100644 --- a/plugin/evm/header/block_gas_cost_test.go +++ b/plugin/evm/header/block_gas_cost_test.go @@ -120,7 +120,6 @@ func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeCon assert.Equal(t, test.expected, BlockGasCost( config, feeConfig, - acp224FeeConfig, parent, test.timestamp, )) diff --git a/plugin/evm/header/dynamic_fee_state.go b/plugin/evm/header/dynamic_fee_state.go index 5c2b1372c3..d052c5ff0f 100644 --- a/plugin/evm/header/dynamic_fee_state.go +++ b/plugin/evm/header/dynamic_fee_state.go @@ -10,7 +10,9 @@ import ( "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/params/extras" + "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" ) // feeStateBeforeBlock takes the previous header and the timestamp of its child @@ -49,6 +51,7 @@ func feeStateBeforeBlock( // the execution of the provided child. func feeStateAfterBlock( config *extras.ChainConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, desiredTargetExcess *gas.Gas, @@ -65,9 +68,17 @@ func feeStateAfterBlock( return acp176.State{}, fmt.Errorf("advancing the fee state: %w", err) } - // If the desired target excess is specified, move the target excess as much + // If the ACP224 fee manager precompile is activated, override the target excess with the + // latest value set in the precompile state. + // Otherwise, if the desired target excess is specified, move the target excess as much // as possible toward that desired value. - if desiredTargetExcess != nil { + if config.IsPrecompileEnabled(acp224feemanager.ContractAddress, header.Time) { + if acp224FeeConfig.TargetGas == nil || acp224FeeConfig.TargetGas.Cmp(common.Big0) == 0 || !acp224FeeConfig.TargetGas.IsInt64() { + return acp176.State{}, fmt.Errorf("invalid target gas: %s", acp224FeeConfig.TargetGas.String()) + } + newTargetExcess := acp176.DesiredTargetExcess(gas.Gas(acp224FeeConfig.TargetGas.Uint64())) + state.UpdateTargetExcessUnbounded(newTargetExcess) + } else if desiredTargetExcess != nil { state.UpdateTargetExcess(*desiredTargetExcess) } return state, nil diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index ff2a00e4a2..bb919bc82c 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -12,8 +12,10 @@ import ( "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/upgrade/subnetevm" + "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" ) const ( @@ -32,6 +34,7 @@ var ( // If the `desiredTargetExcess` is nil, the parent's target excess is used. func ExtraPrefix( config *extras.ChainConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, desiredTargetExcess *gas.Gas, @@ -40,6 +43,7 @@ func ExtraPrefix( case config.IsFortuna(header.Time): state, err := feeStateAfterBlock( config, + acp224FeeConfig, parent, header, desiredTargetExcess, @@ -47,6 +51,11 @@ func ExtraPrefix( if err != nil { return nil, fmt.Errorf("calculating fee state: %w", err) } + + // If the ACP224 fee manager precompile is activated, override the target excess with the + // latest value set in the precompile state. + config.IsPrecompileEnabled(acp224feemanager.ContractAddress, header.Time) + return state.Bytes(), nil case config.IsSubnetEVM(header.Time): window, err := feeWindow(config, parent, header.Time) @@ -64,6 +73,7 @@ func ExtraPrefix( // formatted. func VerifyExtraPrefix( config *extras.ChainConfig, + acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, ) error { @@ -81,6 +91,7 @@ func VerifyExtraPrefix( // not be equal. expectedState, err := feeStateAfterBlock( config, + acp224FeeConfig, parent, header, &remoteState.TargetExcess, diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index 1167f9d656..b3032d1ade 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -58,7 +58,6 @@ func GasLimit( func VerifyGasUsed( config *extras.ChainConfig, feeConfig commontype.FeeConfig, - acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, ) error { @@ -81,7 +80,6 @@ func VerifyGasUsed( func VerifyGasLimit( config *extras.ChainConfig, feeConfig commontype.FeeConfig, - acp224FeeConfig commontype.ACP224FeeConfig, parent *types.Header, header *types.Header, ) error { diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index 47d2a9c2cc..d563a00058 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -141,7 +141,7 @@ func TestVerifyGasUsed(t *testing.T) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - err := VerifyGasUsed(config, test.feeConfig, test.acp224FeeConfig, test.parent, test.header) + err := VerifyGasUsed(config, test.feeConfig, test.parent, test.header) require.ErrorIs(t, err, test.want) }) } @@ -149,14 +149,14 @@ func TestVerifyGasUsed(t *testing.T) { func TestVerifyGasLimit(t *testing.T) { t.Run("normal", func(t *testing.T) { - VerifyGasLimitTest(t, testFeeConfig, testACP224FeeConfig) + VerifyGasLimitTest(t, testFeeConfig) }) t.Run("double", func(t *testing.T) { - VerifyGasLimitTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) + VerifyGasLimitTest(t, testFeeConfigDouble) }) } -func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { +func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { tests := []struct { name string upgrades extras.NetworkUpgrades @@ -258,7 +258,7 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeC config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - err := VerifyGasLimit(config, feeConfig, acp224FeeConfig, test.parent, test.header) + err := VerifyGasLimit(config, feeConfig, test.parent, test.header) require.ErrorIs(t, err, test.want) }) } diff --git a/precompile/precompileconfig/mocks.go b/precompile/precompileconfig/mocks.go index 41f8a16fa4..91ef9b88f0 100644 --- a/precompile/precompileconfig/mocks.go +++ b/precompile/precompileconfig/mocks.go @@ -203,6 +203,20 @@ func (mr *MockChainConfigMockRecorder) AllowedFeeRecipients() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllowedFeeRecipients", reflect.TypeOf((*MockChainConfig)(nil).AllowedFeeRecipients)) } +// GetACP224FeeConfig mocks base method. +func (m *MockChainConfig) GetACP224FeeConfig() commontype.ACP224FeeConfig { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetACP224FeeConfig") + ret0, _ := ret[0].(commontype.ACP224FeeConfig) + return ret0 +} + +// GetACP224FeeConfig indicates an expected call of GetACP224FeeConfig. +func (mr *MockChainConfigMockRecorder) GetACP224FeeConfig() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetACP224FeeConfig", reflect.TypeOf((*MockChainConfig)(nil).GetACP224FeeConfig)) +} + // GetFeeConfig mocks base method. func (m *MockChainConfig) GetFeeConfig() commontype.FeeConfig { m.ctrl.T.Helper() From 801070f4bdceed86f1e88aed237829be8029369a Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Wed, 10 Sep 2025 18:22:06 -0400 Subject: [PATCH 5/8] Pipe through ACP-176 configs --- IACP224FeeManager.abi | 8 +-- cmd/evm/internal/t8ntool/transition.go | 3 +- commontype/fee_config.go | 45 +++++++++++---- consensus/dummy/consensus.go | 14 +++-- .../interfaces/IACP224FeeManager.sol | 2 +- core/chain_makers.go | 12 +++- core/state_processor_test.go | 20 ++++--- core/txpool/blobpool/blobpool.go | 22 ++++++++ core/txpool/blobpool/blobpool_test.go | 6 +- core/txpool/legacypool/legacypool.go | 10 +++- core/txpool/legacypool/legacypool_test.go | 10 ++-- eth/gasprice/gasprice.go | 10 +++- ethclient/simulated/options_test.go | 4 +- go.mod | 3 +- go.sum | 8 ++- miner/worker.go | 26 +++++++-- params/extras/config.go | 8 +-- plugin/evm/header/base_fee.go | 9 ++- plugin/evm/header/base_fee_test.go | 20 +++---- plugin/evm/header/block_gas_cost_test.go | 23 +++++--- plugin/evm/header/dynamic_fee_state.go | 16 ++++-- plugin/evm/header/extra.go | 5 -- plugin/evm/header/extra_test.go | 4 +- plugin/evm/header/gas_limit.go | 25 +++++---- plugin/evm/header/gas_limit_test.go | 55 ++++++++++--------- plugin/evm/vm.go | 17 ++++-- .../contracts/acp224feemanager/config_test.go | 2 +- .../contracts/acp224feemanager/contract.abi | 8 +-- .../contracts/acp224feemanager/contract.go | 10 ++-- .../contracts/acp224feemanager/module.go | 1 + 30 files changed, 266 insertions(+), 140 deletions(-) diff --git a/IACP224FeeManager.abi b/IACP224FeeManager.abi index 2154805e5d..c605eb142a 100644 --- a/IACP224FeeManager.abi +++ b/IACP224FeeManager.abi @@ -22,7 +22,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { @@ -50,7 +50,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { @@ -117,7 +117,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { @@ -208,7 +208,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 44d5f62e58..d6a5187eac 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -35,6 +35,7 @@ import ( "os" "path" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/common/hexutil" "github.com/ava-labs/libevm/core/state" @@ -232,7 +233,7 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { } configExtra := params.GetExtra(chainConfig) var err error - env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, parent, env.Timestamp) + env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, acp176.DefaultACP176Config, parent, env.Timestamp) if err != nil { return NewError(ErrorConfig, fmt.Errorf("failed calculating base fee: %v", err)) } diff --git a/commontype/fee_config.go b/commontype/fee_config.go index 35f4cf94fa..80a6844822 100644 --- a/commontype/fee_config.go +++ b/commontype/fee_config.go @@ -8,16 +8,17 @@ import ( "fmt" "math/big" + "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" - "github.com/ava-labs/subnet-evm/utils" ) type ACP224FeeConfig struct { - TargetGas *big.Int `json:"targetGas,omitempty"` - MinGasPrice *big.Int `json:"minGasPrice,omitempty"` - MaxCapacityFactor *big.Int `json:"maxCapacityFactor,omitempty"` - TimeToDouble *big.Int `json:"timeToDouble,omitempty"` + TargetGas *big.Int `json:"targetGas,omitempty"` + MinGasPrice *big.Int `json:"minGasPrice,omitempty"` + TimeToFillCapacity *big.Int `json:"timeToFillCapacity,omitempty"` + TimeToDouble *big.Int `json:"timeToDouble,omitempty"` } // represents an empty ACP-224 fee config without any field @@ -29,8 +30,8 @@ func (f *ACP224FeeConfig) Verify() error { return errors.New("targetGas cannot be nil") case f.MinGasPrice == nil: return errors.New("minGasPrice cannot be nil") - case f.MaxCapacityFactor == nil: - return errors.New("maxCapacityFactor cannot be nil") + case f.TimeToFillCapacity == nil: + return errors.New("timeToFillCapacity cannot be nil") case f.TimeToDouble == nil: return errors.New("timeToDouble cannot be nil") } @@ -40,11 +41,18 @@ func (f *ACP224FeeConfig) Verify() error { return fmt.Errorf("targetGas = %d cannot be less than or equal to 0", f.TargetGas) case f.MinGasPrice.Cmp(common.Big0) != 1: return fmt.Errorf("minGasPrice = %d cannot be less than or equal to 0", f.MinGasPrice) - case f.MaxCapacityFactor.Cmp(common.Big0) == -1: - return fmt.Errorf("maxCapacityFactor = %d cannot be less than 0", f.MaxCapacityFactor) + case f.TimeToFillCapacity.Cmp(common.Big0) == -1: + return fmt.Errorf("timeToFillCapacity = %d cannot be less than 0", f.TimeToFillCapacity) case f.TimeToDouble.Cmp(common.Big0) == -1: return fmt.Errorf("timeToDouble = %d cannot be less than 0", f.TimeToDouble) } + + switch { + case f.TimeToFillCapacity.Cmp(big.NewInt(acp176.MaxTimeToFillCapacity)) == 1: + return fmt.Errorf("timeToFillCapacity = %d cannot be greater than %d", f.TimeToFillCapacity, acp176.MaxTimeToFillCapacity) + case f.TimeToDouble.Cmp(big.NewInt(acp176.MaxTimeToDouble)) == 1: + return fmt.Errorf("timeToDouble = %d cannot be greater than %d", f.TimeToDouble, acp176.MaxTimeToDouble) + } return f.checkByteLens() } @@ -55,10 +63,23 @@ func (f *ACP224FeeConfig) Equal(other *ACP224FeeConfig) bool { return utils.BigNumEqual(f.TargetGas, other.TargetGas) && utils.BigNumEqual(f.MinGasPrice, other.MinGasPrice) && - utils.BigNumEqual(f.MaxCapacityFactor, other.MaxCapacityFactor) && + utils.BigNumEqual(f.TimeToFillCapacity, other.TimeToFillCapacity) && utils.BigNumEqual(f.TimeToDouble, other.TimeToDouble) } +func (f *ACP224FeeConfig) ToACP176Config() (acp176.Config, error) { + if err := f.Verify(); err != nil { + return acp176.Config{}, err + } + + config := acp176.Config{ + MinGasPrice: gas.Price(f.MinGasPrice.Uint64()), + TimeToFillCapacity: gas.Gas(f.TimeToFillCapacity.Uint64()), + TimeToDouble: f.TimeToDouble.Uint64(), + } + return config, config.Verify() +} + // checkByteLens checks byte lengths against common.HashLen (32 bytes) and returns error func (f *ACP224FeeConfig) checkByteLens() error { if isBiggerThanHashLen(f.TargetGas) { @@ -67,8 +88,8 @@ func (f *ACP224FeeConfig) checkByteLens() error { if isBiggerThanHashLen(f.MinGasPrice) { return fmt.Errorf("minGasPrice exceeds %d bytes", common.HashLength) } - if isBiggerThanHashLen(f.MaxCapacityFactor) { - return fmt.Errorf("maxCapacityFactor exceeds %d bytes", common.HashLength) + if isBiggerThanHashLen(f.TimeToFillCapacity) { + return fmt.Errorf("timeToFillCapacity exceeds %d bytes", common.HashLength) } if isBiggerThanHashLen(f.TimeToDouble) { return fmt.Errorf("timeToDouble exceeds %d bytes", common.HashLength) diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index fd021d10c9..851433b478 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -148,15 +148,19 @@ func verifyHeaderGasFields( return err } - if err := customheader.VerifyGasUsed(config, feeConfig, parent, header); err != nil { + acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) + if err != nil { return err } - if err := customheader.VerifyGasLimit(config, feeConfig, parent, header); err != nil { + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { return err } - acp224FeeConfig, _, err := chain.GetACP224FeeConfigAt(parent) - if err != nil { + if err := customheader.VerifyGasUsed(config, feeConfig, acp176Config, parent, header); err != nil { + return err + } + if err := customheader.VerifyGasLimit(config, feeConfig, acp176Config, parent, header); err != nil { return err } @@ -165,7 +169,7 @@ func verifyHeaderGasFields( } // Verify header.BaseFee matches the expected value. - expectedBaseFee, err := customheader.BaseFee(config, feeConfig, parent, header.Time) + expectedBaseFee, err := customheader.BaseFee(config, feeConfig, acp176Config, parent, header.Time) if err != nil { return fmt.Errorf("failed to calculate base fee: %w", err) } diff --git a/contracts/contracts/interfaces/IACP224FeeManager.sol b/contracts/contracts/interfaces/IACP224FeeManager.sol index adcae69cdf..bd3a122fe2 100644 --- a/contracts/contracts/interfaces/IACP224FeeManager.sol +++ b/contracts/contracts/interfaces/IACP224FeeManager.sol @@ -11,7 +11,7 @@ interface IACP224FeeManager is IAllowList { struct FeeConfig { uint256 targetGas; // Target gas consumption per second uint256 minGasPrice; // Minimum gas price in wei - uint256 maxCapacityFactor; // Maximum capacity factor (C = factor * T) + uint256 timeToFillCapacity; // Maximum capacity factor (C = factor * T) uint256 timeToDouble; // Time in seconds for gas price to double at max capacity } diff --git a/core/chain_makers.go b/core/chain_makers.go index 36c97381c5..b797928ab4 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -383,12 +383,20 @@ func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.S if err != nil { panic(err) } + acp224FeeConfig, _, err := cm.GetACP224FeeConfigAt(parent.Header()) + if err != nil { + panic(err) + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + panic(err) + } config := params.GetExtra(cm.config) - gasLimit, err := header.GasLimit(config, feeConfig, parent.Header(), time) + gasLimit, err := header.GasLimit(config, feeConfig, acp176Config, parent.Header(), time) if err != nil { panic(err) } - baseFee, err := header.BaseFee(config, feeConfig, parent.Header(), time) + baseFee, err := header.BaseFee(config, feeConfig, acp176Config, parent.Header(), time) if err != nil { panic(err) } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 27a614f754..31a6e29784 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -156,7 +156,7 @@ func TestStateProcessorErrors(t *testing.T) { { // ErrGasLimitReached txs: []*types.Transaction{ // This test was modified to account for ACP-176 gas limits - makeTx(key1, 0, common.Address{}, big.NewInt(0), acp176.MinMaxCapacity+1, big.NewInt(acp176.MinGasPrice), nil), + makeTx(key1, 0, common.Address{}, big.NewInt(0), uint64(acp176.DefaultACP176Config.MinMaxCapacity()+1), big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), nil), }, want: "could not apply tx 0 [0x6c95e59678246e8b44a1d9382a9cc6589684298b32b7aaf640e8b6fc75ce3dfc]: gas limit reached", }, @@ -185,7 +185,7 @@ func TestStateProcessorErrors(t *testing.T) { { // ErrGasLimitReached txs: []*types.Transaction{ // This test was modified to account for ACP-176 gas limits - makeTx(key1, 0, common.Address{}, big.NewInt(0), ethparams.TxGas*953, big.NewInt(acp176.MinGasPrice), nil), + makeTx(key1, 0, common.Address{}, big.NewInt(0), ethparams.TxGas*953, big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), nil), }, want: "could not apply tx 0 [0xcd46718c1af6fd074deb6b036d34c1cb499517bf90d93df74dcfaba25fdf34af]: gas limit reached", }, @@ -365,9 +365,17 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr if err != nil { panic(err) } + acp224FeeConfig, _, err := fakeChainReader.GetACP224FeeConfigAt(parent.Header()) + if err != nil { + panic(err) + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + panic(err) + } configExtra := params.GetExtra(config) - gasLimit, _ := customheader.GasLimit(configExtra, feeConfig, parent.Header(), time) - baseFee, _ := customheader.BaseFee(configExtra, feeConfig, parent.Header(), time) + gasLimit, _ := customheader.GasLimit(configExtra, feeConfig, acp176Config, parent.Header(), time) + baseFee, _ := customheader.BaseFee(configExtra, feeConfig, acp176Config, parent.Header(), time) header := &types.Header{ ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), @@ -405,10 +413,6 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr cumulativeGas += tx.Gas() nBlobs += len(tx.BlobHashes()) } - acp224FeeConfig, _, err := fakeChainReader.GetACP224FeeConfigAt(parent.Header()) - if err != nil { - panic(err) - } header.Extra, _ = customheader.ExtraPrefix(configExtra, acp224FeeConfig, parent.Header(), header, nil) header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index bc76282455..4b300d2b4b 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -417,9 +417,20 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres p.Close() return err } + acp224FeeConfig, _, err := p.chain.GetACP224FeeConfigAt(p.head) + if err != nil { + p.Close() + return err + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + p.Close() + return err + } baseFee, err := header.EstimateNextBaseFee( params.GetExtra(p.chain.Config()), feeConfig, + acp176Config, p.head, uint64(time.Now().Unix()), ) @@ -853,9 +864,20 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) { log.Error("Failed to get fee config to reset blobpool fees", "err", err) return } + acp224FeeConfig, _, err := p.chain.GetACP224FeeConfigAt(p.head) + if err != nil { + log.Error("Failed to get ACP224 fee config to reset blobpool fees", "err", err) + return + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + log.Error("Failed to convert ACP224 fee config to ACP176 config to reset blobpool fees", "err", err) + return + } baseFeeBig, err := header.EstimateNextBaseFee( params.GetExtra(p.chain.Config()), feeConfig, + acp176Config, p.head, uint64(time.Now().Unix()), ) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 3c5642fed5..1d9e90f9be 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -121,8 +121,12 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { Extra: make([]byte, subnetevm.WindowSize), } config := params.GetExtra(bc.config) + acp176Config, err := config.ACP224FeeConfig.ToACP176Config() + if err != nil { + panic(err) + } baseFee, err := header.BaseFee( - config, config.FeeConfig, parent, blockTime, + config, config.FeeConfig, acp176Config, parent, blockTime, ) if err != nil { panic(err) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 14ca5de820..1c88bda16e 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1852,8 +1852,16 @@ func (pool *LegacyPool) updateBaseFeeAt(head *types.Header) error { if err != nil { return err } + acp224FeeConfig, _, err := pool.chain.GetACP224FeeConfigAt(head) + if err != nil { + return err + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + return err + } chainConfig := params.GetExtra(pool.chainconfig) - baseFeeEstimate, err := header.EstimateNextBaseFee(chainConfig, feeConfig, head, uint64(time.Now().Unix())) + baseFeeEstimate, err := header.EstimateNextBaseFee(chainConfig, feeConfig, acp176Config, head, uint64(time.Now().Unix())) if err != nil { return err } diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index c0af0e0591..04ebfd54ed 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -40,6 +40,7 @@ import ( "testing" "time" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/core/state" @@ -76,11 +77,12 @@ var ( } testACP224FeeConfig = commontype.ACP224FeeConfig{ - TargetGas: big.NewInt(1_000_000), - MinGasPrice: big.NewInt(1), - MaxCapacityFactor: big.NewInt(5), - TimeToDouble: big.NewInt(60), + TargetGas: big.NewInt(1_000_000), + MinGasPrice: big.NewInt(1), + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), } + testACP176Config = acp176.DefaultACP176Config ) func init() { diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 3bf6cf4843..89d8a6933e 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -233,6 +233,14 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) if err != nil { return nil, err } + acp224FeeConfig, _, err := oracle.backend.GetACP224FeeConfigAt(header) + if err != nil { + return nil, err + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + return nil, err + } // If the fetched block does not have a base fee, return nil as the base fee if header.BaseFee == nil { return nil, nil @@ -242,7 +250,7 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) // based on the current time and add it to the tip to estimate the // total gas price estimate. chainConfig := params.GetExtra(oracle.backend.ChainConfig()) - return customheader.EstimateNextBaseFee(chainConfig, feeConfig, header, oracle.clock.Unix()) + return customheader.EstimateNextBaseFee(chainConfig, feeConfig, acp176Config, header, oracle.clock.Unix()) } // SuggestPrice returns an estimated price for legacy transactions. diff --git a/ethclient/simulated/options_test.go b/ethclient/simulated/options_test.go index 14d9b35b66..e27aff7fd3 100644 --- a/ethclient/simulated/options_test.go +++ b/ethclient/simulated/options_test.go @@ -61,8 +61,8 @@ func TestWithBlockGasLimitOption(t *testing.T) { if err != nil { t.Fatalf("failed to retrieve head block: %v", err) } - if head.GasLimit() != acp176.MinMaxCapacity { - t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), acp176.MinMaxCapacity) + if head.GasLimit() != uint64(acp176.DefaultACP176Config.MinMaxCapacity()) { + t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), acp176.DefaultACP176Config.MinMaxCapacity()) } } diff --git a/go.mod b/go.mod index 7110e62c51..5d090b1a08 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.9 require ( github.com/VictoriaMetrics/fastcache v1.12.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/avalanchego v1.13.6-0.20250909214751-efec0dce8364 + github.com/ava-labs/avalanchego v1.13.6-0.20250910213146-23a113adc559 github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 github.com/ava-labs/libevm v1.13.14-0.3.0.rc.6 github.com/davecgh/go-spew v1.1.1 @@ -72,6 +72,7 @@ require ( github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect diff --git a/go.sum b/go.sum index 724bdc783d..c854458856 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,10 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/avalanchego v1.13.6-0.20250909214751-efec0dce8364 h1:5X5HCLEZM1tceK13bUYymVcKGsV44FTvye7E9nOPHrM= -github.com/ava-labs/avalanchego v1.13.6-0.20250909214751-efec0dce8364/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= +github.com/ava-labs/avalanchego v1.13.6-0.20250910212054-5218d21143f6 h1:XgNP58BY2FmaQGiPMzE2YxgqimCJljQuvkGoZtUgjoY= +github.com/ava-labs/avalanchego v1.13.6-0.20250910212054-5218d21143f6/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= +github.com/ava-labs/avalanchego v1.13.6-0.20250910213146-23a113adc559 h1:dB4T5OC3uOteDnsHRheNXsS/U+QuTn/vDDYiEfuGsOg= +github.com/ava-labs/avalanchego v1.13.6-0.20250910213146-23a113adc559/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= github.com/ava-labs/coreth v0.15.4-rc.3 h1:v33OOerxpGIKa1MpljXMBB3Yljy23xzsez3E/dn7TzY= github.com/ava-labs/coreth v0.15.4-rc.3/go.mod h1:Esb0FK+KJr6co7rrhtBWsmSMXEL5JWelEsijlqAHdq0= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 h1:aMcrLbpJ/dyu2kZDf/Di/4JIWsUcYPyTDKymiHpejt0= @@ -151,6 +153,8 @@ github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHE github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fjl/gencodec v0.1.1 h1:DhQY29Q6JLXB/GgMqE86NbOEuvckiYcJCbXFu02toms= github.com/fjl/gencodec v0.1.1/go.mod h1:chDHL3wKXuBgauP8x3XNZkl5EIAR5SoCTmmmDTZRzmw= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= diff --git a/miner/worker.go b/miner/worker.go index 1000522ae1..edd2d3d81f 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -40,6 +40,7 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/evm/predicate" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/state" "github.com/ava-labs/libevm/core/types" @@ -154,12 +155,20 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte if err != nil { return nil, err } + acp224FeeConfig, _, err := w.chain.GetACP224FeeConfigAt(parent) + if err != nil { + return nil, err + } + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + return nil, err + } chainConfig := params.GetExtra(w.chainConfig) - gasLimit, err := customheader.GasLimit(chainConfig, feeConfig, parent, timestamp) + gasLimit, err := customheader.GasLimit(chainConfig, feeConfig, acp176Config, parent, timestamp) if err != nil { return nil, fmt.Errorf("calculating new gas limit: %w", err) } - baseFee, err := customheader.BaseFee(chainConfig, feeConfig, parent, timestamp) + baseFee, err := customheader.BaseFee(chainConfig, feeConfig, acp176Config, parent, timestamp) if err != nil { return nil, fmt.Errorf("failed to calculate new base fee: %w", err) } @@ -208,7 +217,7 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte return nil, fmt.Errorf("failed to prepare header for mining: %w", err) } - env, err := w.createCurrentEnvironment(predicateContext, parent, header, feeConfig, tstart) + env, err := w.createCurrentEnvironment(predicateContext, parent, header, feeConfig, acp176Config, tstart) if err != nil { return nil, fmt.Errorf("failed to create new current environment: %w", err) } @@ -279,13 +288,20 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte return w.commit(env) } -func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.PredicateContext, parent *types.Header, header *types.Header, feeConfig commontype.FeeConfig, tstart time.Time) (*environment, error) { +func (w *worker) createCurrentEnvironment( + predicateContext *precompileconfig.PredicateContext, + parent *types.Header, + header *types.Header, + feeConfig commontype.FeeConfig, + acp176Config acp176.Config, + tstart time.Time, +) (*environment, error) { currentState, err := w.chain.StateAt(parent.Root) if err != nil { return nil, err } chainConfig := params.GetExtra(w.chainConfig) - capacity, err := customheader.GasCapacity(chainConfig, feeConfig, parent, header.Time) + capacity, err := customheader.GasCapacity(chainConfig, feeConfig, acp176Config, parent, header.Time) if err != nil { return nil, fmt.Errorf("calculating gas capacity: %w", err) } diff --git a/params/extras/config.go b/params/extras/config.go index 08224164b6..1765379e03 100644 --- a/params/extras/config.go +++ b/params/extras/config.go @@ -34,10 +34,10 @@ var ( } DefaultACP224FeeConfig = commontype.ACP224FeeConfig{ - TargetGas: big.NewInt(1_000_000), - MinGasPrice: big.NewInt(1), - MaxCapacityFactor: big.NewInt(5), - TimeToDouble: big.NewInt(60), + TargetGas: big.NewInt(1_000_000), + MinGasPrice: big.NewInt(1), + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), } SubnetEVMDefaultChainConfig = &ChainConfig{ diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index 4676618832..12ab6dc38a 100644 --- a/plugin/evm/header/base_fee.go +++ b/plugin/evm/header/base_fee.go @@ -8,6 +8,7 @@ import ( "fmt" "math/big" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/subnet-evm/commontype" @@ -23,17 +24,18 @@ var errEstimateBaseFeeWithoutActivation = errors.New("cannot estimate base fee f func BaseFee( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp176Config acp176.Config, parent *types.Header, timestamp uint64, ) (*big.Int, error) { // TODO: XXX Handle feeConfig with Fortuna here switch { case config.IsFortuna(timestamp): - state, err := feeStateBeforeBlock(config, parent, timestamp) + state, err := feeStateBeforeBlock(config, acp176Config, parent, timestamp) if err != nil { return nil, fmt.Errorf("calculating initial fee state: %w", err) } - price := state.GasPrice() + price := state.GasPrice(acp176Config) return new(big.Int).SetUint64(uint64(price)), nil case config.IsSubnetEVM(timestamp): return baseFeeFromWindow(config, feeConfig, parent, timestamp) @@ -54,6 +56,7 @@ func BaseFee( func EstimateNextBaseFee( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp176Config acp176.Config, parent *types.Header, timestamp uint64, ) (*big.Int, error) { @@ -62,5 +65,5 @@ func EstimateNextBaseFee( } timestamp = max(timestamp, parent.Time, *config.SubnetEVMTimestamp) - return BaseFee(config, feeConfig, parent, timestamp) + return BaseFee(config, feeConfig, acp176Config, parent, timestamp) } diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index 26ad59a2b0..0f014bd154 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -25,14 +25,14 @@ const ( func TestBaseFee(t *testing.T) { t.Run("normal", func(t *testing.T) { - BaseFeeTest(t, testFeeConfig) + BaseFeeTest(t, testFeeConfig, testACP176Config) }) t.Run("double", func(t *testing.T) { - BaseFeeTest(t, testFeeConfigDouble) + BaseFeeTest(t, testFeeConfigDouble, testACP176ConfigDouble) }) } -func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { +func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp176.Config) { tests := []struct { name string upgrades extras.NetworkUpgrades @@ -201,7 +201,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { Number: big.NewInt(1), }, timestamp: 1, - want: big.NewInt(acp176.MinGasPrice), + want: big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), }, { name: "fortuna_genesis_block", @@ -209,7 +209,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { parent: &types.Header{ Number: big.NewInt(0), }, - want: big.NewInt(acp176.MinGasPrice), + want: big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), }, { name: "fortuna_invalid_fee_state", @@ -257,7 +257,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := BaseFee(config, feeConfig, test.parent, test.timestamp) + got, err := BaseFee(config, feeConfig, acp176Config, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) @@ -269,14 +269,14 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { func TestEstimateNextBaseFee(t *testing.T) { t.Run("normal", func(t *testing.T) { - EstimateNextBaseFeeTest(t, testFeeConfig) + EstimateNextBaseFeeTest(t, testFeeConfig, testACP176Config) }) t.Run("double", func(t *testing.T) { - EstimateNextBaseFeeTest(t, testFeeConfigDouble) + EstimateNextBaseFeeTest(t, testFeeConfigDouble, testACP176ConfigDouble) }) } -func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { +func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp176.Config) { testBaseFee := uint64(225 * utils.GWei) nilUpgrade := extras.NetworkUpgrades{} tests := []struct { @@ -323,7 +323,7 @@ func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := EstimateNextBaseFee(config, feeConfig, test.parent, test.timestamp) + got, err := EstimateNextBaseFee(config, feeConfig, acp176Config, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) diff --git a/plugin/evm/header/block_gas_cost_test.go b/plugin/evm/header/block_gas_cost_test.go index c0e31d3873..73e9760e37 100644 --- a/plugin/evm/header/block_gas_cost_test.go +++ b/plugin/evm/header/block_gas_cost_test.go @@ -7,6 +7,7 @@ import ( "math/big" "testing" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -29,11 +30,12 @@ var ( GasLimit: big.NewInt(12_000_000), } testACP224FeeConfig = commontype.ACP224FeeConfig{ - TargetGas: big.NewInt(1_000_000), - MinGasPrice: big.NewInt(1), - MaxCapacityFactor: big.NewInt(5), - TimeToDouble: big.NewInt(60), + TargetGas: big.NewInt(1_000_000), + MinGasPrice: big.NewInt(1), + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), } + testACP176Config = acp176.DefaultACP176Config testFeeConfigDouble = commontype.FeeConfig{ MinBlockGasCost: big.NewInt(2), @@ -46,10 +48,15 @@ var ( GasLimit: big.NewInt(24_000_000), } testACP224FeeConfigDouble = commontype.ACP224FeeConfig{ - TargetGas: big.NewInt(2_000_000), - MinGasPrice: big.NewInt(2), - MaxCapacityFactor: big.NewInt(10), - TimeToDouble: big.NewInt(120), + TargetGas: big.NewInt(2_000_000), + MinGasPrice: big.NewInt(2), + TimeToFillCapacity: big.NewInt(10), + TimeToDouble: big.NewInt(120), + } + testACP176ConfigDouble = acp176.Config{ + MinGasPrice: testACP176Config.MinGasPrice * 2, + TimeToFillCapacity: testACP176Config.TimeToFillCapacity * 2, + TimeToDouble: testACP176Config.TimeToDouble * 2, } ) diff --git a/plugin/evm/header/dynamic_fee_state.go b/plugin/evm/header/dynamic_fee_state.go index d052c5ff0f..cb29d24494 100644 --- a/plugin/evm/header/dynamic_fee_state.go +++ b/plugin/evm/header/dynamic_fee_state.go @@ -19,6 +19,7 @@ import ( // block and calculates the fee state before the child block is executed. func feeStateBeforeBlock( config *extras.ChainConfig, + acp176Config acp176.Config, parent *types.Header, timestamp uint64, ) (acp176.State, error) { @@ -43,7 +44,7 @@ func feeStateBeforeBlock( } } - state.AdvanceTime(timestamp - parent.Time) + state.AdvanceTime(timestamp-parent.Time, acp176Config) return state, nil } @@ -56,8 +57,13 @@ func feeStateAfterBlock( header *types.Header, desiredTargetExcess *gas.Gas, ) (acp176.State, error) { + acp176Config, err := acp224FeeConfig.ToACP176Config() + if err != nil { + return acp176.State{}, fmt.Errorf("converting ACP224 fee config to ACP176 config: %w", err) + } + // Calculate the gas state after the parent block - state, err := feeStateBeforeBlock(config, parent, header.Time) + state, err := feeStateBeforeBlock(config, acp176Config, parent, header.Time) if err != nil { return acp176.State{}, fmt.Errorf("calculating initial fee state: %w", err) } @@ -73,13 +79,13 @@ func feeStateAfterBlock( // Otherwise, if the desired target excess is specified, move the target excess as much // as possible toward that desired value. if config.IsPrecompileEnabled(acp224feemanager.ContractAddress, header.Time) { - if acp224FeeConfig.TargetGas == nil || acp224FeeConfig.TargetGas.Cmp(common.Big0) == 0 || !acp224FeeConfig.TargetGas.IsInt64() { + if acp224FeeConfig.TargetGas == nil || acp224FeeConfig.TargetGas.Cmp(common.Big0) == 0 || !acp224FeeConfig.TargetGas.IsUint64() { return acp176.State{}, fmt.Errorf("invalid target gas: %s", acp224FeeConfig.TargetGas.String()) } newTargetExcess := acp176.DesiredTargetExcess(gas.Gas(acp224FeeConfig.TargetGas.Uint64())) - state.UpdateTargetExcessUnbounded(newTargetExcess) + state.UpdateTargetExcessUnbounded(newTargetExcess, acp176Config) } else if desiredTargetExcess != nil { - state.UpdateTargetExcess(*desiredTargetExcess) + state.UpdateTargetExcess(*desiredTargetExcess, acp176Config) } return state, nil } diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index bb919bc82c..a5a847c3e7 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -15,7 +15,6 @@ import ( "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/plugin/evm/upgrade/subnetevm" - "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" ) const ( @@ -52,10 +51,6 @@ func ExtraPrefix( return nil, fmt.Errorf("calculating fee state: %w", err) } - // If the ACP224 fee manager precompile is activated, override the target excess with the - // latest value set in the precompile state. - config.IsPrecompileEnabled(acp224feemanager.ContractAddress, header.Time) - return state.Bytes(), nil case config.IsSubnetEVM(header.Time): window, err := feeWindow(config, parent, header.Time) diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index 259891491f..0271f31f75 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -204,7 +204,7 @@ func TestExtraPrefix(t *testing.T) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := ExtraPrefix(config, test.parent, test.header, test.desiredTargetExcess) + got, err := ExtraPrefix(config, testACP224FeeConfig, test.parent, test.header, test.desiredTargetExcess) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) @@ -316,7 +316,7 @@ func TestVerifyExtraPrefix(t *testing.T) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - err := VerifyExtraPrefix(config, test.parent, test.header) + err := VerifyExtraPrefix(config, testACP224FeeConfig, test.parent, test.header) require.ErrorIs(t, err, test.wantErr) }) } diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index b3032d1ade..a934de68b2 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/subnet-evm/commontype" @@ -17,9 +18,8 @@ import ( ) var ( - errInvalidExtraDataGasUsed = errors.New("invalid extra data gas used") - errInvalidGasUsed = errors.New("invalid gas used") - errInvalidGasLimit = errors.New("invalid gas limit") + errInvalidGasUsed = errors.New("invalid gas used") + errInvalidGasLimit = errors.New("invalid gas limit") ) // GasLimit takes the previous header and the timestamp of its child block and @@ -27,13 +27,13 @@ var ( func GasLimit( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp176Config acp176.Config, parent *types.Header, timestamp uint64, ) (uint64, error) { - // TODO: XXX Handle feeConfig with Fortuna here switch { case config.IsFortuna(timestamp): - state, err := feeStateBeforeBlock(config, parent, timestamp) + state, err := feeStateBeforeBlock(config, acp176Config, parent, timestamp) if err != nil { return 0, fmt.Errorf("calculating initial fee state: %w", err) } @@ -41,7 +41,7 @@ func GasLimit( // capacity, to minimize the differences with upstream geth. During // block building and gas usage calculations, the gas limit is checked // against the current capacity. - return uint64(state.MaxCapacity()), nil + return uint64(state.MaxCapacity(acp176Config)), nil case config.IsSubnetEVM(timestamp): return feeConfig.GasLimit.Uint64(), nil default: @@ -58,11 +58,12 @@ func GasLimit( func VerifyGasUsed( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp176Config acp176.Config, parent *types.Header, header *types.Header, ) error { gasUsed := header.GasUsed - capacity, err := GasCapacity(config, feeConfig, parent, header.Time) + capacity, err := GasCapacity(config, feeConfig, acp176Config, parent, header.Time) if err != nil { return fmt.Errorf("calculating gas capacity: %w", err) } @@ -80,16 +81,17 @@ func VerifyGasUsed( func VerifyGasLimit( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp176Config acp176.Config, parent *types.Header, header *types.Header, ) error { switch { case config.IsFortuna(header.Time): - state, err := feeStateBeforeBlock(config, parent, header.Time) + state, err := feeStateBeforeBlock(config, acp176Config, parent, header.Time) if err != nil { return fmt.Errorf("calculating initial fee state: %w", err) } - maxCapacity := state.MaxCapacity() + maxCapacity := state.MaxCapacity(acp176Config) if header.GasLimit != uint64(maxCapacity) { return fmt.Errorf("%w: have %d, want %d", errInvalidGasLimit, @@ -136,15 +138,16 @@ func VerifyGasLimit( func GasCapacity( config *extras.ChainConfig, feeConfig commontype.FeeConfig, + acp176Config acp176.Config, parent *types.Header, timestamp uint64, ) (uint64, error) { // Prior to the F upgrade, the gas capacity is equal to the gas limit. if !config.IsFortuna(timestamp) { - return GasLimit(config, feeConfig, parent, timestamp) + return GasLimit(config, feeConfig, acp176Config, parent, timestamp) } - state, err := feeStateBeforeBlock(config, parent, timestamp) + state, err := feeStateBeforeBlock(config, acp176Config, parent, timestamp) if err != nil { return 0, fmt.Errorf("calculating initial fee state: %w", err) } diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index d563a00058..680d141d5e 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -21,14 +21,14 @@ import ( func TestGasLimit(t *testing.T) { t.Run("normal", func(t *testing.T) { - GasLimitTest(t, testFeeConfig) + GasLimitTest(t, testFeeConfig, testACP176Config) }) t.Run("double", func(t *testing.T) { - GasLimitTest(t, testFeeConfigDouble) + GasLimitTest(t, testFeeConfigDouble, testACP176ConfigDouble) }) } -func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { +func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp176.Config) { tests := []struct { name string upgrades extras.NetworkUpgrades @@ -56,7 +56,7 @@ func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { parent: &types.Header{ Number: big.NewInt(0), }, - want: acp176.MinMaxCapacity, + want: uint64(acp176.DefaultACP176Config.MinMaxCapacity()), }, { name: "pre_subnet_evm", @@ -74,7 +74,7 @@ func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := GasLimit(config, feeConfig, test.parent, test.timestamp) + got, err := GasLimit(config, feeConfig, acp176Config, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) @@ -83,13 +83,13 @@ func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { func TestVerifyGasUsed(t *testing.T) { tests := []struct { - name string - feeConfig commontype.FeeConfig - acp224FeeConfig commontype.ACP224FeeConfig - upgrades extras.NetworkUpgrades - parent *types.Header - header *types.Header - want error + name string + feeConfig commontype.FeeConfig + acp176Config acp176.Config + upgrades extras.NetworkUpgrades + parent *types.Header + header *types.Header + want error }{ { name: "fortuna_gas_used_overflow", @@ -141,7 +141,7 @@ func TestVerifyGasUsed(t *testing.T) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - err := VerifyGasUsed(config, test.feeConfig, test.parent, test.header) + err := VerifyGasUsed(config, test.feeConfig, test.acp176Config, test.parent, test.header) require.ErrorIs(t, err, test.want) }) } @@ -149,14 +149,14 @@ func TestVerifyGasUsed(t *testing.T) { func TestVerifyGasLimit(t *testing.T) { t.Run("normal", func(t *testing.T) { - VerifyGasLimitTest(t, testFeeConfig) + VerifyGasLimitTest(t, testFeeConfig, testACP176Config) }) t.Run("double", func(t *testing.T) { - VerifyGasLimitTest(t, testFeeConfigDouble) + VerifyGasLimitTest(t, testFeeConfigDouble, testACP176ConfigDouble) }) } -func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { +func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp176.Config) { tests := []struct { name string upgrades extras.NetworkUpgrades @@ -180,7 +180,7 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { Number: big.NewInt(0), }, header: &types.Header{ - GasLimit: acp176.MinMaxCapacity + 1, + GasLimit: uint64(acp176.DefaultACP176Config.MinMaxCapacity()) + 1, }, want: errInvalidGasLimit, }, @@ -191,7 +191,7 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { Number: big.NewInt(0), }, header: &types.Header{ - GasLimit: acp176.MinMaxCapacity, + GasLimit: uint64(acp176.DefaultACP176Config.MinMaxCapacity()), }, }, { @@ -258,7 +258,7 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - err := VerifyGasLimit(config, feeConfig, test.parent, test.header) + err := VerifyGasLimit(config, feeConfig, acp176Config, test.parent, test.header) require.ErrorIs(t, err, test.want) }) } @@ -266,13 +266,14 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) { func TestGasCapacity(t *testing.T) { tests := []struct { - name string - feeConfig commontype.FeeConfig - upgrades extras.NetworkUpgrades - parent *types.Header - timestamp uint64 - want uint64 - wantErr error + name string + feeConfig commontype.FeeConfig + acp176Config acp176.Config + upgrades extras.NetworkUpgrades + parent *types.Header + timestamp uint64 + want uint64 + wantErr error }{ { name: "subnet_evm", @@ -304,7 +305,7 @@ func TestGasCapacity(t *testing.T) { config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := GasCapacity(config, test.feeConfig, test.parent, test.timestamp) + got, err := GasCapacity(config, test.feeConfig, test.acp176Config, test.parent, test.timestamp) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 1eae62cb9a..1b17237b67 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -642,13 +642,20 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash, ethConfig ethconfig. vm.blockChain = vm.eth.BlockChain() vm.miner = vm.eth.Miner() lastAccepted := vm.blockChain.LastAcceptedBlock() - feeConfig, _, err := vm.blockChain.GetFeeConfigAt(lastAccepted.Header()) - if err != nil { - return err + if vm.chainConfigExtra().IsFortuna(lastAccepted.Header().Time) { + acp224FeeConfig, _, err := vm.blockChain.GetACP224FeeConfigAt(lastAccepted.Header()) + if err != nil { + return err + } + vm.txPool.SetMinFee(acp224FeeConfig.MinGasPrice) + } else { + feeConfig, _, err := vm.blockChain.GetFeeConfigAt(lastAccepted.Header()) + if err != nil { + return err + } + vm.txPool.SetMinFee(feeConfig.MinBaseFee) } - vm.txPool.SetMinFee(feeConfig.MinBaseFee) vm.txPool.SetGasTip(big.NewInt(0)) - vm.txPool.SetMinFee(big.NewInt(acp176.MinGasPrice)) vm.eth.Start() return vm.initChainState(lastAccepted) diff --git a/precompile/contracts/acp224feemanager/config_test.go b/precompile/contracts/acp224feemanager/config_test.go index 04c94fda4b..e98cef5c27 100644 --- a/precompile/contracts/acp224feemanager/config_test.go +++ b/precompile/contracts/acp224feemanager/config_test.go @@ -27,7 +27,7 @@ package acp224feemanager // Config: NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ // TargetGas: utils.NewUint64(1000000), // MinGasPrice: utils.NewUint64(1000000), -// MaxCapacityFactor: utils.NewUint64(1000000), +// TimeToFillCapacity: utils.NewUint64(1000000), // TimeToDouble: utils.NewUint64(1000000), // }), // ChainConfig: func() precompileconfig.ChainConfig { diff --git a/precompile/contracts/acp224feemanager/contract.abi b/precompile/contracts/acp224feemanager/contract.abi index 2154805e5d..c605eb142a 100644 --- a/precompile/contracts/acp224feemanager/contract.abi +++ b/precompile/contracts/acp224feemanager/contract.abi @@ -22,7 +22,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { @@ -50,7 +50,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { @@ -117,7 +117,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { @@ -208,7 +208,7 @@ }, { "internalType": "uint256", - "name": "maxCapacityFactor", + "name": "timeToFillCapacity", "type": "uint256" }, { diff --git a/precompile/contracts/acp224feemanager/contract.go b/precompile/contracts/acp224feemanager/contract.go index 4ba26c2f72..5c79daa18a 100644 --- a/precompile/contracts/acp224feemanager/contract.go +++ b/precompile/contracts/acp224feemanager/contract.go @@ -28,7 +28,7 @@ const ( // must preserve order of these fields targetGasKey = iota minGasPriceKey - maxCapacityFactorKey + timeToFillCapacityKey timeToDoubleKey // add new fields above this numFeeConfigField = iota - 1 @@ -84,8 +84,8 @@ func GetStoredFeeConfig(stateDB contract.StateReader) commontype.ACP224FeeConfig feeConfig.TargetGas = new(big.Int).Set(val.Big()) case minGasPriceKey: feeConfig.MinGasPrice = new(big.Int).Set(val.Big()) - case maxCapacityFactorKey: - feeConfig.MaxCapacityFactor = new(big.Int).Set(val.Big()) + case timeToFillCapacityKey: + feeConfig.TimeToFillCapacity = new(big.Int).Set(val.Big()) case timeToDoubleKey: feeConfig.TimeToDouble = new(big.Int).Set(val.Big()) default: @@ -115,8 +115,8 @@ func StoreFeeConfig(stateDB contract.StateDB, feeConfig commontype.ACP224FeeConf input = common.BigToHash(feeConfig.TargetGas) case minGasPriceKey: input = common.BigToHash(feeConfig.MinGasPrice) - case maxCapacityFactorKey: - input = common.BigToHash(feeConfig.MaxCapacityFactor) + case timeToFillCapacityKey: + input = common.BigToHash(feeConfig.TimeToFillCapacity) case timeToDoubleKey: input = common.BigToHash(feeConfig.TimeToDouble) default: diff --git a/precompile/contracts/acp224feemanager/module.go b/precompile/contracts/acp224feemanager/module.go index 6fa14c651e..37dec96970 100644 --- a/precompile/contracts/acp224feemanager/module.go +++ b/precompile/contracts/acp224feemanager/module.go @@ -61,6 +61,7 @@ func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg pre return fmt.Errorf("cannot configure given initial fee config: %w", err) } } else { + // TODO: XXX - If the initial fee config is not set, we should use the latest fee config rather than the one set in genesis. if err := StoreFeeConfig(state, chainConfig.GetACP224FeeConfig(), blockContext); err != nil { // This should not happen since we already checked the chain config in the genesis creation. return fmt.Errorf("cannot configure fee config in chain config: %w", err) From 379927b7595094f1dce292c9b89b58b5859fb3c0 Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Tue, 16 Sep 2025 16:33:39 -0400 Subject: [PATCH 6/8] Initial ACP-224 implementation --- cmd/evm/internal/t8ntool/transition.go | 8 +- commontype/test_fee_config.go | 7 + core/blockchain_ext_test.go | 10 +- core/chain_makers.go | 20 +- core/state_processor_test.go | 33 +- core/txpool/legacypool/legacypool_test.go | 2 - eth/gasprice/fee_info_provider_test.go | 4 +- eth/gasprice/gasprice.go | 2 +- eth/gasprice/gasprice_test.go | 98 ++++- ethclient/simulated/options_test.go | 13 +- go.mod | 3 +- go.sum | 8 +- internal/ethapi/api_test.go | 2 +- .../testdata/eth_getBlockByHash-hash-1.json | 18 +- ...h_getBlockByHash-hash-latest-1-fullTx.json | 30 +- .../eth_getBlockByHash-hash-latest.json | 20 +- .../eth_getBlockByNumber-number-1.json | 18 +- .../eth_getBlockByNumber-number-latest-1.json | 30 +- .../eth_getBlockByNumber-tag-latest.json | 20 +- ...h_getBlockReceipts-block-with-blob-tx.json | 38 +- ...eceipts-block-with-contract-create-tx.json | 34 +- ...ockReceipts-block-with-dynamic-fee-tx.json | 34 +- ...ts-block-with-legacy-contract-call-tx.json | 12 +- ...eceipts-block-with-legacy-transfer-tx.json | 34 +- .../eth_getBlockReceipts-tag-latest.json | 38 +- .../testdata/eth_getHeaderByHash-hash-1.json | 14 +- .../eth_getHeaderByHash-hash-latest-1.json | 16 +- .../eth_getHeaderByHash-hash-latest.json | 16 +- .../eth_getHeaderByNumber-number-1.json | 14 +- ...eth_getHeaderByNumber-number-latest-1.json | 16 +- .../eth_getHeaderByNumber-tag-latest.json | 16 +- .../eth_getTransactionReceipt-blob-tx.json | 8 +- ...TransactionReceipt-create-contract-tx.json | 4 +- ...eipt-create-contract-with-access-list.json | 8 +- ...ansactionReceipt-dynamic-tx-with-logs.json | 8 +- ...TransactionReceipt-normal-transfer-tx.json | 8 +- .../eth_getTransactionReceipt-with-logs.json | 12 +- params/config_test.go | 7 + params/extras/config.go | 3 +- params/extras/network_upgrades.go | 3 +- plugin/evm/header/base_fee_test.go | 63 ++- plugin/evm/header/block_gas_cost_test.go | 6 +- plugin/evm/header/extra_test.go | 14 +- plugin/evm/header/gas_limit_test.go | 30 +- .../acp224feemanagertest/config_test.go | 169 ++++++++ .../acp224feemanagertest/contract_test.go | 402 ++++++++++++++++++ .../contracts/acp224feemanager/config.go | 4 - .../contracts/acp224feemanager/config_test.go | 90 ---- .../contracts/acp224feemanager/contract.go | 10 +- .../acp224feemanager/contract_test.go | 395 ----------------- .../contracts/acp224feemanager/event.go | 32 -- precompile/precompiletest/test_precompile.go | 1 + 52 files changed, 1025 insertions(+), 880 deletions(-) create mode 100644 precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go create mode 100644 precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go delete mode 100644 precompile/contracts/acp224feemanager/config_test.go delete mode 100644 precompile/contracts/acp224feemanager/contract_test.go diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index d6a5187eac..be4a031a20 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -35,7 +35,6 @@ import ( "os" "path" - "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/common/hexutil" "github.com/ava-labs/libevm/core/state" @@ -231,9 +230,12 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { // Override the default min base fee if it's set in the env feeConfig.MinBaseFee = env.MinBaseFee } + acp176Config, err := params.DefaultACP224FeeConfig.ToACP176Config() + if err != nil { + return NewError(ErrorConfig, fmt.Errorf("failed converting ACP224 fee config to ACP176 config: %v", err)) + } configExtra := params.GetExtra(chainConfig) - var err error - env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, acp176.DefaultACP176Config, parent, env.Timestamp) + env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, acp176Config, parent, env.Timestamp) if err != nil { return NewError(ErrorConfig, fmt.Errorf("failed calculating base fee: %v", err)) } diff --git a/commontype/test_fee_config.go b/commontype/test_fee_config.go index 22c3b38280..4a7b65affd 100644 --- a/commontype/test_fee_config.go +++ b/commontype/test_fee_config.go @@ -17,3 +17,10 @@ var ValidTestFeeConfig = FeeConfig{ MaxBlockGasCost: big.NewInt(1_000_000), BlockGasCostStep: big.NewInt(200_000), } + +var ValidTestACP224FeeConfig = ACP224FeeConfig{ + TargetGas: big.NewInt(15_000_000), + MinGasPrice: big.NewInt(1), + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), +} diff --git a/core/blockchain_ext_test.go b/core/blockchain_ext_test.go index 33ddb4b97f..984a32d3e5 100644 --- a/core/blockchain_ext_test.go +++ b/core/blockchain_ext_test.go @@ -1479,7 +1479,7 @@ func InsertChainValidBlockFee(t *testing.T, create createFunc) { // Ensure that key1 has some funds in the genesis block. genesisBalance := new(big.Int).Mul(big.NewInt(1000000), big.NewInt(params.Ether)) gspec := &Genesis{ - Config: params.TestChainConfig, + Config: params.TestEtnaChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: genesisBalance}}, } @@ -1488,13 +1488,13 @@ func InsertChainValidBlockFee(t *testing.T, create createFunc) { t.Cleanup(blockchain.Stop) // This call generates a chain of 3 blocks. - signer := types.LatestSigner(params.TestChainConfig) + signer := types.LatestSigner(params.TestEtnaChainConfig) tip := big.NewInt(50000 * params.GWei) transfer := big.NewInt(10000) - _, chain, _, err := GenerateChainWithGenesis(gspec, blockchain.engine, 3, extras.TestChainConfig.FeeConfig.TargetBlockRate-1, func(_ int, gen *BlockGen) { + _, chain, _, err := GenerateChainWithGenesis(gspec, blockchain.engine, 3, extras.TestEtnaChainConfig.FeeConfig.TargetBlockRate-1, func(_ int, gen *BlockGen) { feeCap := new(big.Int).Add(gen.BaseFee(), tip) tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: params.TestChainConfig.ChainID, + ChainID: params.TestEtnaChainConfig.ChainID, Nonce: gen.TxNonce(addr1), To: &addr2, Gas: ethparams.TxGas, @@ -1561,7 +1561,7 @@ func StatefulPrecompiles(t *testing.T, create createFunc) { // Ensure that key1 has sufficient funds in the genesis block for all of the tests. genesisBalance := new(big.Int).Mul(big.NewInt(1000000), big.NewInt(params.Ether)) - config := params.Copy(params.TestChainConfig) + config := params.Copy(params.TestEtnaChainConfig) // Set all of the required config parameters params.GetExtra(&config).GenesisPrecompiles = extras.Precompiles{ deployerallowlist.ConfigKey: deployerallowlist.NewConfig(utils.NewUint64(0), []common.Address{addr1}, nil, nil), diff --git a/core/chain_makers.go b/core/chain_makers.go index b797928ab4..f66f228bbe 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -31,6 +31,7 @@ import ( "fmt" "math/big" + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/core/state" @@ -383,15 +384,18 @@ func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.S if err != nil { panic(err) } - acp224FeeConfig, _, err := cm.GetACP224FeeConfigAt(parent.Header()) - if err != nil { - panic(err) - } - acp176Config, err := acp224FeeConfig.ToACP176Config() - if err != nil { - panic(err) - } config := params.GetExtra(cm.config) + var acp176Config acp176.Config + if config.IsFortuna(time) { + acp224FeeConfig, _, err := cm.GetACP224FeeConfigAt(parent.Header()) + if err != nil { + panic(err) + } + acp176Config, err = acp224FeeConfig.ToACP176Config() + if err != nil { + panic(err) + } + } gasLimit, err := header.GasLimit(config, feeConfig, acp176Config, parent.Header(), time) if err != nil { panic(err) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 31a6e29784..d93f63f2a9 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -41,6 +41,7 @@ import ( "github.com/ava-labs/libevm/crypto" ethparams "github.com/ava-labs/libevm/params" "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/consensus" "github.com/ava-labs/subnet-evm/consensus/dummy" "github.com/ava-labs/subnet-evm/consensus/misc/eip4844" @@ -53,6 +54,12 @@ import ( "golang.org/x/crypto/sha3" ) +var testACP176Config = acp176.Config{ + MinGasPrice: 1, + TimeToFillCapacity: 5, + TimeToDouble: 60, +} + func u64(val uint64) *uint64 { return &val } // TestStateProcessorErrors tests the output from the 'core' errors @@ -156,9 +163,9 @@ func TestStateProcessorErrors(t *testing.T) { { // ErrGasLimitReached txs: []*types.Transaction{ // This test was modified to account for ACP-176 gas limits - makeTx(key1, 0, common.Address{}, big.NewInt(0), uint64(acp176.DefaultACP176Config.MinMaxCapacity()+1), big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), nil), + makeTx(key1, 0, common.Address{}, big.NewInt(0), uint64(testACP176Config.MinMaxCapacity()+1), big.NewInt(int64(testACP176Config.MinGasPrice)), nil), }, - want: "could not apply tx 0 [0x6c95e59678246e8b44a1d9382a9cc6589684298b32b7aaf640e8b6fc75ce3dfc]: gas limit reached", + want: "could not apply tx 0 [0xb709565c056a68a4b4dc7714ae901a0f03663bb98f9fa58a10b88ec614362caf]: gas limit reached", }, { // ErrInsufficientFundsForTransfer txs: []*types.Transaction{ @@ -185,7 +192,7 @@ func TestStateProcessorErrors(t *testing.T) { { // ErrGasLimitReached txs: []*types.Transaction{ // This test was modified to account for ACP-176 gas limits - makeTx(key1, 0, common.Address{}, big.NewInt(0), ethparams.TxGas*953, big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), nil), + makeTx(key1, 0, common.Address{}, big.NewInt(0), ethparams.TxGas*953, big.NewInt(int64(testACP176Config.MinGasPrice)), nil), }, want: "could not apply tx 0 [0xcd46718c1af6fd074deb6b036d34c1cb499517bf90d93df74dcfaba25fdf34af]: gas limit reached", }, @@ -365,15 +372,19 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr if err != nil { panic(err) } - acp224FeeConfig, _, err := fakeChainReader.GetACP224FeeConfigAt(parent.Header()) - if err != nil { - panic(err) - } - acp176Config, err := acp224FeeConfig.ToACP176Config() - if err != nil { - panic(err) - } configExtra := params.GetExtra(config) + var acp224FeeConfig commontype.ACP224FeeConfig + var acp176Config acp176.Config + if configExtra.IsFortuna(time) { + acp224FeeConfig, _, err = fakeChainReader.GetACP224FeeConfigAt(parent.Header()) + if err != nil { + panic(err) + } + acp176Config, err = acp224FeeConfig.ToACP176Config() + if err != nil { + panic(err) + } + } gasLimit, _ := customheader.GasLimit(configExtra, feeConfig, acp176Config, parent.Header(), time) baseFee, _ := customheader.BaseFee(configExtra, feeConfig, acp176Config, parent.Header(), time) header := &types.Header{ diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 04ebfd54ed..f49faab7d3 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -40,7 +40,6 @@ import ( "testing" "time" - "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/core/state" @@ -82,7 +81,6 @@ var ( TimeToFillCapacity: big.NewInt(5), TimeToDouble: big.NewInt(60), } - testACP176Config = acp176.DefaultACP176Config ) func init() { diff --git a/eth/gasprice/fee_info_provider_test.go b/eth/gasprice/fee_info_provider_test.go index 7d91e41194..72fd813102 100644 --- a/eth/gasprice/fee_info_provider_test.go +++ b/eth/gasprice/fee_info_provider_test.go @@ -16,8 +16,8 @@ import ( "github.com/ava-labs/subnet-evm/params" ) -func TestFeeInfoProvider(t *testing.T) { - backend := newTestBackend(t, params.TestChainConfig, 2, testGenBlock(t, 55, 370)) +func TestEtnaFeeInfoProvider(t *testing.T) { + backend := newTestBackend(t, params.TestEtnaChainConfig, 2, testGenBlock(t, 55, 370)) f, err := newFeeInfoProvider(backend, 1, 2) require.NoError(t, err) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 89d8a6933e..2c97d4f7b6 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -67,7 +67,7 @@ const ( var ( DefaultMaxPrice = big.NewInt(150 * params.GWei) - DefaultMinPrice = big.NewInt(0 * params.GWei) + DefaultMinPrice = big.NewInt(1) DefaultMinBaseFee = big.NewInt(legacy.BaseFee) DefaultMinGasUsed = big.NewInt(acp176.MinTargetPerSecond) DefaultMaxLookbackSeconds = uint64(80) diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 6e7db63a39..c98df9ed97 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -47,6 +47,7 @@ import ( "github.com/ava-labs/subnet-evm/params/extras" customheader "github.com/ava-labs/subnet-evm/plugin/evm/header" "github.com/ava-labs/subnet-evm/plugin/evm/upgrade/legacy" + "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" "github.com/ava-labs/subnet-evm/rpc" "github.com/ava-labs/subnet-evm/utils" @@ -143,8 +144,8 @@ func newTestBackend(t *testing.T, config *params.ChainConfig, numBlocks int, gen engine := dummy.NewFaker() // Generate testing blocks - targetBlockRate := params.GetExtra(config).FeeConfig.TargetBlockRate - _, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, targetBlockRate-1, genBlocks) + blockGap := uint64(1) + _, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, blockGap, genBlocks) if err != nil { t.Fatal(err) } @@ -270,8 +271,8 @@ func TestSuggestTipCapSimple(t *testing.T) { applyGasPriceTest(t, suggestTipCapTest{ chainConfig: params.TestChainConfig, numBlocks: 3, - genBlock: testGenBlock(t, 55, 370), - expectedTip: big.NewInt(1_287_001_288), + genBlock: testGenBlock(t, 55, 80), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -279,8 +280,8 @@ func TestSuggestTipCapSimpleFloor(t *testing.T) { applyGasPriceTest(t, suggestTipCapTest{ chainConfig: params.TestChainConfig, numBlocks: 1, - genBlock: testGenBlock(t, 55, 370), - expectedTip: big.NewInt(643_500_644), + genBlock: testGenBlock(t, 55, 80), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -311,7 +312,7 @@ func TestSuggestTipCapSmallTips(t *testing.T) { } b.AddTx(tx) tx = types.NewTx(&types.DynamicFeeTx{ - ChainID: params.TestChainConfig.ChainID, + ChainID: params.TestEtnaChainConfig.ChainID, Nonce: b.TxNonce(addr), To: &common.Address{}, Gas: ethparams.TxGas, @@ -324,7 +325,7 @@ func TestSuggestTipCapSmallTips(t *testing.T) { b.AddTx(tx) } }, - expectedTip: big.NewInt(1_287_001_288), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -333,7 +334,7 @@ func TestSuggestTipCapMinGas(t *testing.T) { chainConfig: params.TestChainConfig, numBlocks: 3, genBlock: testGenBlock(t, 500, 50), - expectedTip: big.NewInt(0), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -375,7 +376,7 @@ func TestSuggestGasPriceSubnetEVM(t *testing.T) { func TestSuggestTipCapMaxBlocksLookback(t *testing.T) { applyGasPriceTest(t, suggestTipCapTest{ - chainConfig: params.TestChainConfig, + chainConfig: params.TestEtnaChainConfig, numBlocks: 20, genBlock: testGenBlock(t, 550, 370), expectedTip: big.NewInt(5_807_226_111), @@ -393,7 +394,7 @@ func TestSuggestTipCapMaxBlocksSecondsLookback(t *testing.T) { // Regression test to ensure the last estimation of base fee is not used // for the block immediately following a fee configuration update. -func TestSuggestGasPriceAfterFeeConfigUpdate(t *testing.T) { +func TestSuggestGasPriceAfterFeeManagerUpdate(t *testing.T) { require := require.New(t) config := Config{ Blocks: 20, @@ -401,26 +402,26 @@ func TestSuggestGasPriceAfterFeeConfigUpdate(t *testing.T) { } // create a chain config with fee manager enabled at genesis with [addr] as the admin - chainConfig := params.Copy(params.TestChainConfig) + chainConfig := params.Copy(params.TestEtnaChainConfig) chainConfigExtra := params.GetExtra(&chainConfig) chainConfigExtra.GenesisPrecompiles = extras.Precompiles{ feemanager.ConfigKey: feemanager.NewConfig(utils.NewUint64(0), []common.Address{addr}, nil, nil, nil), } // create a fee config with higher MinBaseFee and prepare it for inclusion in a tx - signer := types.LatestSigner(params.TestChainConfig) + signer := types.LatestSigner(params.TestEtnaChainConfig) highFeeConfig := chainConfigExtra.FeeConfig highFeeConfig.MinBaseFee = big.NewInt(28_000_000_000) data, err := feemanager.PackSetFeeConfig(highFeeConfig) require.NoError(err) - // before issuing the block changing the fee into the chain, the fee estimation should + // before issuing the block changing the fee into the chain, the base fee estimation should // follow the fee config in genesis. backend := newTestBackend(t, &chainConfig, 0, func(i int, b *core.BlockGen) {}) defer backend.teardown() oracle, err := NewOracle(backend, config) require.NoError(err) - got, err := oracle.SuggestPrice(context.Background()) + got, err := oracle.EstimateBaseFee(context.Background()) require.NoError(err) require.Equal(chainConfigExtra.FeeConfig.MinBaseFee, got) @@ -450,8 +451,71 @@ func TestSuggestGasPriceAfterFeeConfigUpdate(t *testing.T) { _, err = backend.chain.InsertChain(blocks) require.NoError(err) - // verify the suggested price follows the new fee config. - got, err = oracle.SuggestPrice(context.Background()) + // verify the estimated base fee follows the new fee config. + got, err = oracle.EstimateBaseFee(context.Background()) require.NoError(err) require.Equal(highFeeConfig.MinBaseFee, got) } + +func TestSuggestGasPriceAfterACP224FeeManagerUpdate(t *testing.T) { + require := require.New(t) + config := Config{ + Blocks: 20, + Percentile: 60, + } + + // create a chain config with fee manager enabled at genesis with [addr] as the admin + chainConfig := params.Copy(params.TestChainConfig) + chainConfigExtra := params.GetExtra(&chainConfig) + chainConfigExtra.GenesisPrecompiles = extras.Precompiles{ + acp224feemanager.ConfigKey: acp224feemanager.NewConfig(utils.NewUint64(0), []common.Address{addr}, nil, nil, nil), + } + + // create a fee config with higher MinBaseFee and prepare it for inclusion in a tx + signer := types.LatestSigner(params.TestChainConfig) + highFeeConfig := chainConfigExtra.ACP224FeeConfig + highFeeConfig.MinGasPrice = big.NewInt(13_000_000_000) + data, err := acp224feemanager.PackSetFeeConfig(highFeeConfig) + require.NoError(err) + + // before issuing the block changing the fee into the chain, the base fee estimation should + // follow the fee config in genesis. + backend := newTestBackend(t, &chainConfig, 0, func(i int, b *core.BlockGen) {}) + defer backend.teardown() + oracle, err := NewOracle(backend, config) + require.NoError(err) + got, err := oracle.EstimateBaseFee(context.Background()) + require.NoError(err) + require.Equal(chainConfigExtra.ACP224FeeConfig.MinGasPrice, got) + + // issue the block with tx that changes the fee + genesis := backend.chain.Genesis() + engine := backend.chain.Engine() + db := rawdb.NewDatabase(backend.chain.StateCache().DiskDB()) + blocks, _, err := core.GenerateChain(&chainConfig, genesis, engine, db, 1, chainConfigExtra.FeeConfig.TargetBlockRate, func(i int, b *core.BlockGen) { + b.SetCoinbase(common.Address{1}) + + // admin issues tx to change fee config to higher MinBaseFee + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainConfig.ChainID, + Nonce: b.TxNonce(addr), + To: &acp224feemanager.ContractAddress, + Gas: 500_000, + Value: common.Big0, + GasFeeCap: chainConfigExtra.ACP224FeeConfig.MinGasPrice, // give low fee, it should work since we still haven't applied high fees + GasTipCap: common.Big0, + Data: data, + }) + tx, err = types.SignTx(tx, signer, key) + require.NoError(err, "failed to create tx") + b.AddTx(tx) + }) + require.NoError(err) + _, err = backend.chain.InsertChain(blocks) + require.NoError(err) + + // verify the estimated base fee follows the new fee config. + got, err = oracle.EstimateBaseFee(context.Background()) + require.NoError(err) + require.Equal(highFeeConfig.MinGasPrice, got) +} diff --git a/ethclient/simulated/options_test.go b/ethclient/simulated/options_test.go index e27aff7fd3..484e102715 100644 --- a/ethclient/simulated/options_test.go +++ b/ethclient/simulated/options_test.go @@ -33,11 +33,11 @@ import ( "strings" "testing" - "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" ethereum "github.com/ava-labs/libevm" "github.com/ava-labs/libevm/core/types" ethparams "github.com/ava-labs/libevm/params" "github.com/ava-labs/subnet-evm/core" + "github.com/ava-labs/subnet-evm/params/extras" ) // Tests that the simulator starts with the initial gas limit in the genesis block, @@ -61,8 +61,15 @@ func TestWithBlockGasLimitOption(t *testing.T) { if err != nil { t.Fatalf("failed to retrieve head block: %v", err) } - if head.GasLimit() != uint64(acp176.DefaultACP176Config.MinMaxCapacity()) { - t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), acp176.DefaultACP176Config.MinMaxCapacity()) + acp176Config, err := extras.DefaultACP224FeeConfig.ToACP176Config() + if err != nil { + t.Fatalf("failed to convert ACP224 fee config to ACP176 config: %v", err) + } + if err != nil { + t.Fatalf("failed to convert ACP224 fee config to ACP176 config: %v", err) + } + if head.GasLimit() != uint64(acp176Config.MinMaxCapacity()) { + t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), acp176Config.MinMaxCapacity()) } } diff --git a/go.mod b/go.mod index 5d090b1a08..c5d4a758d5 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.9 require ( github.com/VictoriaMetrics/fastcache v1.12.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/avalanchego v1.13.6-0.20250910213146-23a113adc559 + github.com/ava-labs/avalanchego v1.13.6-0.20250912174155-ed70ad638d2c github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 github.com/ava-labs/libevm v1.13.14-0.3.0.rc.6 github.com/davecgh/go-spew v1.1.1 @@ -72,7 +72,6 @@ require ( github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect - github.com/fatih/structtag v1.2.0 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect diff --git a/go.sum b/go.sum index c854458856..36168b88a9 100644 --- a/go.sum +++ b/go.sum @@ -24,10 +24,8 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/avalanchego v1.13.6-0.20250910212054-5218d21143f6 h1:XgNP58BY2FmaQGiPMzE2YxgqimCJljQuvkGoZtUgjoY= -github.com/ava-labs/avalanchego v1.13.6-0.20250910212054-5218d21143f6/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= -github.com/ava-labs/avalanchego v1.13.6-0.20250910213146-23a113adc559 h1:dB4T5OC3uOteDnsHRheNXsS/U+QuTn/vDDYiEfuGsOg= -github.com/ava-labs/avalanchego v1.13.6-0.20250910213146-23a113adc559/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= +github.com/ava-labs/avalanchego v1.13.6-0.20250912174155-ed70ad638d2c h1:S7l1PEaYYRmT2bs9LXY2z1wk7UAyMU6veavKf4IN9e4= +github.com/ava-labs/avalanchego v1.13.6-0.20250912174155-ed70ad638d2c/go.mod h1:/eugkYcDQfCt9czHr/Jlw3MW/1DIoI7Cm0maqNkuWMs= github.com/ava-labs/coreth v0.15.4-rc.3 h1:v33OOerxpGIKa1MpljXMBB3Yljy23xzsez3E/dn7TzY= github.com/ava-labs/coreth v0.15.4-rc.3/go.mod h1:Esb0FK+KJr6co7rrhtBWsmSMXEL5JWelEsijlqAHdq0= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 h1:aMcrLbpJ/dyu2kZDf/Di/4JIWsUcYPyTDKymiHpejt0= @@ -153,8 +151,6 @@ github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHE github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= -github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fjl/gencodec v0.1.1 h1:DhQY29Q6JLXB/GgMqE86NbOEuvckiYcJCbXFu02toms= github.com/fjl/gencodec v0.1.1/go.mod h1:chDHL3wKXuBgauP8x3XNZkl5EIAR5SoCTmmmDTZRzmw= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 9ebd0bf2cc..fecd851bd8 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1030,7 +1030,7 @@ func TestSignTransaction(t *testing.T) { if err != nil { t.Fatal(err) } - expect := `{"type":"0x2","chainId":"0x1","nonce":"0x0","to":"0x703c4b2bd70c169f5717101caee543299fc946c7","gas":"0x5208","gasPrice":null,"maxPriorityFeePerGas":"0x0","maxFeePerGas":"0xba43b7400","value":"0x1","input":"0x","accessList":[],"v":"0x0","r":"0xa7bbf5672b6f78e934bd380aad0b2626d5337e96c12f1e755fa5522ba7a314bd","s":"0x4d661f8c7b850b7dc3ce1c8c7b443a4434a22fe3ad14cc463205e0259546f0c8","yParity":"0x0","hash":"0x0333d97cbdababb6af7cc55a6f64d47711b8e18a93d7343657508a454407a82c"}` + expect := `{"type":"0x2","chainId":"0x1","nonce":"0x0","to":"0x703c4b2bd70c169f5717101caee543299fc946c7","gas":"0x5208","gasPrice":null,"maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x2","value":"0x1","input":"0x","accessList":[],"v":"0x1","r":"0x5a32230e497be0277b58afb995227a167e087462fb770057ed6946f5ef5a2df5","s":"0x431e048124baffbd67bc35df940bb9f5ddf8a36afb2672616d075ac39415e885","yParity":"0x1","hash":"0xf5e941beeca516d3d3dca2707d74c54a58e07365b89efc5de58dd7b6041ef78e"}` if !bytes.Equal(tx, []byte(expect)) { t.Errorf("result mismatch. Have:\n%s\nWant:\n%s\n", tx, expect) } diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json index 29acfe3fcb..149c6ac3d8 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json @@ -1,13 +1,13 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0xb6592ae424eafd61ba0339dffe9b080c5b3f005224186447df26638e6c0bbd3b", + "hash": "0xd2ed27e3bcf7c1c8403ba0b13951b9d036bcdd7fbdae6eb0c1ae149e59337c18", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -17,13 +17,13 @@ "parentHash": "0xba5fb8e40c7c77b70d6977300cea5072e1811622808e41b3488832031e4f6a6d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2de", - "stateRoot": "0xa17c770ca1e18e544a4a6d14b611cd03b505d465cc967ba5162d59ce459b553d", + "size": "0x29b", + "stateRoot": "0x8b63f66c0da7b9ed8e8a6ede137b919fa67fcefaaa70ce8fb455d2d63a517c6c", "timestamp": "0xa", "totalDifficulty": "0x1", "transactions": [ - "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26" + "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389" ], - "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5", + "transactionsRoot": "0x2091c9f520d1aee00e5552f3e8da86e1d0668593e8dc189c1c2f429401ab2c23", "uncles": [] -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json index cfc4fdf23c..b288b622e6 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json @@ -1,45 +1,45 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "hash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0xae0813ad53958eb4030c34dd19872f06d9eab41bf6140a4536258a2b4f46f45d", + "parentHash": "0x4488a80805f2911efa27cd150af52898714b001c04b8b5208210ff3e84065b2d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2de", - "stateRoot": "0x67e974f6435c557282cd778ae1ae16dded6e84db121d3ab27b931726bd48e2ac", + "size": "0x29b", + "stateRoot": "0x6d333799439bcfa2a9901891f412879293ec93d1a01429452fa3cdadfb86ccb9", "timestamp": "0x5a", "totalDifficulty": "0x9", "transactions": [ { - "blockHash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "blockHash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "blockNumber": "0x9", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gas": "0x5208", - "gasPrice": "0x5d21dba00", - "hash": "0x237f95840187a93f8aaf8d6f1515f8a8ac9d9359fcb0c220cdb3d642d6b9a19a", + "gasPrice": "0x1", + "hash": "0x788f1d9b6ab5314ca3157e4e514b602d3d9cf98773402749cd0ea73d4f373330", "input": "0x", "nonce": "0x8", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", "transactionIndex": "0x0", "value": "0x3e8", "type": "0x0", - "v": "0x1c", - "r": "0xd7cdc527490b7ba29c515aae3bbe80c67729cda7f736e6515652cfc40e9da68f", - "s": "0x4d0a4a59bef165b16f910bdadd41efaaad1b73549bacc35eaf6d073eb1fb92b7" + "v": "0x1b", + "r": "0x405203de7391198cd3dd1bfc2b12201053a799be421d74a5d3bc1338e75abfed", + "s": "0x683e95bab8c6c2d757bdd5cd0d75dc2bc9e54d9066023935a5d2b93281bfd0a3" } ], - "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb", + "transactionsRoot": "0xf3f69c61b639254ec6538351b9edaebce124270a70dd2d7fbc8d197b2a7cd928", "uncles": [] -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json index 4b238c2b59..2771475121 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json @@ -1,29 +1,29 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0b01774210aec0d5e0969a2e2cf0d6ec95ede0e7e9692d2e4be1d0779c9059c1", + "hash": "0x0b1d5db9740143d57114cc750c89ec59d75276798a76aa24255bcaaf9fcbc255", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "parentHash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2de", - "stateRoot": "0x2b8307a066fd4575aca1fa6b42ef2c3a860a9c40337ea0d647c9f25e22062e34", + "size": "0x29b", + "stateRoot": "0xda6a753ddf04cde2621800ed8ce40fa9a09328789e5b309f0e32b4827262ae61", "timestamp": "0x64", "totalDifficulty": "0xa", "transactions": [ - "0x71be223424ab6e3457513a760b196d43b094414c32a70ff929b2b720a16b832d" + "0x2019a52ff9645912a406c958eaf597be403ba9cadb25b981bcbdb2b38711c12d" ], - "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01", + "transactionsRoot": "0x4022accb18056de5994cfb85f3c2721a86c9b1de72ef02f3b224e9c913a18a10", "uncles": [] -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json index 29acfe3fcb..149c6ac3d8 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json @@ -1,13 +1,13 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0xb6592ae424eafd61ba0339dffe9b080c5b3f005224186447df26638e6c0bbd3b", + "hash": "0xd2ed27e3bcf7c1c8403ba0b13951b9d036bcdd7fbdae6eb0c1ae149e59337c18", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -17,13 +17,13 @@ "parentHash": "0xba5fb8e40c7c77b70d6977300cea5072e1811622808e41b3488832031e4f6a6d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2de", - "stateRoot": "0xa17c770ca1e18e544a4a6d14b611cd03b505d465cc967ba5162d59ce459b553d", + "size": "0x29b", + "stateRoot": "0x8b63f66c0da7b9ed8e8a6ede137b919fa67fcefaaa70ce8fb455d2d63a517c6c", "timestamp": "0xa", "totalDifficulty": "0x1", "transactions": [ - "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26" + "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389" ], - "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5", + "transactionsRoot": "0x2091c9f520d1aee00e5552f3e8da86e1d0668593e8dc189c1c2f429401ab2c23", "uncles": [] -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json index cfc4fdf23c..b288b622e6 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json @@ -1,45 +1,45 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "hash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0xae0813ad53958eb4030c34dd19872f06d9eab41bf6140a4536258a2b4f46f45d", + "parentHash": "0x4488a80805f2911efa27cd150af52898714b001c04b8b5208210ff3e84065b2d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2de", - "stateRoot": "0x67e974f6435c557282cd778ae1ae16dded6e84db121d3ab27b931726bd48e2ac", + "size": "0x29b", + "stateRoot": "0x6d333799439bcfa2a9901891f412879293ec93d1a01429452fa3cdadfb86ccb9", "timestamp": "0x5a", "totalDifficulty": "0x9", "transactions": [ { - "blockHash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "blockHash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "blockNumber": "0x9", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gas": "0x5208", - "gasPrice": "0x5d21dba00", - "hash": "0x237f95840187a93f8aaf8d6f1515f8a8ac9d9359fcb0c220cdb3d642d6b9a19a", + "gasPrice": "0x1", + "hash": "0x788f1d9b6ab5314ca3157e4e514b602d3d9cf98773402749cd0ea73d4f373330", "input": "0x", "nonce": "0x8", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", "transactionIndex": "0x0", "value": "0x3e8", "type": "0x0", - "v": "0x1c", - "r": "0xd7cdc527490b7ba29c515aae3bbe80c67729cda7f736e6515652cfc40e9da68f", - "s": "0x4d0a4a59bef165b16f910bdadd41efaaad1b73549bacc35eaf6d073eb1fb92b7" + "v": "0x1b", + "r": "0x405203de7391198cd3dd1bfc2b12201053a799be421d74a5d3bc1338e75abfed", + "s": "0x683e95bab8c6c2d757bdd5cd0d75dc2bc9e54d9066023935a5d2b93281bfd0a3" } ], - "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb", + "transactionsRoot": "0xf3f69c61b639254ec6538351b9edaebce124270a70dd2d7fbc8d197b2a7cd928", "uncles": [] -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json index 4b238c2b59..2771475121 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json @@ -1,29 +1,29 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0b01774210aec0d5e0969a2e2cf0d6ec95ede0e7e9692d2e4be1d0779c9059c1", + "hash": "0x0b1d5db9740143d57114cc750c89ec59d75276798a76aa24255bcaaf9fcbc255", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "parentHash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2de", - "stateRoot": "0x2b8307a066fd4575aca1fa6b42ef2c3a860a9c40337ea0d647c9f25e22062e34", + "size": "0x29b", + "stateRoot": "0xda6a753ddf04cde2621800ed8ce40fa9a09328789e5b309f0e32b4827262ae61", "timestamp": "0x64", "totalDifficulty": "0xa", "transactions": [ - "0x71be223424ab6e3457513a760b196d43b094414c32a70ff929b2b720a16b832d" + "0x2019a52ff9645912a406c958eaf597be403ba9cadb25b981bcbdb2b38711c12d" ], - "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01", + "transactionsRoot": "0x4022accb18056de5994cfb85f3c2721a86c9b1de72ef02f3b224e9c913a18a10", "uncles": [] -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json index 12ca695538..cdc8a65a77 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json @@ -1,20 +1,20 @@ [ - { - "blobGasPrice": "0x1", - "blobGasUsed": "0x20000", - "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", - "blockNumber": "0x6", - "contractAddress": null, - "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba01", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x5208", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", - "transactionIndex": "0x0", - "type": "0x3" - } -] + { + "blobGasPrice": "0x1", + "blobGasUsed": "0x20000", + "blockHash": "0xd74e08700a0b69f81670d23e3ae4095f1bb5a7a3a93e131ca26747b510de8d03", + "blockNumber": "0x6", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x2", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0x77255f1a75d6c0252a56539ad11edf9047df59dc390085946b410f406b9cd254", + "transactionIndex": "0x0", + "type": "0x3" + } +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json index b843dacf9d..4ea47c0440 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-contract-create-tx.json @@ -1,18 +1,18 @@ [ - { - "blockHash": "0xdcba2f7c99ad0f58002737f1393578f1b72aca3270c1722d9d0fbdc2439b0484", - "blockNumber": "0x2", - "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", - "cumulativeGasUsed": "0xcf50", - "effectiveGasPrice": "0x5d21dba00", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0xcf50", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": null, - "transactionHash": "0x22aa617165f83a9f8c191c2b7724ae43eeb1249bee06c98c03c7624c21d27dc8", - "transactionIndex": "0x0", - "type": "0x0" - } -] + { + "blockHash": "0x67bc227618d9f281e84b55dceea251bcbdd1061217a469f85f9af7e04c14a1fb", + "blockNumber": "0x2", + "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", + "cumulativeGasUsed": "0xcf50", + "effectiveGasPrice": "0x1", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0xcf50", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": null, + "transactionHash": "0x3b727d5e08e2176d96ee1bea244f772b592acd2cda1acc3d822c8b7f3de362f9", + "transactionIndex": "0x0", + "type": "0x0" + } +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json index ad294280cc..8d86b5d8b6 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-dynamic-fee-tx.json @@ -1,18 +1,18 @@ [ - { - "blockHash": "0xfa29fee1c5195fda47b23d3ce5259e314eb7578d18b76b36068d0e321db024e1", - "blockNumber": "0x4", - "contractAddress": null, - "cumulativeGasUsed": "0x538d", - "effectiveGasPrice": "0x5d21dbbf4", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x538d", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x0", - "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x4e1e9194ca6f9d4e1736e9e441f66104f273548ed6d91b236a5f9c2ea10fa06d", - "transactionIndex": "0x0", - "type": "0x2" - } -] + { + "blockHash": "0x8cbe87a61fa9bb8a89bac2ff327f75e18d6b53618dabc9788f7f61e4d6c43421", + "blockNumber": "0x4", + "contractAddress": null, + "cumulativeGasUsed": "0x538d", + "effectiveGasPrice": "0x1f5", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x538d", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x0", + "to": "0x0000000000000000000000000000000000031ec7", + "transactionHash": "0x8416458a5e36b7b2f33020bd43d121c8d42c787d743b6eaf64ef09d663892b40", + "transactionIndex": "0x0", + "type": "0x2" + } +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json index c60bf1cec1..e483f9fc7e 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-contract-call-tx.json @@ -1,10 +1,10 @@ [ { - "blockHash": "0xd82a2ecb764df020971408362eed2f6521c9a7ae38ab991aba7c6ddd60ba7e64", + "blockHash": "0x21e527bcf2f59792ad6e35ba7cf3f92a3f319ed7d74581371a0c3a6eb53d4fd7", "blockNumber": "0x3", "contractAddress": null, "cumulativeGasUsed": "0x5e28", - "effectiveGasPrice": "0x5d21dba00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5e28", "logs": [ @@ -17,9 +17,9 @@ ], "data": "0x000000000000000000000000000000000000000000000000000000000000000d", "blockNumber": "0x3", - "transactionHash": "0x7366a7738f47e32f5b6d292ca064b6b66f295d3931533a3745975be1191fccdf", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", - "blockHash": "0xd82a2ecb764df020971408362eed2f6521c9a7ae38ab991aba7c6ddd60ba7e64", + "blockHash": "0x21e527bcf2f59792ad6e35ba7cf3f92a3f319ed7d74581371a0c3a6eb53d4fd7", "logIndex": "0x0", "removed": false } @@ -27,8 +27,8 @@ "logsBloom": "0x00000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000000000000008000000000000000000000000000000000020000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000400000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000", "status": "0x1", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x7366a7738f47e32f5b6d292ca064b6b66f295d3931533a3745975be1191fccdf", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", "type": "0x0" } -] +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json index 81d857254e..61753f96b4 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-legacy-transfer-tx.json @@ -1,18 +1,18 @@ [ - { - "blockHash": "0xf9081fe79fcdfd6a743577cc42fa17bec5e6cc1ebf5807b771724bf88b454b71", - "blockNumber": "0x1", - "contractAddress": null, - "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba00", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x5208", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26", - "transactionIndex": "0x0", - "type": "0x0" - } -] + { + "blockHash": "0x713ac10c7315b3ec44de14280f4422852dd151dd48619e9ae3827f230665c0cd", + "blockNumber": "0x1", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x1", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389", + "transactionIndex": "0x0", + "type": "0x0" + } +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json index 12ca695538..cdc8a65a77 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json @@ -1,20 +1,20 @@ [ - { - "blobGasPrice": "0x1", - "blobGasUsed": "0x20000", - "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", - "blockNumber": "0x6", - "contractAddress": null, - "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba01", - "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", - "gasUsed": "0x5208", - "logs": [], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", - "transactionIndex": "0x0", - "type": "0x3" - } -] + { + "blobGasPrice": "0x1", + "blobGasUsed": "0x20000", + "blockHash": "0xd74e08700a0b69f81670d23e3ae4095f1bb5a7a3a93e131ca26747b510de8d03", + "blockNumber": "0x6", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x2", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0x77255f1a75d6c0252a56539ad11edf9047df59dc390085946b410f406b9cd254", + "transactionIndex": "0x0", + "type": "0x3" + } +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json index 67bfe196bc..a20cdc228a 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json @@ -1,13 +1,13 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0xb6592ae424eafd61ba0339dffe9b080c5b3f005224186447df26638e6c0bbd3b", + "hash": "0xd2ed27e3bcf7c1c8403ba0b13951b9d036bcdd7fbdae6eb0c1ae149e59337c18", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -17,8 +17,8 @@ "parentHash": "0xba5fb8e40c7c77b70d6977300cea5072e1811622808e41b3488832031e4f6a6d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0xa17c770ca1e18e544a4a6d14b611cd03b505d465cc967ba5162d59ce459b553d", + "stateRoot": "0x8b63f66c0da7b9ed8e8a6ede137b919fa67fcefaaa70ce8fb455d2d63a517c6c", "timestamp": "0xa", "totalDifficulty": "0x1", - "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5" -} + "transactionsRoot": "0x2091c9f520d1aee00e5552f3e8da86e1d0668593e8dc189c1c2f429401ab2c23" +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json index d6e8b2fb6d..b50c7450ec 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json @@ -1,24 +1,24 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "hash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0xae0813ad53958eb4030c34dd19872f06d9eab41bf6140a4536258a2b4f46f45d", + "parentHash": "0x4488a80805f2911efa27cd150af52898714b001c04b8b5208210ff3e84065b2d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x67e974f6435c557282cd778ae1ae16dded6e84db121d3ab27b931726bd48e2ac", + "stateRoot": "0x6d333799439bcfa2a9901891f412879293ec93d1a01429452fa3cdadfb86ccb9", "timestamp": "0x5a", "totalDifficulty": "0x9", - "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb" -} + "transactionsRoot": "0xf3f69c61b639254ec6538351b9edaebce124270a70dd2d7fbc8d197b2a7cd928" +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json index 93e2b93378..7d13c8657e 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json @@ -1,24 +1,24 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0b01774210aec0d5e0969a2e2cf0d6ec95ede0e7e9692d2e4be1d0779c9059c1", + "hash": "0x0b1d5db9740143d57114cc750c89ec59d75276798a76aa24255bcaaf9fcbc255", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "parentHash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x2b8307a066fd4575aca1fa6b42ef2c3a860a9c40337ea0d647c9f25e22062e34", + "stateRoot": "0xda6a753ddf04cde2621800ed8ce40fa9a09328789e5b309f0e32b4827262ae61", "timestamp": "0x64", "totalDifficulty": "0xa", - "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01" -} + "transactionsRoot": "0x4022accb18056de5994cfb85f3c2721a86c9b1de72ef02f3b224e9c913a18a10" +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json index 67bfe196bc..a20cdc228a 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json @@ -1,13 +1,13 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0xb6592ae424eafd61ba0339dffe9b080c5b3f005224186447df26638e6c0bbd3b", + "hash": "0xd2ed27e3bcf7c1c8403ba0b13951b9d036bcdd7fbdae6eb0c1ae149e59337c18", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -17,8 +17,8 @@ "parentHash": "0xba5fb8e40c7c77b70d6977300cea5072e1811622808e41b3488832031e4f6a6d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0xa17c770ca1e18e544a4a6d14b611cd03b505d465cc967ba5162d59ce459b553d", + "stateRoot": "0x8b63f66c0da7b9ed8e8a6ede137b919fa67fcefaaa70ce8fb455d2d63a517c6c", "timestamp": "0xa", "totalDifficulty": "0x1", - "transactionsRoot": "0x87c65a3f1a98dafe282ace11eaf88b8f31bf41fe6794d401d2f986c1af84bcd5" -} + "transactionsRoot": "0x2091c9f520d1aee00e5552f3e8da86e1d0668593e8dc189c1c2f429401ab2c23" +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json index d6e8b2fb6d..b50c7450ec 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json @@ -1,24 +1,24 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "hash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0xae0813ad53958eb4030c34dd19872f06d9eab41bf6140a4536258a2b4f46f45d", + "parentHash": "0x4488a80805f2911efa27cd150af52898714b001c04b8b5208210ff3e84065b2d", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x67e974f6435c557282cd778ae1ae16dded6e84db121d3ab27b931726bd48e2ac", + "stateRoot": "0x6d333799439bcfa2a9901891f412879293ec93d1a01429452fa3cdadfb86ccb9", "timestamp": "0x5a", "totalDifficulty": "0x9", - "transactionsRoot": "0xe16929d9c7efab0f962c1ed8c1295ddff42d3026779ed1318ea079ca580ee4cb" -} + "transactionsRoot": "0xf3f69c61b639254ec6538351b9edaebce124270a70dd2d7fbc8d197b2a7cd928" +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json index 93e2b93378..7d13c8657e 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json @@ -1,24 +1,24 @@ { - "baseFeePerGas": "0x5d21dba00", + "baseFeePerGas": "0x1", "blobGasUsed": "0x0", "blockGasCost": "0x0", "difficulty": "0x1", "excessBlobGas": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x7a1200", + "extraData": "0x000000000098447800000000000052080000000000000000", + "gasLimit": "0x989680", "gasUsed": "0x5208", - "hash": "0x0b01774210aec0d5e0969a2e2cf0d6ec95ede0e7e9692d2e4be1d0779c9059c1", + "hash": "0x0b1d5db9740143d57114cc750c89ec59d75276798a76aa24255bcaaf9fcbc255", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0ac6abf1efe35140d080b10789a0c0581a7f4b040558920fcb86325bbb7fc0a5", + "parentHash": "0xef08fe152b50ff9a4220f2ba7c27f07eaa00abb156fd44ce513f6ff67f0c03e9", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x2b8307a066fd4575aca1fa6b42ef2c3a860a9c40337ea0d647c9f25e22062e34", + "stateRoot": "0xda6a753ddf04cde2621800ed8ce40fa9a09328789e5b309f0e32b4827262ae61", "timestamp": "0x64", "totalDifficulty": "0xa", - "transactionsRoot": "0x69ff8003291e1cd08f75d174f070618f7291e4540b2e33f60b3375743e3fda01" -} + "transactionsRoot": "0x4022accb18056de5994cfb85f3c2721a86c9b1de72ef02f3b224e9c913a18a10" +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json index 84be5d1a9a..51918e7c31 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-blob-tx.json @@ -1,18 +1,18 @@ { "blobGasPrice": "0x1", "blobGasUsed": "0x20000", - "blockHash": "0xff73bf27fcb39258f9c4a2f7f6eb018f7029f2d5bd960a63ebb4d7ecd8044545", + "blockHash": "0xd74e08700a0b69f81670d23e3ae4095f1bb5a7a3a93e131ca26747b510de8d03", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba01", + "effectiveGasPrice": "0x2", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x7e71344129674f4bbfdaa86313d005a96581993d93ae3a30d81b13fa25579eb2", + "transactionHash": "0x77255f1a75d6c0252a56539ad11edf9047df59dc390085946b410f406b9cd254", "transactionIndex": "0x0", "type": "0x3" -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json index e9e995f839..919881e842 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-tx.json @@ -1,5 +1,5 @@ { - "blockHash": "0x08bd14928be51a5496c0bdcccfc53184052485fa3bb8fa7b74f2ce7897036a0c", + "blockHash": "0x67bc227618d9f281e84b55dceea251bcbdd1061217a469f85f9af7e04c14a1fb", "blockNumber": "0x2", "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", "cumulativeGasUsed": "0xcf50", @@ -13,4 +13,4 @@ "transactionHash": "0x3b727d5e08e2176d96ee1bea244f772b592acd2cda1acc3d822c8b7f3de362f9", "transactionIndex": "0x0", "type": "0x0" -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json index fc633368be..ef38729ad9 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-create-contract-with-access-list.json @@ -1,16 +1,16 @@ { - "blockHash": "0xea28a367715debefc3b6d9f5ed5ab5b8d3a13b956e87f05f148852d3e1e522b5", + "blockHash": "0x46e967065beb0fd473a0e74420803329bac55b2bfadc3e70957945e3b4b6b3da", "blockNumber": "0x5", "contractAddress": "0xfdaa97661a584d977b4d3abb5370766ff5b86a18", "cumulativeGasUsed": "0xe01c", - "effectiveGasPrice": "0x5d21dba00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0xe01c", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": null, - "transactionHash": "0x8afe030574f663fe5096371d6f58a6287bfb3e0c73a5050220f5775a08e7abc9", + "transactionHash": "0x9a012322bddd6075c93dda3f5ad1c782fdd3552510fb7bf66ca87f6112550f46", "transactionIndex": "0x0", "type": "0x1" -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json b/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json index 885e9f0b3d..0e9e807937 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-dynamic-tx-with-logs.json @@ -1,16 +1,16 @@ { - "blockHash": "0xfa29fee1c5195fda47b23d3ce5259e314eb7578d18b76b36068d0e321db024e1", + "blockHash": "0x8cbe87a61fa9bb8a89bac2ff327f75e18d6b53618dabc9788f7f61e4d6c43421", "blockNumber": "0x4", "contractAddress": null, "cumulativeGasUsed": "0x538d", - "effectiveGasPrice": "0x5d21dbbf4", + "effectiveGasPrice": "0x1f5", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x538d", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x0", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x4e1e9194ca6f9d4e1736e9e441f66104f273548ed6d91b236a5f9c2ea10fa06d", + "transactionHash": "0x8416458a5e36b7b2f33020bd43d121c8d42c787d743b6eaf64ef09d663892b40", "transactionIndex": "0x0", "type": "0x2" -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json b/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json index 80be7cb97e..713a248cfa 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-normal-transfer-tx.json @@ -1,16 +1,16 @@ { - "blockHash": "0xf9081fe79fcdfd6a743577cc42fa17bec5e6cc1ebf5807b771724bf88b454b71", + "blockHash": "0x713ac10c7315b3ec44de14280f4422852dd151dd48619e9ae3827f230665c0cd", "blockNumber": "0x1", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x5d21dba00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xdf92bc7c4c0341ecbdcd2a3ca7011fe9e21df4b8553bf0c8caabe6cb4a1aee26", + "transactionHash": "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389", "transactionIndex": "0x0", "type": "0x0" -} +} \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json b/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json index 3fea31ef63..fb572fe733 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json @@ -1,9 +1,9 @@ { - "blockHash": "0xd82a2ecb764df020971408362eed2f6521c9a7ae38ab991aba7c6ddd60ba7e64", + "blockHash": "0x21e527bcf2f59792ad6e35ba7cf3f92a3f319ed7d74581371a0c3a6eb53d4fd7", "blockNumber": "0x3", "contractAddress": null, "cumulativeGasUsed": "0x5e28", - "effectiveGasPrice": "0x5d21dba00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5e28", "logs": [ @@ -16,9 +16,9 @@ ], "data": "0x000000000000000000000000000000000000000000000000000000000000000d", "blockNumber": "0x3", - "transactionHash": "0x7366a7738f47e32f5b6d292ca064b6b66f295d3931533a3745975be1191fccdf", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", - "blockHash": "0xd82a2ecb764df020971408362eed2f6521c9a7ae38ab991aba7c6ddd60ba7e64", + "blockHash": "0x21e527bcf2f59792ad6e35ba7cf3f92a3f319ed7d74581371a0c3a6eb53d4fd7", "logIndex": "0x0", "removed": false } @@ -26,7 +26,7 @@ "logsBloom": "0x00000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000000000000008000000000000000000000000000000000020000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000400000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000", "status": "0x1", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x7366a7738f47e32f5b6d292ca064b6b66f295d3931533a3745975be1191fccdf", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", "type": "0x0" -} +} \ No newline at end of file diff --git a/params/config_test.go b/params/config_test.go index b6e017bb1f..ba6e9533eb 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -283,6 +283,7 @@ func TestChainConfigMarshalWithUpgrades(t *testing.T) { }, &extras.ChainConfig{ FeeConfig: DefaultFeeConfig, + ACP224FeeConfig: DefaultACP224FeeConfig, AllowFeeRecipients: false, NetworkUpgrades: extras.NetworkUpgrades{ SubnetEVMTimestamp: utils.NewUint64(0), @@ -302,6 +303,12 @@ func TestChainConfigMarshalWithUpgrades(t *testing.T) { result, err := json.Marshal(&config) require.NoError(t, err) expectedJSON := `{ + "acp224FeeConfig": { + "targetGas": 20000000, + "minGasPrice": 1, + "timeToFillCapacity": 5, + "timeToDouble": 60 + }, "chainId": 1, "feeConfig": { "gasLimit": 8000000, diff --git a/params/extras/config.go b/params/extras/config.go index 1765379e03..889d1d36ff 100644 --- a/params/extras/config.go +++ b/params/extras/config.go @@ -34,7 +34,7 @@ var ( } DefaultACP224FeeConfig = commontype.ACP224FeeConfig{ - TargetGas: big.NewInt(1_000_000), + TargetGas: big.NewInt(20_000_000), MinGasPrice: big.NewInt(1), TimeToFillCapacity: big.NewInt(5), TimeToDouble: big.NewInt(60), @@ -70,6 +70,7 @@ var ( TestGraniteChainConfig = copyAndSet(TestFortunaChainConfig, func(c *ChainConfig) { c.NetworkUpgrades.GraniteTimestamp = utils.NewUint64(0) + c.ACP224FeeConfig = DefaultACP224FeeConfig }) TestChainConfig = copyConfig(TestGraniteChainConfig) diff --git a/params/extras/network_upgrades.go b/params/extras/network_upgrades.go index 8da5451809..003f785af2 100644 --- a/params/extras/network_upgrades.go +++ b/params/extras/network_upgrades.go @@ -208,7 +208,8 @@ func GetNetworkUpgrades(agoUpgrade upgrade.Config) NetworkUpgrades { // Fortuna was initially an optional upgrade upon its release, but it is required as of the Granite upgrade. // Chains can still opt to not activate Fortuna, but they will not be able to activate the Granite upgrade. // Chains can also override this timestamp with a custom upgrade configuration. - FortunaTimestamp: utils.TimeToNewUint64(agoUpgrade.GraniteTime), + // FortunaTimestamp: utils.TimeToNewUint64(agoUpgrade.GraniteTime), + FortunaTimestamp: nil, GraniteTimestamp: utils.TimeToNewUint64(agoUpgrade.GraniteTime), } } diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index 0f014bd154..d4ef80b9c7 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -7,7 +7,6 @@ import ( "math/big" "testing" - "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" @@ -201,7 +200,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp1 Number: big.NewInt(1), }, timestamp: 1, - want: big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), + want: big.NewInt(int64(acp176Config.MinGasPrice)), }, { name: "fortuna_genesis_block", @@ -209,7 +208,7 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp1 parent: &types.Header{ Number: big.NewInt(0), }, - want: big.NewInt(int64(acp176.DefaultACP176Config.MinGasPrice)), + want: big.NewInt(int64(acp176Config.MinGasPrice)), }, { name: "fortuna_invalid_fee_state", @@ -220,35 +219,35 @@ func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp1 }, wantErr: acp176.ErrStateInsufficientLength, }, - { - name: "fortuna_current", - upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - Extra: (&acp176.State{ - Gas: gas.State{ - Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * [acp176.TargetToPriceUpdateConversion] - }, - TargetExcess: 13_605_152, // 2^25 * ln(1.5) - }).Bytes(), - }, - want: big.NewInt(1_000_000_002), // nAVAX + 2 due to rounding - }, - { - name: "fortuna_decrease", - upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - Extra: (&acp176.State{ - Gas: gas.State{ - Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * [acp176.TargetToPriceUpdateConversion] - }, - TargetExcess: 13_605_152, // 2^25 * ln(1.5) - }).Bytes(), - }, - timestamp: 1, - want: big.NewInt(988_571_555), // e^((2_704_386_192 - 1_500_000) / 1_500_000 / [acp176.TargetToPriceUpdateConversion]) - }, + // { + // name: "fortuna_current", + // upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + // parent: &types.Header{ + // Number: big.NewInt(1), + // Extra: (&acp176.State{ + // Gas: gas.State{ + // Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * [acp176.TargetToPriceUpdateConversion] + // }, + // TargetExcess: 13_605_152, // 2^25 * ln(1.5) + // }).Bytes(), + // }, + // want: big.NewInt(1_000_000_002), // nAVAX + 2 due to rounding + // }, + // { + // name: "fortuna_decrease", + // upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + // parent: &types.Header{ + // Number: big.NewInt(1), + // Extra: (&acp176.State{ + // Gas: gas.State{ + // Excess: 2_704_386_192, // 1_500_000 * ln(nAVAX) * [acp176.TargetToPriceUpdateConversion] + // }, + // TargetExcess: 13_605_152, // 2^25 * ln(1.5) + // }).Bytes(), + // }, + // timestamp: 1, + // want: big.NewInt(988_571_555), // e^((2_704_386_192 - 1_500_000) / 1_500_000 / [acp176.TargetToPriceUpdateConversion]) + // }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/plugin/evm/header/block_gas_cost_test.go b/plugin/evm/header/block_gas_cost_test.go index 73e9760e37..c6e8c2b495 100644 --- a/plugin/evm/header/block_gas_cost_test.go +++ b/plugin/evm/header/block_gas_cost_test.go @@ -35,7 +35,11 @@ var ( TimeToFillCapacity: big.NewInt(5), TimeToDouble: big.NewInt(60), } - testACP176Config = acp176.DefaultACP176Config + testACP176Config = acp176.Config{ + MinGasPrice: 1, + TimeToFillCapacity: 5, + TimeToDouble: 60, + } testFeeConfigDouble = commontype.FeeConfig{ MinBlockGasCost: big.NewInt(2), diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index 0271f31f75..6394f9815a 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -125,8 +125,8 @@ func TestExtraPrefix(t *testing.T) { }, want: (&acp176.State{ Gas: gas.State{ - Capacity: acp176.MinMaxPerSecond - 6, - Excess: 6, + Capacity: acp176.MinMaxPerSecond - 1, + Excess: 1, }, TargetExcess: 0, }).Bytes(), @@ -144,8 +144,8 @@ func TestExtraPrefix(t *testing.T) { desiredTargetExcess: (*gas.Gas)(utils.NewUint64(3)), want: (&acp176.State{ Gas: gas.State{ - Capacity: acp176.MinMaxPerSecond - 3, - Excess: 3, + Capacity: acp176.MinMaxPerSecond - 2, + Excess: 2, }, TargetExcess: 3, }).Bytes(), @@ -178,7 +178,7 @@ func TestExtraPrefix(t *testing.T) { Number: big.NewInt(1), Extra: (&acp176.State{ Gas: gas.State{ - Capacity: 20_039_100, // [acp176.MinTargetPerSecond] * e^(2*[acp176.MaxTargetExcessDiff] / [acp176.TargetConversion]) + Capacity: 10_019_550, // [acp176.MinMaxCapacity] * e^(2*[acp176.MaxTargetExcessDiff] / [acp176.TargetConversion]) Excess: 2_000_000_000 - 3, }, TargetExcess: 2 * acp176.MaxTargetExcessDiff, @@ -190,8 +190,8 @@ func TestExtraPrefix(t *testing.T) { desiredTargetExcess: (*gas.Gas)(utils.NewUint64(0)), want: (&acp176.State{ Gas: gas.State{ - Capacity: 20_019_540, // [acp176.MinTargetPerSecond] * e^([acp176.MaxTargetExcessDiff] / [acp176.TargetConversion]) - Excess: 1_998_047_816, // 2M * NewTarget / OldTarget + Capacity: 10_009_770, // [acp176.MinTargetPerSecond] * e^([acp176.MaxTargetExcessDiff] / [acp176.TargetConversion]) + Excess: 1_998_047_815, // 2M * NewTarget / OldTarget }, TargetExcess: acp176.MaxTargetExcessDiff, }).Bytes(), diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index 680d141d5e..fd9e6fc327 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -7,7 +7,6 @@ import ( "math/big" "testing" - "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/core/types" @@ -56,7 +55,7 @@ func GasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Config acp parent: &types.Header{ Number: big.NewInt(0), }, - want: uint64(acp176.DefaultACP176Config.MinMaxCapacity()), + want: uint64(acp176Config.MinMaxCapacity()), }, { name: "pre_subnet_evm", @@ -91,14 +90,6 @@ func TestVerifyGasUsed(t *testing.T) { header *types.Header want error }{ - { - name: "fortuna_gas_used_overflow", - upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, - header: &types.Header{ - GasUsed: math.MaxUint[uint64](), - }, - want: math.ErrOverflow, - }, { name: "fortuna_invalid_capacity", upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, @@ -133,7 +124,8 @@ func TestVerifyGasUsed(t *testing.T) { Time: 1, GasUsed: acp176.MinMaxPerSecond, }, - want: nil, + acp176Config: testACP176Config, + want: nil, }, } for _, test := range tests { @@ -180,7 +172,7 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Conf Number: big.NewInt(0), }, header: &types.Header{ - GasLimit: uint64(acp176.DefaultACP176Config.MinMaxCapacity()) + 1, + GasLimit: uint64(acp176Config.MinMaxCapacity()) + 1, }, want: errInvalidGasLimit, }, @@ -191,7 +183,7 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig, acp176Conf Number: big.NewInt(0), }, header: &types.Header{ - GasLimit: uint64(acp176.DefaultACP176Config.MinMaxCapacity()), + GasLimit: uint64(acp176Config.MinMaxCapacity()), }, }, { @@ -276,9 +268,10 @@ func TestGasCapacity(t *testing.T) { wantErr error }{ { - name: "subnet_evm", - upgrades: extras.TestSubnetEVMChainConfig.NetworkUpgrades, - want: 0, // TODO: XXX Handle feeConfig with Fortuna here + name: "subnet_evm", + upgrades: extras.TestSubnetEVMChainConfig.NetworkUpgrades, + feeConfig: testFeeConfig, + want: testFeeConfig.GasLimit.Uint64(), }, { name: "fortuna_invalid_header", @@ -294,8 +287,9 @@ func TestGasCapacity(t *testing.T) { parent: &types.Header{ Number: big.NewInt(0), }, - timestamp: 1, - want: acp176.MinMaxPerSecond, + timestamp: 1, + acp176Config: testACP176Config, + want: acp176.MinMaxPerSecond, }, } for _, test := range tests { diff --git a/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go b/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go new file mode 100644 index 0000000000..951c00a26e --- /dev/null +++ b/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go @@ -0,0 +1,169 @@ +package acp224feemanagertest + +import ( + "fmt" + "math/big" + "testing" + + "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" + "github.com/ava-labs/subnet-evm/commontype" + "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" + "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" + "github.com/ava-labs/subnet-evm/precompile/precompiletest" + "github.com/ava-labs/subnet-evm/utils" + + "github.com/ava-labs/libevm/common" + "go.uber.org/mock/gomock" +) + +// TestVerify tests the verification of Config. +func TestVerify(t *testing.T) { + admins := []common.Address{allowlisttest.TestAdminAddr} + enableds := []common.Address{allowlisttest.TestEnabledAddr} + managers := []common.Address{allowlisttest.TestManagerAddr} + tests := map[string]precompiletest.ConfigVerifyTest{ + "valid config": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ValidTestACP224FeeConfig), + ChainConfig: func() precompileconfig.ChainConfig { + config := precompileconfig.NewMockChainConfig(gomock.NewController(t)) + config.EXPECT().IsDurango(gomock.Any()).Return(true).AnyTimes() + return config + }(), + ExpectedError: "", + }, + "invalid - nil TargetGas": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: nil, + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + }), + ExpectedError: "targetGas cannot be nil", + }, + "invalid - nil MinGasPrice": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: nil, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + }), + ExpectedError: "minGasPrice cannot be nil", + }, + "invalid - nil TimeToFillCapacity": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: nil, + TimeToDouble: big.NewInt(60), + }), + ExpectedError: "timeToFillCapacity cannot be nil", + }, + "invalid - nil TimeToDouble": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: nil, + }), + ExpectedError: "timeToDouble cannot be nil", + }, + "invalid - TargetGas <= 0": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(0), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + }), + ExpectedError: "targetGas = 0 cannot be less than or equal to 0", + }, + "invalid - MinGasPrice <= 0": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: big.NewInt(0), + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + }), + ExpectedError: "minGasPrice = 0 cannot be less than or equal to 0", + }, + "invalid - TimeToFillCapacity < 0": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(-1), + TimeToDouble: big.NewInt(60), + }), + ExpectedError: "timeToFillCapacity = -1 cannot be less than 0", + }, + "invalid - TimeToDouble < 0": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(-1), + }), + ExpectedError: "timeToDouble = -1 cannot be less than 0", + }, + "invalid - TimeToFillCapacity > MaxTimeToFillCapacity": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(acp176.MaxTimeToFillCapacity + 1), + TimeToDouble: big.NewInt(60), + }), + ExpectedError: fmt.Sprintf("timeToFillCapacity = %d cannot be greater than %d", big.NewInt(acp176.MaxTimeToFillCapacity+1), acp176.MaxTimeToFillCapacity), + }, + "invalid - TimeToDouble > MaxTimeToDouble": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(acp176.MaxTimeToDouble + 1), + }), + ExpectedError: fmt.Sprintf("timeToDouble = %d cannot be greater than %d", big.NewInt(acp176.MaxTimeToDouble+1), acp176.MaxTimeToDouble), + }, + } + // Verify the precompile with the allowlist. + // This adds allowlist verify tests to your custom tests + // and runs them all together. + // Even if you don't add any custom tests, keep this. This will still + // run the default allowlist verify tests. + allowlisttest.VerifyPrecompileWithAllowListTests(t, acp224feemanager.Module, tests) +} + +// TestEqual tests the equality of Config with other precompile configs. +func TestEqual(t *testing.T) { + admins := []common.Address{allowlisttest.TestAdminAddr} + enableds := []common.Address{allowlisttest.TestEnabledAddr} + managers := []common.Address{allowlisttest.TestManagerAddr} + tests := map[string]precompiletest.ConfigEqualTest{ + "non-nil config and nil other": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{}), + Other: nil, + Expected: false, + }, + "different type": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{}), + Other: precompileconfig.NewMockConfig(gomock.NewController(t)), + Expected: false, + }, + "different timestamp": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{}), + Other: acp224feemanager.NewConfig(utils.NewUint64(4), admins, enableds, managers, &commontype.ACP224FeeConfig{}), + Expected: false, + }, + "same config": { + Config: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{}), + Other: acp224feemanager.NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{}), + Expected: true, + }, + // CUSTOM CODE STARTS HERE + // Add your own Equal tests here + } + // Run allow list equal tests. + // This adds allowlist equal tests to your custom tests + // and runs them all together. + // Even if you don't add any custom tests, keep this. This will still + // run the default allowlist equal tests. + allowlisttest.EqualPrecompileWithAllowListTests(t, acp224feemanager.Module, tests) +} diff --git a/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go b/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go new file mode 100644 index 0000000000..d81db2552a --- /dev/null +++ b/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go @@ -0,0 +1,402 @@ +package acp224feemanagertest + +import ( + "math/big" + "testing" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/subnet-evm/commontype" + "github.com/ava-labs/subnet-evm/core/extstate" + "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" + "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" + "github.com/ava-labs/subnet-evm/precompile/precompiletest" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +var ( + _ = vm.ErrOutOfGas + _ = big.NewInt + _ = common.Big0 + _ = require.New +) + +// These tests are run against the precompile contract directly with +// the given input and expected output. They're just a guide to +// help you write your own tests. These tests are for general cases like +// allowlist, readOnly behaviour, and gas cost. You should write your own +// tests for specific cases. +var ( + testBlockNumber = big.NewInt(7) + testDefaultUpdatedFeeConfig = commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + } + tests = map[string]precompiletest.PrecompileTest{ + "calling getFeeConfig from NoRole should succeed": { + Caller: allowlisttest.TestNoRoleAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfig() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigOutput(testDefaultUpdatedFeeConfig) + if err != nil { + panic(err) + } + return packedOutput + }(), + SuppliedGas: acp224feemanager.GetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling getFeeConfig from Enabled should succeed": { + Caller: allowlisttest.TestEnabledAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfig() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigOutput(testDefaultUpdatedFeeConfig) + if err != nil { + panic(err) + } + return packedOutput + }(), + SuppliedGas: acp224feemanager.GetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling getFeeConfig from Manager should succeed": { + Caller: allowlisttest.TestManagerAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfig() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigOutput(testDefaultUpdatedFeeConfig) + if err != nil { + panic(err) + } + return packedOutput + }(), + SuppliedGas: acp224feemanager.GetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling getFeeConfig from Admin should succeed": { + Caller: allowlisttest.TestAdminAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfig() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigOutput(testDefaultUpdatedFeeConfig) + if err != nil { + panic(err) + } + return packedOutput + }(), + SuppliedGas: acp224feemanager.GetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "insufficient gas for getFeeConfig should fail": { + Caller: common.Address{1}, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfig() + require.NoError(t, err) + return input + }, + SuppliedGas: acp224feemanager.GetFeeConfigGasCost - 1, + ReadOnly: false, + ExpectedErr: vm.ErrOutOfGas.Error(), + }, + "calling getFeeConfigLastChangedAt from NoRole should succeed": { + Caller: allowlisttest.TestNoRoleAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigLastChangedAtOutput(testBlockNumber) + if err != nil { + panic(err) + } + return packedOutput + }(), + AfterHook: func(t testing.TB, state *extstate.StateDB) { + feeConfig := acp224feemanager.GetStoredFeeConfig(state) + require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + require.Equal(t, testBlockNumber, lastChangedAt) + }, + SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling getFeeConfigLastChangedAt from Enabled should succeed": { + Caller: allowlisttest.TestEnabledAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigLastChangedAtOutput(testBlockNumber) + if err != nil { + panic(err) + } + return packedOutput + }(), + AfterHook: func(t testing.TB, state *extstate.StateDB) { + feeConfig := acp224feemanager.GetStoredFeeConfig(state) + require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + require.Equal(t, testBlockNumber, lastChangedAt) + }, + SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling getFeeConfigLastChangedAt from Manager should succeed": { + Caller: allowlisttest.TestManagerAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigLastChangedAtOutput(testBlockNumber) + if err != nil { + panic(err) + } + return packedOutput + }(), + AfterHook: func(t testing.TB, state *extstate.StateDB) { + feeConfig := acp224feemanager.GetStoredFeeConfig(state) + require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + require.Equal(t, testBlockNumber, lastChangedAt) + }, + SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling getFeeConfigLastChangedAt from Admin should succeed": { + Caller: allowlisttest.TestAdminAddr, + BeforeHook: func(t testing.TB, state *extstate.StateDB) { + blockContext := contract.NewMockBlockContext(gomock.NewController(t)) + blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) + allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + }, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + packedOutput, err := acp224feemanager.PackGetFeeConfigLastChangedAtOutput(testBlockNumber) + if err != nil { + panic(err) + } + return packedOutput + }(), + AfterHook: func(t testing.TB, state *extstate.StateDB) { + feeConfig := acp224feemanager.GetStoredFeeConfig(state) + require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + require.Equal(t, testBlockNumber, lastChangedAt) + }, + SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "insufficient gas for getFeeConfigLastChangedAt should fail": { + Caller: common.Address{1}, + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() + require.NoError(t, err) + return input + }, + SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost - 1, + ReadOnly: false, + ExpectedErr: vm.ErrOutOfGas.Error(), + }, + "calling setFeeConfig from NoRole should fail": { + Caller: allowlisttest.TestNoRoleAddr, + BeforeHook: allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address), + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackSetFeeConfig(testDefaultUpdatedFeeConfig) + require.NoError(t, err) + return input + }, + SuppliedGas: acp224feemanager.SetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: acp224feemanager.ErrCannotSetFeeConfig.Error(), + }, + "calling setFeeConfig from Enabled should succeed": { + Caller: allowlisttest.TestEnabledAddr, + BeforeHook: allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address), + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackSetFeeConfig(testDefaultUpdatedFeeConfig) + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + return []byte{} + }(), + SuppliedGas: acp224feemanager.SetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling setFeeConfig from Manager should succeed": { + Caller: allowlisttest.TestManagerAddr, + BeforeHook: allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address), + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackSetFeeConfig(testDefaultUpdatedFeeConfig) + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + return []byte{} + }(), + SuppliedGas: acp224feemanager.SetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "calling setFeeConfig from Admin should succeed": { + Caller: allowlisttest.TestAdminAddr, + BeforeHook: allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address), + InputFn: func(t testing.TB) []byte { + input, err := acp224feemanager.PackSetFeeConfig(testDefaultUpdatedFeeConfig) + require.NoError(t, err) + return input + }, + ExpectedRes: func() []byte { + return []byte{} + }(), + SuppliedGas: acp224feemanager.SetFeeConfigGasCost, + ReadOnly: false, + ExpectedErr: "", + }, + "readOnly setFeeConfig should fail": { + Caller: common.Address{1}, + InputFn: func(t testing.TB) []byte { + testInput := commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + } + input, err := acp224feemanager.PackSetFeeConfig(testInput) + require.NoError(t, err) + return input + }, + SuppliedGas: acp224feemanager.SetFeeConfigGasCost, + ReadOnly: true, + ExpectedErr: vm.ErrWriteProtection.Error(), + }, + "insufficient gas for setFeeConfig should fail": { + Caller: common.Address{1}, + InputFn: func(t testing.TB) []byte { + testInput := commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(10_000_000), + MinGasPrice: common.Big1, + TimeToFillCapacity: big.NewInt(5), + TimeToDouble: big.NewInt(60), + } + input, err := acp224feemanager.PackSetFeeConfig(testInput) + require.NoError(t, err) + return input + }, + SuppliedGas: acp224feemanager.SetFeeConfigGasCost - 1, + ReadOnly: false, + ExpectedErr: vm.ErrOutOfGas.Error(), + }, + } +) + +// TestACP224FeeManagerRun tests the Run function of the precompile contract. +func TestACP224FeeManagerRun(t *testing.T) { + allowlisttest.RunPrecompileWithAllowListTests(t, acp224feemanager.Module, tests) +} + +// TestPackUnpackFeeConfigUpdatedEventData tests the Pack/UnpackFeeConfigUpdatedEventData. +func TestPackUnpackFeeConfigUpdatedEventData(t *testing.T) { + var senderInput common.Address = acp224feemanager.ContractAddress + oldFeeConfig := commontype.ValidTestACP224FeeConfig + newFeeConfig := commontype.ACP224FeeConfig{ + TargetGas: big.NewInt(42_000_000), + MinGasPrice: big.NewInt(42), + TimeToFillCapacity: big.NewInt(42), + TimeToDouble: big.NewInt(42), + } + + dataInput := acp224feemanager.FeeConfigUpdatedEventData{ + OldFeeConfig: oldFeeConfig, + NewFeeConfig: newFeeConfig, + } + + _, data, err := acp224feemanager.PackFeeConfigUpdatedEvent( + senderInput, + dataInput, + ) + require.NoError(t, err) + + unpacked, err := acp224feemanager.UnpackFeeConfigUpdatedEventData(data) + require.NoError(t, err) + require.Equal(t, dataInput, unpacked) +} diff --git a/precompile/contracts/acp224feemanager/config.go b/precompile/contracts/acp224feemanager/config.go index 03e9c25d31..5d87949941 100644 --- a/precompile/contracts/acp224feemanager/config.go +++ b/precompile/contracts/acp224feemanager/config.go @@ -1,7 +1,3 @@ -// Code generated -// This file is a generated precompile contract config with stubbed abstract functions. -// The file is generated by a template. Please inspect every code and comment in this file before use. - package acp224feemanager import ( diff --git a/precompile/contracts/acp224feemanager/config_test.go b/precompile/contracts/acp224feemanager/config_test.go deleted file mode 100644 index e98cef5c27..0000000000 --- a/precompile/contracts/acp224feemanager/config_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated -// This file is a generated precompile config test with the skeleton of test functions. -// The file is generated by a template. Please inspect every code and comment in this file before use. - -package acp224feemanager - -// import ( -// "testing" - -// "github.com/ava-labs/subnet-evm/commontype" -// "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" -// "github.com/ava-labs/subnet-evm/precompile/precompileconfig" -// "github.com/ava-labs/subnet-evm/precompile/precompiletest" -// "github.com/ava-labs/subnet-evm/utils" - -// "github.com/ava-labs/libevm/common" -// "go.uber.org/mock/gomock" -// ) - -// // TestVerify tests the verification of Config. -// func TestVerify(t *testing.T) { -// admins := []common.Address{allowlisttest.TestAdminAddr} -// enableds := []common.Address{allowlisttest.TestEnabledAddr} -// managers := []common.Address{allowlisttest.TestManagerAddr} -// tests := map[string]precompiletest.ConfigVerifyTest{ -// "valid config": { -// Config: NewConfig(utils.NewUint64(3), admins, enableds, managers, &commontype.ACP224FeeConfig{ -// TargetGas: utils.NewUint64(1000000), -// MinGasPrice: utils.NewUint64(1000000), -// TimeToFillCapacity: utils.NewUint64(1000000), -// TimeToDouble: utils.NewUint64(1000000), -// }), -// ChainConfig: func() precompileconfig.ChainConfig { -// config := precompileconfig.NewMockChainConfig(gomock.NewController(t)) -// config.EXPECT().IsDurango(gomock.Any()).Return(true).AnyTimes() -// return config -// }(), -// ExpectedError: "", -// }, -// // CUSTOM CODE STARTS HERE -// // Add your own Verify tests here, e.g.: -// // "your custom test name": { -// // Config: NewConfig(utils.NewUint64(3), admins, enableds, managers), -// // ExpectedError: ErrYourCustomError.Error(), -// // }, -// } -// // Verify the precompile with the allowlist. -// // This adds allowlist verify tests to your custom tests -// // and runs them all together. -// // Even if you don't add any custom tests, keep this. This will still -// // run the default allowlist verify tests. -// allowlisttest.VerifyPrecompileWithAllowListTests(t, Module, tests) -// } - -// // TestEqual tests the equality of Config with other precompile configs. -// func TestEqual(t *testing.T) { -// admins := []common.Address{allowlisttest.TestAdminAddr} -// enableds := []common.Address{allowlisttest.TestEnabledAddr} -// managers := []common.Address{allowlisttest.TestManagerAddr} -// tests := map[string]precompiletest.ConfigEqualTest{ -// "non-nil config and nil other": { -// Config: NewConfig(utils.NewUint64(3), admins, enableds, managers), -// Other: nil, -// Expected: false, -// }, -// "different type": { -// Config: NewConfig(utils.NewUint64(3), admins, enableds, managers), -// Other: precompileconfig.NewMockConfig(gomock.NewController(t)), -// Expected: false, -// }, -// "different timestamp": { -// Config: NewConfig(utils.NewUint64(3), admins, enableds, managers), -// Other: NewConfig(utils.NewUint64(4), admins, enableds, managers), -// Expected: false, -// }, -// "same config": { -// Config: NewConfig(utils.NewUint64(3), admins, enableds, managers), -// Other: NewConfig(utils.NewUint64(3), admins, enableds, managers), -// Expected: true, -// }, -// // CUSTOM CODE STARTS HERE -// // Add your own Equal tests here -// } -// // Run allow list equal tests. -// // This adds allowlist equal tests to your custom tests -// // and runs them all together. -// // Even if you don't add any custom tests, keep this. This will still -// // run the default allowlist equal tests. -// allowlisttest.EqualPrecompileWithAllowListTests(t, Module, tests) -// } diff --git a/precompile/contracts/acp224feemanager/contract.go b/precompile/contracts/acp224feemanager/contract.go index 5c79daa18a..ee3c91267e 100644 --- a/precompile/contracts/acp224feemanager/contract.go +++ b/precompile/contracts/acp224feemanager/contract.go @@ -41,7 +41,11 @@ const ( // You should also increase gas costs of functions that read from AllowList storage. GetFeeConfigGasCost uint64 = contract.ReadGasCostPerSlot * numFeeConfigField GetFeeConfigLastChangedAtGasCost uint64 = contract.ReadGasCostPerSlot - SetFeeConfigGasCost uint64 = contract.WriteGasCostPerSlot*(numFeeConfigField+1) + allowlist.ReadAllowListGasCost // plus one for setting last changed at + FeeConfigUpdatedEventGasCost uint64 = (contract.LogGas) + (contract.LogTopicGas * 2) + (contract.LogDataGas * numFeeConfigField * common.HashLength * 2) + SetFeeConfigGasCost uint64 = allowlist.ReadAllowListGasCost + + contract.WriteGasCostPerSlot*(numFeeConfigField+1) + // plus one for setting last changed at + GetFeeConfigGasCost + // for reading existing fee config to be emitted in event + FeeConfigUpdatedEventGasCost ) var ( @@ -254,10 +258,6 @@ func setFeeConfig(accessibleState contract.AccessibleState, caller common.Addres OldFeeConfig: oldConfig, NewFeeConfig: feeConfig, } - gas := GetFeeConfigUpdatedEventGasCost(eventData) - if remainingGas, err = contract.DeductGas(remainingGas, gas); err != nil { - return nil, 0, err - } topics, data, err := PackFeeConfigUpdatedEvent( caller, eventData, diff --git a/precompile/contracts/acp224feemanager/contract_test.go b/precompile/contracts/acp224feemanager/contract_test.go deleted file mode 100644 index ab9c2d691f..0000000000 --- a/precompile/contracts/acp224feemanager/contract_test.go +++ /dev/null @@ -1,395 +0,0 @@ -// Code generated -// This file is a generated precompile contract test with the skeleton of test functions. -// The file is generated by a template. Please inspect every code and comment in this file before use. - -package acp224feemanager - -import ( - "math/big" - "testing" - - "github.com/ava-labs/libevm/common" - "github.com/ava-labs/libevm/core/vm" - "github.com/ava-labs/subnet-evm/commontype" - "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" - "github.com/ava-labs/subnet-evm/precompile/precompiletest" - "github.com/stretchr/testify/require" -) - -var ( - _ = vm.ErrOutOfGas - _ = big.NewInt - _ = common.Big0 - _ = require.New -) - -// These tests are run against the precompile contract directly with -// the given input and expected output. They're just a guide to -// help you write your own tests. These tests are for general cases like -// allowlist, readOnly behaviour, and gas cost. You should write your own -// tests for specific cases. -var ( - tests = map[string]precompiletest.PrecompileTest{ - "calling getFeeConfig from NoRole should succeed": { - Caller: allowlisttest.TestNoRoleAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfig() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output commontype.ACP224FeeConfig // CUSTOM CODE FOR AN OUTPUT - output = commontype.ACP224FeeConfig{} // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling getFeeConfig from Enabled should succeed": { - Caller: allowlisttest.TestEnabledAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfig() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output commontype.ACP224FeeConfig // CUSTOM CODE FOR AN OUTPUT - output = commontype.ACP224FeeConfig{} // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling getFeeConfig from Manager should succeed": { - Caller: allowlisttest.TestManagerAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfig() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output commontype.ACP224FeeConfig // CUSTOM CODE FOR AN OUTPUT - output = commontype.ACP224FeeConfig{} // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling getFeeConfig from Admin should succeed": { - Caller: allowlisttest.TestAdminAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfig() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output commontype.ACP224FeeConfig // CUSTOM CODE FOR AN OUTPUT - output = commontype.ACP224FeeConfig{} // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "insufficient gas for getFeeConfig should fail": { - Caller: common.Address{1}, - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfig() - require.NoError(t, err) - return input - }, - SuppliedGas: GetFeeConfigGasCost - 1, - ReadOnly: false, - ExpectedErr: vm.ErrOutOfGas.Error(), - }, - "calling getFeeConfigLastChangedAt from NoRole should succeed": { - Caller: allowlisttest.TestNoRoleAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfigLastChangedAt() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output *big.Int // CUSTOM CODE FOR AN OUTPUT - output = new(big.Int) // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigLastChangedAtOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigLastChangedAtGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling getFeeConfigLastChangedAt from Enabled should succeed": { - Caller: allowlisttest.TestEnabledAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfigLastChangedAt() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output *big.Int // CUSTOM CODE FOR AN OUTPUT - output = new(big.Int) // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigLastChangedAtOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigLastChangedAtGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling getFeeConfigLastChangedAt from Manager should succeed": { - Caller: allowlisttest.TestManagerAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfigLastChangedAt() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output *big.Int // CUSTOM CODE FOR AN OUTPUT - output = new(big.Int) // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigLastChangedAtOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigLastChangedAtGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling getFeeConfigLastChangedAt from Admin should succeed": { - Caller: allowlisttest.TestAdminAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfigLastChangedAt() - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - - var output *big.Int // CUSTOM CODE FOR AN OUTPUT - output = new(big.Int) // CUSTOM CODE FOR AN OUTPUT - packedOutput, err := PackGetFeeConfigLastChangedAtOutput(output) - if err != nil { - panic(err) - } - return packedOutput - }(), - SuppliedGas: GetFeeConfigLastChangedAtGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "insufficient gas for getFeeConfigLastChangedAt should fail": { - Caller: common.Address{1}, - InputFn: func(t testing.TB) []byte { - input, err := PackGetFeeConfigLastChangedAt() - require.NoError(t, err) - return input - }, - SuppliedGas: GetFeeConfigLastChangedAtGasCost - 1, - ReadOnly: false, - ExpectedErr: vm.ErrOutOfGas.Error(), - }, - "calling setFeeConfig from NoRole should fail": { - Caller: allowlisttest.TestNoRoleAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput commontype.ACP224FeeConfig - testInput = commontype.ACP224FeeConfig{} - input, err := PackSetFeeConfig(testInput) - require.NoError(t, err) - return input - }, - SuppliedGas: SetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: ErrCannotSetFeeConfig.Error(), - }, - "calling setFeeConfig from Enabled should succeed": { - Caller: allowlisttest.TestEnabledAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput commontype.ACP224FeeConfig - testInput = commontype.ACP224FeeConfig{} - input, err := PackSetFeeConfig(testInput) - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - // this function does not return an output, leave this one as is - packedOutput := []byte{} - return packedOutput - }(), - SuppliedGas: SetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling setFeeConfig from Manager should succeed": { - Caller: allowlisttest.TestManagerAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput commontype.ACP224FeeConfig - testInput = commontype.ACP224FeeConfig{} - input, err := PackSetFeeConfig(testInput) - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - // this function does not return an output, leave this one as is - packedOutput := []byte{} - return packedOutput - }(), - SuppliedGas: SetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "calling setFeeConfig from Admin should succeed": { - Caller: allowlisttest.TestAdminAddr, - BeforeHook: allowlisttest.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput commontype.ACP224FeeConfig - testInput = commontype.ACP224FeeConfig{} - input, err := PackSetFeeConfig(testInput) - require.NoError(t, err) - return input - }, - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: func() []byte { - // this function does not return an output, leave this one as is - packedOutput := []byte{} - return packedOutput - }(), - SuppliedGas: SetFeeConfigGasCost, - ReadOnly: false, - ExpectedErr: "", - }, - "readOnly setFeeConfig should fail": { - Caller: common.Address{1}, - InputFn: func(t testing.TB) []byte { - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput commontype.ACP224FeeConfig - testInput = commontype.ACP224FeeConfig{} - input, err := PackSetFeeConfig(testInput) - require.NoError(t, err) - return input - }, - SuppliedGas: SetFeeConfigGasCost, - ReadOnly: true, - ExpectedErr: vm.ErrWriteProtection.Error(), - }, - "insufficient gas for setFeeConfig should fail": { - Caller: common.Address{1}, - InputFn: func(t testing.TB) []byte { - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput commontype.ACP224FeeConfig - testInput = commontype.ACP224FeeConfig{} - input, err := PackSetFeeConfig(testInput) - require.NoError(t, err) - return input - }, - SuppliedGas: SetFeeConfigGasCost - 1, - ReadOnly: false, - ExpectedErr: vm.ErrOutOfGas.Error(), - }, - } -) - -// TestACP224FeeManagerRun tests the Run function of the precompile contract. -func TestACP224FeeManagerRun(t *testing.T) { - // Run tests with allowlist tests. - // This adds allowlist tests to your custom tests - // and runs them all together. - // Even if you don't add any custom tests, keep this. This will still - // run the default allowlist tests. - allowlisttest.RunPrecompileWithAllowListTests(t, Module, tests) -} - -// TestPackUnpackFeeConfigUpdatedEventData tests the Pack/UnpackFeeConfigUpdatedEventData. -func TestPackUnpackFeeConfigUpdatedEventData(t *testing.T) { - // CUSTOM CODE STARTS HERE - // set test inputs with proper values here - var senderInput common.Address = common.Address{} - - dataInput := FeeConfigUpdatedEventData{ - OldFeeConfig: commontype.ACP224FeeConfig{}, - NewFeeConfig: commontype.ACP224FeeConfig{}, - } - - _, data, err := PackFeeConfigUpdatedEvent( - senderInput, - dataInput, - ) - require.NoError(t, err) - - unpacked, err := UnpackFeeConfigUpdatedEventData(data) - require.NoError(t, err) - require.Equal(t, dataInput, unpacked) -} diff --git a/precompile/contracts/acp224feemanager/event.go b/precompile/contracts/acp224feemanager/event.go index 4b60d16dcd..606ca60740 100644 --- a/precompile/contracts/acp224feemanager/event.go +++ b/precompile/contracts/acp224feemanager/event.go @@ -7,7 +7,6 @@ package acp224feemanager import ( "github.com/ava-labs/libevm/common" "github.com/ava-labs/subnet-evm/commontype" - "github.com/ava-labs/subnet-evm/precompile/contract" ) // ACP224FeeManagerFeeConfigUpdated represents a FeeConfigUpdated non-indexed event data raised by the ACP224FeeManager contract. @@ -16,37 +15,6 @@ type FeeConfigUpdatedEventData struct { NewFeeConfig commontype.ACP224FeeConfig } -// GetFeeConfigUpdatedEventGasCost returns the gas cost of the event. -// The gas cost of an event is the base gas cost + the gas cost of the topics + the gas cost of the non-indexed data. -// The base gas cost and the gas cost of per topics are fixed and can be found in the contract package. -// The gas cost of the non-indexed data depends on the data type and the data size. -func GetFeeConfigUpdatedEventGasCost(data FeeConfigUpdatedEventData) uint64 { - gas := contract.LogGas // base gas cost - - // Add topics gas cost (2 topics) - // Topics always include the signature hash of the event. The rest are the indexed event arguments. - gas += contract.LogTopicGas * 2 - - // CUSTOM CODE STARTS HERE - // TODO: calculate gas cost for packing the data.oldFeeConfig according to the type. - // Keep in mind that the data here will be encoded using the ABI encoding scheme. - // So the computation cost might change according to the data type + data size and should be charged accordingly. - // i.e gas += LogDataGas * uint64(len(data.oldFeeConfig)) - gas += contract.LogDataGas // * ... - // CUSTOM CODE ENDS HERE - // CUSTOM CODE STARTS HERE - // TODO: calculate gas cost for packing the data.newFeeConfig according to the type. - // Keep in mind that the data here will be encoded using the ABI encoding scheme. - // So the computation cost might change according to the data type + data size and should be charged accordingly. - // i.e gas += LogDataGas * uint64(len(data.newFeeConfig)) - gas += contract.LogDataGas // * ... - // CUSTOM CODE ENDS HERE - - // CUSTOM CODE STARTS HERE - // TODO: do any additional gas cost calculation here (only if needed) - return gas -} - // PackFeeConfigUpdatedEvent packs the event into the appropriate arguments for FeeConfigUpdated. // It returns topic hashes and the encoded non-indexed data. func PackFeeConfigUpdatedEvent(sender common.Address, data FeeConfigUpdatedEventData) ([]common.Hash, []byte, error) { diff --git a/precompile/precompiletest/test_precompile.go b/precompile/precompiletest/test_precompile.go index 36790f7748..6d9d87c1cd 100644 --- a/precompile/precompiletest/test_precompile.go +++ b/precompile/precompiletest/test_precompile.go @@ -104,6 +104,7 @@ func (test PrecompileTest) setup(t testing.TB, module modules.Module, state *tes test.ChainConfigFn = func(ctrl *gomock.Controller) precompileconfig.ChainConfig { mockChainConfig := precompileconfig.NewMockChainConfig(ctrl) mockChainConfig.EXPECT().GetFeeConfig().AnyTimes().Return(commontype.ValidTestFeeConfig) + mockChainConfig.EXPECT().GetACP224FeeConfig().AnyTimes().Return(commontype.ValidTestACP224FeeConfig) mockChainConfig.EXPECT().AllowedFeeRecipients().AnyTimes().Return(false) mockChainConfig.EXPECT().IsDurango(gomock.Any()).AnyTimes().Return(true) return mockChainConfig From ca7174efb44bff96c6dc34b70f77e7e5c4f5d679 Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Tue, 16 Sep 2025 16:46:02 -0400 Subject: [PATCH 7/8] clean up todos --- params/extras/network_upgrades.go | 2 +- plugin/evm/header/base_fee.go | 1 - precompile/contracts/acp224feemanager/module.go | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/params/extras/network_upgrades.go b/params/extras/network_upgrades.go index 003f785af2..121fc80b23 100644 --- a/params/extras/network_upgrades.go +++ b/params/extras/network_upgrades.go @@ -205,7 +205,7 @@ func GetNetworkUpgrades(agoUpgrade upgrade.Config) NetworkUpgrades { SubnetEVMTimestamp: utils.NewUint64(0), DurangoTimestamp: utils.TimeToNewUint64(agoUpgrade.DurangoTime), EtnaTimestamp: utils.TimeToNewUint64(agoUpgrade.EtnaTime), - // Fortuna was initially an optional upgrade upon its release, but it is required as of the Granite upgrade. + // TODO: Fortuna was initially an optional upgrade upon its release, but it should be required as of the Granite upgrade. // Chains can still opt to not activate Fortuna, but they will not be able to activate the Granite upgrade. // Chains can also override this timestamp with a custom upgrade configuration. // FortunaTimestamp: utils.TimeToNewUint64(agoUpgrade.GraniteTime), diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index 12ab6dc38a..2c40d0f133 100644 --- a/plugin/evm/header/base_fee.go +++ b/plugin/evm/header/base_fee.go @@ -28,7 +28,6 @@ func BaseFee( parent *types.Header, timestamp uint64, ) (*big.Int, error) { - // TODO: XXX Handle feeConfig with Fortuna here switch { case config.IsFortuna(timestamp): state, err := feeStateBeforeBlock(config, acp176Config, parent, timestamp) diff --git a/precompile/contracts/acp224feemanager/module.go b/precompile/contracts/acp224feemanager/module.go index 37dec96970..6fa14c651e 100644 --- a/precompile/contracts/acp224feemanager/module.go +++ b/precompile/contracts/acp224feemanager/module.go @@ -61,7 +61,6 @@ func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg pre return fmt.Errorf("cannot configure given initial fee config: %w", err) } } else { - // TODO: XXX - If the initial fee config is not set, we should use the latest fee config rather than the one set in genesis. if err := StoreFeeConfig(state, chainConfig.GetACP224FeeConfig(), blockContext); err != nil { // This should not happen since we already checked the chain config in the genesis creation. return fmt.Errorf("cannot configure fee config in chain config: %w", err) From 1bf31b5c6bf329b56788f45ece51eaca6c6c216d Mon Sep 17 00:00:00 2001 From: Michael Kaplan Date: Wed, 17 Sep 2025 11:26:45 -0400 Subject: [PATCH 8/8] lint --- commontype/fee_config.go | 1 + core/blockchain_reader.go | 4 +- plugin/evm/header/block_gas_cost_test.go | 12 +-- plugin/evm/header/dynamic_fee_state.go | 3 +- plugin/evm/header/gas_limit_test.go | 1 - plugin/evm/vm.go | 8 -- .../acp224feemanagertest/config_test.go | 9 +- .../acp224feemanagertest/contract_test.go | 40 +++++---- .../contracts/acp224feemanager/config.go | 9 +- .../contracts/acp224feemanager/contract.go | 90 ++++++++++++------- .../contracts/acp224feemanager/event.go | 6 +- .../contracts/acp224feemanager/module.go | 13 ++- 12 files changed, 110 insertions(+), 86 deletions(-) diff --git a/commontype/fee_config.go b/commontype/fee_config.go index 80a6844822..732e602829 100644 --- a/commontype/fee_config.go +++ b/commontype/fee_config.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/utils" ) diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index d400a3be5b..273c319a6e 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -425,7 +425,7 @@ func (bc *BlockChain) GetACP224FeeConfigAt(parent *types.Header) (commontype.ACP return commontype.EmptyACP224FeeConfig, nil, err } - storedFeeConfig := acp224feemanager.GetStoredFeeConfig(stateDB) + storedFeeConfig := acp224feemanager.GetStoredFeeConfig(stateDB, acp224feemanager.ContractAddress) // this should not return an invalid fee config since it's assumed that // StoreFeeConfig returns an error when an invalid fee config is attempted to be stored. // However an external stateDB call can modify the contract state. @@ -433,7 +433,7 @@ func (bc *BlockChain) GetACP224FeeConfigAt(parent *types.Header) (commontype.ACP if err := storedFeeConfig.Verify(); err != nil { return commontype.EmptyACP224FeeConfig, nil, err } - lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(stateDB) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(stateDB, acp224feemanager.ContractAddress) cacheable := &cacheableACP224FeeConfig{acp224FeeConfig: storedFeeConfig, lastChangedAt: lastChangedAt} // add it to the cache bc.acp224FeeConfigCache.Add(parent.Root, cacheable) diff --git a/plugin/evm/header/block_gas_cost_test.go b/plugin/evm/header/block_gas_cost_test.go index c6e8c2b495..fd4a3af7bd 100644 --- a/plugin/evm/header/block_gas_cost_test.go +++ b/plugin/evm/header/block_gas_cost_test.go @@ -51,12 +51,6 @@ var ( MinBaseFee: big.NewInt(50 * utils.GWei), GasLimit: big.NewInt(24_000_000), } - testACP224FeeConfigDouble = commontype.ACP224FeeConfig{ - TargetGas: big.NewInt(2_000_000), - MinGasPrice: big.NewInt(2), - TimeToFillCapacity: big.NewInt(10), - TimeToDouble: big.NewInt(120), - } testACP176ConfigDouble = acp176.Config{ MinGasPrice: testACP176Config.MinGasPrice * 2, TimeToFillCapacity: testACP176Config.TimeToFillCapacity * 2, @@ -66,14 +60,14 @@ var ( func TestBlockGasCost(t *testing.T) { t.Run("normal", func(t *testing.T) { - BlockGasCostTest(t, testFeeConfig, testACP224FeeConfig) + BlockGasCostTest(t, testFeeConfig) }) t.Run("double", func(t *testing.T) { - BlockGasCostTest(t, testFeeConfigDouble, testACP224FeeConfigDouble) + BlockGasCostTest(t, testFeeConfigDouble) }) } -func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig, acp224FeeConfig commontype.ACP224FeeConfig) { +func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig) { maxBlockGasCostBig := feeConfig.MaxBlockGasCost maxBlockGasCost := feeConfig.MaxBlockGasCost.Uint64() blockGasCostStep := feeConfig.BlockGasCostStep.Uint64() diff --git a/plugin/evm/header/dynamic_fee_state.go b/plugin/evm/header/dynamic_fee_state.go index cb29d24494..8c75cec53c 100644 --- a/plugin/evm/header/dynamic_fee_state.go +++ b/plugin/evm/header/dynamic_fee_state.go @@ -1,4 +1,4 @@ -// (c) 2025, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package header @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/params/extras" "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index fd9e6fc327..f39dc44a65 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" - "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 1b17237b67..d7eb8a1563 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -112,14 +112,6 @@ const ( ethMetricsPrefix = "eth" sdkMetricsPrefix = "sdk" chainStateMetricsPrefix = "chain_state" - - // gossip constants - pushGossipDiscardedElements = 16_384 - txGossipTargetMessageSize = 20 * units.KiB - maxValidatorSetStaleness = time.Minute - txGossipThrottlingPeriod = 10 * time.Second - txGossipThrottlingLimit = 2 - txGossipPollSize = 1 ) // Define the API endpoints for the VM diff --git a/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go b/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go index 951c00a26e..4a2f42975a 100644 --- a/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go +++ b/precompile/contracts/acp224feemanager/acp224feemanagertest/config_test.go @@ -1,3 +1,6 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + package acp224feemanagertest import ( @@ -6,15 +9,15 @@ import ( "testing" "github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176" + "github.com/ava-labs/libevm/common" + "go.uber.org/mock/gomock" + "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" "github.com/ava-labs/subnet-evm/precompile/precompileconfig" "github.com/ava-labs/subnet-evm/precompile/precompiletest" "github.com/ava-labs/subnet-evm/utils" - - "github.com/ava-labs/libevm/common" - "go.uber.org/mock/gomock" ) // TestVerify tests the verification of Config. diff --git a/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go b/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go index d81db2552a..f9049ff871 100644 --- a/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go +++ b/precompile/contracts/acp224feemanager/acp224feemanagertest/contract_test.go @@ -1,3 +1,6 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + package acp224feemanagertest import ( @@ -6,14 +9,15 @@ import ( "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/vm" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/core/extstate" "github.com/ava-labs/subnet-evm/precompile/allowlist/allowlisttest" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/contracts/acp224feemanager" "github.com/ava-labs/subnet-evm/precompile/precompiletest" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" ) var ( @@ -43,7 +47,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfig() @@ -67,7 +71,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfig() @@ -91,7 +95,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfig() @@ -115,7 +119,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfig() @@ -150,7 +154,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() @@ -165,9 +169,9 @@ var ( return packedOutput }(), AfterHook: func(t testing.TB, state *extstate.StateDB) { - feeConfig := acp224feemanager.GetStoredFeeConfig(state) + feeConfig := acp224feemanager.GetStoredFeeConfig(state, acp224feemanager.ContractAddress) require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) - lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state, acp224feemanager.ContractAddress) require.Equal(t, testBlockNumber, lastChangedAt) }, SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, @@ -180,7 +184,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() @@ -195,9 +199,9 @@ var ( return packedOutput }(), AfterHook: func(t testing.TB, state *extstate.StateDB) { - feeConfig := acp224feemanager.GetStoredFeeConfig(state) + feeConfig := acp224feemanager.GetStoredFeeConfig(state, acp224feemanager.ContractAddress) require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) - lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state, acp224feemanager.ContractAddress) require.Equal(t, testBlockNumber, lastChangedAt) }, SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, @@ -210,7 +214,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() @@ -225,9 +229,9 @@ var ( return packedOutput }(), AfterHook: func(t testing.TB, state *extstate.StateDB) { - feeConfig := acp224feemanager.GetStoredFeeConfig(state) + feeConfig := acp224feemanager.GetStoredFeeConfig(state, acp224feemanager.ContractAddress) require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) - lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state, acp224feemanager.ContractAddress) require.Equal(t, testBlockNumber, lastChangedAt) }, SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, @@ -240,7 +244,7 @@ var ( blockContext := contract.NewMockBlockContext(gomock.NewController(t)) blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) allowlisttest.SetDefaultRoles(acp224feemanager.Module.Address)(t, state) - require.NoError(t, acp224feemanager.StoreFeeConfig(state, testDefaultUpdatedFeeConfig, blockContext)) + require.NoError(t, acp224feemanager.StoreFeeConfig(state, acp224feemanager.ContractAddress, testDefaultUpdatedFeeConfig, blockContext)) }, InputFn: func(t testing.TB) []byte { input, err := acp224feemanager.PackGetFeeConfigLastChangedAt() @@ -255,9 +259,9 @@ var ( return packedOutput }(), AfterHook: func(t testing.TB, state *extstate.StateDB) { - feeConfig := acp224feemanager.GetStoredFeeConfig(state) + feeConfig := acp224feemanager.GetStoredFeeConfig(state, acp224feemanager.ContractAddress) require.Equal(t, testDefaultUpdatedFeeConfig, feeConfig) - lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state) + lastChangedAt := acp224feemanager.GetFeeConfigLastChangedAt(state, acp224feemanager.ContractAddress) require.Equal(t, testBlockNumber, lastChangedAt) }, SuppliedGas: acp224feemanager.GetFeeConfigLastChangedAtGasCost, diff --git a/precompile/contracts/acp224feemanager/config.go b/precompile/contracts/acp224feemanager/config.go index 5d87949941..9f0ae40c41 100644 --- a/precompile/contracts/acp224feemanager/config.go +++ b/precompile/contracts/acp224feemanager/config.go @@ -1,11 +1,14 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + package acp224feemanager import ( - "github.com/ava-labs/subnet-evm/precompile/allowlist" - "github.com/ava-labs/subnet-evm/precompile/precompileconfig" - "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/commontype" + "github.com/ava-labs/subnet-evm/precompile/allowlist" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" ) var _ precompileconfig.Config = (*Config)(nil) diff --git a/precompile/contracts/acp224feemanager/contract.go b/precompile/contracts/acp224feemanager/contract.go index ee3c91267e..cc7f959b93 100644 --- a/precompile/contracts/acp224feemanager/contract.go +++ b/precompile/contracts/acp224feemanager/contract.go @@ -1,6 +1,5 @@ -// Code generated -// This file is a generated precompile contract config with stubbed abstract functions. -// The file is generated by a template. Please inspect every code and comment in this file before use. +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. package acp224feemanager @@ -9,17 +8,16 @@ import ( "fmt" "math/big" - "github.com/ava-labs/subnet-evm/accounts/abi" - "github.com/ava-labs/subnet-evm/precompile/allowlist" - "github.com/ava-labs/subnet-evm/precompile/contract" - - "github.com/ava-labs/subnet-evm/commontype" - - _ "embed" - "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" + + _ "embed" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/commontype" + "github.com/ava-labs/subnet-evm/precompile/allowlist" + "github.com/ava-labs/subnet-evm/precompile/contract" ) const ( @@ -64,8 +62,12 @@ var ( ) // GetACP224FeeManagerAllowListStatus returns the role of [address] for the ACP224FeeManager list. -func GetACP224FeeManagerAllowListStatus(stateDB contract.StateDB, address common.Address) allowlist.Role { - return allowlist.GetAllowListStatus(stateDB, ContractAddress, address) +func GetACP224FeeManagerAllowListStatus( + stateDB contract.StateDB, + precompileAddr common.Address, + address common.Address, +) allowlist.Role { + return allowlist.GetAllowListStatus(stateDB, precompileAddr, address) } // SetACP224FeeManagerAllowListStatus sets the permissions of [address] to [role] for the @@ -74,15 +76,20 @@ func GetACP224FeeManagerAllowListStatus(stateDB contract.StateDB, address common // and [address] hash. It means that any reusage of the [address] key for different value // conflicts with the same slot [role] is stored. // Precompile implementations must use a different key than [address] for their storage. -func SetACP224FeeManagerAllowListStatus(stateDB contract.StateDB, address common.Address, role allowlist.Role) { - allowlist.SetAllowListRole(stateDB, ContractAddress, address, role) +func SetACP224FeeManagerAllowListStatus( + stateDB contract.StateDB, + precompileAddr common.Address, + address common.Address, + role allowlist.Role, +) { + allowlist.SetAllowListRole(stateDB, precompileAddr, address, role) } // GetStoredFeeConfig returns fee config from contract storage in given state -func GetStoredFeeConfig(stateDB contract.StateReader) commontype.ACP224FeeConfig { +func GetStoredFeeConfig(stateDB contract.StateReader, addr common.Address) commontype.ACP224FeeConfig { feeConfig := commontype.ACP224FeeConfig{} for i := minFeeConfigFieldKey; i <= numFeeConfigField; i++ { - val := stateDB.GetState(ContractAddress, common.Hash{byte(i)}) + val := stateDB.GetState(addr, common.Hash{byte(i)}) switch i { case targetGasKey: feeConfig.TargetGas = new(big.Int).Set(val.Big()) @@ -100,14 +107,14 @@ func GetStoredFeeConfig(stateDB contract.StateReader) commontype.ACP224FeeConfig return feeConfig } -func GetFeeConfigLastChangedAt(stateDB contract.StateReader) *big.Int { - val := stateDB.GetState(ContractAddress, feeConfigLastChangedAtKey) +func GetFeeConfigLastChangedAt(stateDB contract.StateReader, addr common.Address) *big.Int { + val := stateDB.GetState(addr, feeConfigLastChangedAtKey) return val.Big() } // StoreFeeConfig stores given [feeConfig] and block number in the [blockContext] to the [stateDB]. // A validation on [feeConfig] is done before storing. -func StoreFeeConfig(stateDB contract.StateDB, feeConfig commontype.ACP224FeeConfig, blockContext contract.ConfigurationBlockContext) error { +func StoreFeeConfig(stateDB contract.StateDB, addr common.Address, feeConfig commontype.ACP224FeeConfig, blockContext contract.ConfigurationBlockContext) error { if err := feeConfig.Verify(); err != nil { return fmt.Errorf("cannot verify fee config: %w", err) } @@ -127,14 +134,14 @@ func StoreFeeConfig(stateDB contract.StateDB, feeConfig commontype.ACP224FeeConf // This should never encounter an unknown fee config key panic(fmt.Sprintf("unknown fee config key: %d", i)) } - stateDB.SetState(ContractAddress, common.Hash{byte(i)}, input) + stateDB.SetState(addr, common.Hash{byte(i)}, input) } blockNumber := blockContext.Number() if blockNumber == nil { return errors.New("blockNumber cannot be nil") } - stateDB.SetState(ContractAddress, feeConfigLastChangedAtKey, common.BigToHash(blockNumber)) + stateDB.SetState(addr, feeConfigLastChangedAtKey, common.BigToHash(blockNumber)) return nil } @@ -161,12 +168,19 @@ func UnpackGetFeeConfigOutput(output []byte) (commontype.ACP224FeeConfig, error) return unpacked, nil } -func getFeeConfig(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { +func getFeeConfig( + accessibleState contract.AccessibleState, + _ common.Address, + addr common.Address, + _ []byte, + suppliedGas uint64, + _ bool, +) (ret []byte, remainingGas uint64, err error) { if remainingGas, err = contract.DeductGas(suppliedGas, GetFeeConfigGasCost); err != nil { return nil, 0, err } - feeConfig := GetStoredFeeConfig(accessibleState.GetStateDB()) + feeConfig := GetStoredFeeConfig(accessibleState.GetStateDB(), addr) output, err := PackGetFeeConfigOutput(feeConfig) if err != nil { @@ -200,12 +214,19 @@ func UnpackGetFeeConfigLastChangedAtOutput(output []byte) (*big.Int, error) { return unpacked, nil } -func getFeeConfigLastChangedAt(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { +func getFeeConfigLastChangedAt( + accessibleState contract.AccessibleState, + _ common.Address, + addr common.Address, + _ []byte, + suppliedGas uint64, + _ bool, +) (ret []byte, remainingGas uint64, err error) { if remainingGas, err = contract.DeductGas(suppliedGas, GetFeeConfigLastChangedAtGasCost); err != nil { return nil, 0, err } - lastChangedAt := GetFeeConfigLastChangedAt(accessibleState.GetStateDB()) + lastChangedAt := GetFeeConfigLastChangedAt(accessibleState.GetStateDB(), addr) packedOutput, err := PackGetFeeConfigLastChangedAtOutput(lastChangedAt) if err != nil { return nil, remainingGas, err @@ -232,7 +253,14 @@ func PackSetFeeConfig(config commontype.ACP224FeeConfig) ([]byte, error) { return ACP224FeeManagerABI.Pack("setFeeConfig", config) } -func setFeeConfig(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { +func setFeeConfig( + accessibleState contract.AccessibleState, + caller common.Address, + addr common.Address, + input []byte, + suppliedGas uint64, + readOnly bool, +) (ret []byte, remainingGas uint64, err error) { if remainingGas, err = contract.DeductGas(suppliedGas, SetFeeConfigGasCost); err != nil { return nil, 0, err } @@ -248,12 +276,12 @@ func setFeeConfig(accessibleState contract.AccessibleState, caller common.Addres stateDB := accessibleState.GetStateDB() // Verify that the caller is in the allow list and therefore has the right to call this function. - callerStatus := GetACP224FeeManagerAllowListStatus(stateDB, caller) + callerStatus := GetACP224FeeManagerAllowListStatus(stateDB, addr, caller) if !callerStatus.IsEnabled() { return nil, remainingGas, fmt.Errorf("%w: %s", ErrCannotSetFeeConfig, caller) } - oldConfig := GetStoredFeeConfig(stateDB) + oldConfig := GetStoredFeeConfig(stateDB, addr) eventData := FeeConfigUpdatedEventData{ OldFeeConfig: oldConfig, NewFeeConfig: feeConfig, @@ -267,13 +295,13 @@ func setFeeConfig(accessibleState contract.AccessibleState, caller common.Addres } stateDB.AddLog(&types.Log{ - Address: ContractAddress, + Address: addr, Topics: topics, Data: data, BlockNumber: accessibleState.GetBlockContext().Number().Uint64(), }) - if err := StoreFeeConfig(stateDB, feeConfig, accessibleState.GetBlockContext()); err != nil { + if err := StoreFeeConfig(stateDB, addr, feeConfig, accessibleState.GetBlockContext()); err != nil { return nil, remainingGas, err } diff --git a/precompile/contracts/acp224feemanager/event.go b/precompile/contracts/acp224feemanager/event.go index 606ca60740..b56ad4d873 100644 --- a/precompile/contracts/acp224feemanager/event.go +++ b/precompile/contracts/acp224feemanager/event.go @@ -1,11 +1,11 @@ -// Code generated -// This file is a generated precompile contract config with stubbed abstract functions. -// The file is generated by a template. Please inspect every code and comment in this file before use. +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. package acp224feemanager import ( "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/commontype" ) diff --git a/precompile/contracts/acp224feemanager/module.go b/precompile/contracts/acp224feemanager/module.go index 6fa14c651e..6c67267b36 100644 --- a/precompile/contracts/acp224feemanager/module.go +++ b/precompile/contracts/acp224feemanager/module.go @@ -1,17 +1,16 @@ -// Code generated -// This file is a generated precompile contract config with stubbed abstract functions. -// The file is generated by a template. Please inspect every code and comment in this file before use. +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. package acp224feemanager import ( "fmt" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/precompile/precompileconfig" - - "github.com/ava-labs/libevm/common" ) var _ contract.Configurator = (*configurator)(nil) @@ -56,12 +55,12 @@ func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg pre // Store the initial fee config into the state when the fee manager activates. if config.InitialFeeConfig != nil { - if err := StoreFeeConfig(state, *config.InitialFeeConfig, blockContext); err != nil { + if err := StoreFeeConfig(state, ContractAddress, *config.InitialFeeConfig, blockContext); err != nil { // This should not happen since we already checked this config with Verify() return fmt.Errorf("cannot configure given initial fee config: %w", err) } } else { - if err := StoreFeeConfig(state, chainConfig.GetACP224FeeConfig(), blockContext); err != nil { + if err := StoreFeeConfig(state, ContractAddress, chainConfig.GetACP224FeeConfig(), blockContext); err != nil { // This should not happen since we already checked the chain config in the genesis creation. return fmt.Errorf("cannot configure fee config in chain config: %w", err) }