diff --git a/RELEASES.md b/RELEASES.md index 0cce20cbc4..f5f65cc442 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,8 +1,11 @@ # Release Notes ## Pending Release + - Bump golang version to v1.23.6 - Bump golangci-lint to v1.63 and add linters +- Implement ACP-176 +- Add `GasTarget` to the chain config to allow modifying the chain's `GasTarget` based on the ACP-176 rules ## [v0.14.1](https://github.com/ava-labs/coreth/releases/tag/v0.14.1) diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index 12a0b3a8af..b3afff89cd 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -4,13 +4,13 @@ package dummy import ( - "bytes" "errors" "fmt" "math/big" "time" "github.com/ava-labs/avalanchego/utils/timer/mockable" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/misc/eip4844" "github.com/ava-labs/coreth/core/state" @@ -41,8 +41,27 @@ type Mode struct { } type ( - OnFinalizeAndAssembleCallbackType = func(header *types.Header, state *state.StateDB, txs []*types.Transaction) (extraData []byte, blockFeeContribution *big.Int, extDataGasUsed *big.Int, err error) - OnExtraStateChangeType = func(block *types.Block, statedb *state.StateDB) (blockFeeContribution *big.Int, extDataGasUsed *big.Int, err error) + OnFinalizeAndAssembleCallbackType = func( + header *types.Header, + parent *types.Header, + state *state.StateDB, + txs []*types.Transaction, + ) ( + extraData []byte, + blockFeeContribution *big.Int, + extDataGasUsed *big.Int, + err error, + ) + + OnExtraStateChangeType = func( + block *types.Block, + parent *types.Header, + statedb *state.StateDB, + ) ( + blockFeeContribution *big.Int, + extDataGasUsed *big.Int, + err error, + ) ConsensusCallbacks struct { OnFinalizeAndAssemble OnFinalizeAndAssembleCallbackType @@ -50,12 +69,27 @@ type ( } DummyEngine struct { - cb ConsensusCallbacks - clock *mockable.Clock - consensusMode Mode + cb ConsensusCallbacks + clock *mockable.Clock + consensusMode Mode + desiredTargetExcess *gas.Gas } ) +func NewDummyEngine( + cb ConsensusCallbacks, + mode Mode, + clock *mockable.Clock, + desiredTargetExcess *gas.Gas, +) *DummyEngine { + return &DummyEngine{ + cb: cb, + clock: clock, + consensusMode: mode, + desiredTargetExcess: desiredTargetExcess, + } +} + func NewETHFaker() *DummyEngine { return &DummyEngine{ clock: &mockable.Clock{}, @@ -112,21 +146,15 @@ func NewFullFaker() *DummyEngine { } } -func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header) error { - // Verify that the gasUsed is <= gasLimit - if header.GasUsed > header.GasLimit { - return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) +func verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header) error { + if err := customheader.VerifyGasUsed(config, parent, header); err != nil { + return err } if err := customheader.VerifyGasLimit(config, parent, header); err != nil { return err } - // Verify header.Extra matches the expected value. - expectedExtraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time) - if err != nil { - return fmt.Errorf("failed to calculate extra prefix: %w", err) - } - if !bytes.HasPrefix(header.Extra, expectedExtraPrefix) { - return fmt.Errorf("expected header.Extra to have prefix: %x, found %x", expectedExtraPrefix, header.Extra) + if err := customheader.VerifyExtraPrefix(config, parent, header); err != nil { + return err } // Verify header.BaseFee matches the expected value. @@ -185,7 +213,7 @@ func (eng *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header * } // Ensure gas-related header fields are correct - if err := eng.verifyHeaderGasFields(config, header, parent); err != nil { + if err := verifyHeaderGasFields(config, header, parent); err != nil { return err } @@ -341,7 +369,7 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types err error ) if eng.cb.OnExtraStateChange != nil { - contribution, extDataGasUsed, err = eng.cb.OnExtraStateChange(block, state) + contribution, extDataGasUsed, err = eng.cb.OnExtraStateChange(block, parent, state) if err != nil { return err } @@ -396,7 +424,7 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h err error ) if eng.cb.OnFinalizeAndAssemble != nil { - extraData, contribution, extDataGasUsed, err = eng.cb.OnFinalizeAndAssemble(header, state, txs) + extraData, contribution, extDataGasUsed, err = eng.cb.OnFinalizeAndAssemble(header, parent, state, txs) if err != nil { return nil, err } @@ -430,7 +458,7 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h } // finalize the header.Extra - extraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time) + 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 ad52c626a7..4883361b91 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -373,7 +373,10 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.StateDB, engine consensus.Engine) *types.Header { time := parent.Time() + gap // block time is fixed at [gap] seconds - gasLimit := header.GasLimit(cm.config, parent.Header(), time) + gasLimit, err := header.GasLimit(cm.config, parent.Header(), time) + if err != nil { + panic(err) + } baseFee, err := header.BaseFee(cm.config, parent.Header(), time) if err != nil { panic(err) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 024b496187..48157fd8b2 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -40,6 +40,7 @@ import ( "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" @@ -152,9 +153,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{ @@ -180,15 +182,16 @@ func TestStateProcessorErrors(t *testing.T) { }, { // ErrGasLimitReached txs: []*types.Transaction{ - makeTx(key1, 0, common.Address{}, big.NewInt(0), params.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), params.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{}, params.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{ @@ -241,7 +244,7 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkBlobTx(0, common.Address{}, params.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", }, } { // FullFaker used to skip header verification that enforces no blobs. @@ -358,6 +361,7 @@ func TestStateProcessorErrors(t *testing.T) { func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block { fakeChainReader := newChainMaker(nil, config, engine) time := parent.Time() + 10 + gasLimit, _ := customheader.GasLimit(config, parent.Header(), time) baseFee, _ := customheader.BaseFee(config, parent.Header(), time) header := &types.Header{ ParentHash: parent.Hash(), @@ -368,7 +372,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr Difficulty: parent.Difficulty(), UncleHash: parent.UncleHash(), }), - GasLimit: parent.GasLimit(), + GasLimit: gasLimit, Number: new(big.Int).Add(parent.Number(), common.Big1), Time: time, UncleHash: types.EmptyUncleHash, @@ -395,7 +399,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr cumulativeGas += tx.Gas() nBlobs += len(tx.BlobHashes()) } - header.Extra, _ = customheader.ExtraPrefix(config, parent.Header(), time) + header.Extra, _ = customheader.ExtraPrefix(config, 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/test_blockchain.go b/core/test_blockchain.go index d0b2e95e39..f4451774fa 100644 --- a/core/test_blockchain.go +++ b/core/test_blockchain.go @@ -24,11 +24,16 @@ import ( ) var TestCallbacks = dummy.ConsensusCallbacks{ - OnExtraStateChange: func(block *types.Block, sdb *state.StateDB) (*big.Int, *big.Int, error) { + OnExtraStateChange: func(block *types.Block, _ *types.Header, sdb *state.StateDB) (*big.Int, *big.Int, error) { sdb.SetBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(block.Number().Int64())) return nil, nil, nil }, - OnFinalizeAndAssemble: func(header *types.Header, sdb *state.StateDB, txs []*types.Transaction) ([]byte, *big.Int, *big.Int, error) { + OnFinalizeAndAssemble: func( + header *types.Header, + _ *types.Header, + sdb *state.StateDB, + _ []*types.Transaction, + ) ([]byte, *big.Int, *big.Int, error) { sdb.SetBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(header.Number.Int64())) return nil, nil, nil, nil }, diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index a682fe3077..7c86ae2b69 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -78,13 +78,6 @@ func init() { *testChainConfig.CancunTime = uint64(time.Now().Unix()) } -// overrideMinFee sets the minimum base fee to 1 wei for the duration of the test. -func overrideMinFee(t *testing.T) { - orig := header.EtnaMinBaseFee - header.EtnaMinBaseFee = big.NewInt(1) - t.Cleanup(func() { header.EtnaMinBaseFee = orig }) -} - // testBlockChain is a mock of the live chain for testing the pool. type testBlockChain struct { config *params.ChainConfig @@ -755,7 +748,6 @@ func TestOpenIndex(t *testing.T) { // Tests that after indexing all the loaded transactions from disk, a price heap // is correctly constructed based on the head basefee and blobfee. func TestOpenHeap(t *testing.T) { - overrideMinFee(t) log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend @@ -843,7 +835,6 @@ func TestOpenHeap(t *testing.T) { // Tests that after the pool's previous state is loaded back, any transactions // over the new storage cap will get dropped. func TestOpenCap(t *testing.T) { - overrideMinFee(t) log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) // Create a temporary folder for the persistent backend diff --git a/eth/gasprice/fee_info_provider_test.go b/eth/gasprice/fee_info_provider_test.go index 182c3378ea..4ea5db71b1 100644 --- a/eth/gasprice/fee_info_provider_test.go +++ b/eth/gasprice/fee_info_provider_test.go @@ -17,7 +17,7 @@ import ( ) func TestFeeInfoProvider(t *testing.T) { - backend := newTestBackend(t, params.TestChainConfig, 2, common.Big0, testGenBlock(t, 55, 370)) + backend := newTestBackend(t, params.TestChainConfig, 2, common.Big0, testGenBlock(t, 55, 80)) f, err := newFeeInfoProvider(backend, 1, 2) require.NoError(t, err) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index a41d44d709..aa362e7a51 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -36,6 +36,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/rpc" "github.com/ethereum/go-ethereum/common" @@ -64,9 +65,9 @@ const ( var ( DefaultMaxPrice = big.NewInt(150 * params.GWei) - DefaultMinPrice = big.NewInt(0 * params.GWei) + DefaultMinPrice = big.NewInt(acp176.MinGasPrice) DefaultMinBaseFee = big.NewInt(ap3.InitialBaseFee) - 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 d212b15546..2282884010 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -40,7 +40,9 @@ import ( "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/rpc" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -103,7 +105,7 @@ func newTestBackendFakerEngine(t *testing.T, config *params.ChainConfig, numBloc engine := dummy.NewETHFaker() // Generate testing blocks - _, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, 0, genBlocks) + _, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, ap4.TargetBlockRate-1, genBlocks) if err != nil { t.Fatal(err) } @@ -128,16 +130,16 @@ func newTestBackend(t *testing.T, config *params.ChainConfig, numBlocks int, ext } engine := dummy.NewFakerWithCallbacks(dummy.ConsensusCallbacks{ - OnFinalizeAndAssemble: func(header *types.Header, state *state.StateDB, txs []*types.Transaction) ([]byte, *big.Int, *big.Int, error) { + OnFinalizeAndAssemble: func(*types.Header, *types.Header, *state.StateDB, []*types.Transaction) ([]byte, *big.Int, *big.Int, error) { return nil, common.Big0, extDataGasUsage, nil }, - OnExtraStateChange: func(block *types.Block, state *state.StateDB) (*big.Int, *big.Int, error) { + OnExtraStateChange: func(*types.Block, *types.Header, *state.StateDB) (*big.Int, *big.Int, error) { return common.Big0, extDataGasUsage, nil }, }) // Generate testing blocks - _, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, 1, genBlocks) + _, blocks, _, err := core.GenerateChainWithGenesis(gspec, engine, numBlocks, ap4.TargetBlockRate-1, genBlocks) if err != nil { t.Fatal(err) } @@ -249,8 +251,8 @@ func TestSuggestTipCapEmptyExtDataGasUsage(t *testing.T) { chainConfig: params.TestChainConfig, numBlocks: 3, extDataGasUsage: nil, - genBlock: testGenBlock(t, 55, 370), - expectedTip: big.NewInt(5_713_963_964), + genBlock: testGenBlock(t, 55, 80), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -259,8 +261,8 @@ func TestSuggestTipCapSimple(t *testing.T) { chainConfig: params.TestChainConfig, numBlocks: 3, extDataGasUsage: common.Big0, - genBlock: testGenBlock(t, 55, 370), - expectedTip: big.NewInt(5_713_963_964), + genBlock: testGenBlock(t, 55, 80), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -269,8 +271,8 @@ func TestSuggestTipCapSimpleFloor(t *testing.T) { chainConfig: params.TestChainConfig, numBlocks: 1, extDataGasUsage: common.Big0, - genBlock: testGenBlock(t, 55, 370), - expectedTip: common.Big0, + genBlock: testGenBlock(t, 55, 80), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -286,7 +288,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), @@ -316,7 +318,7 @@ func TestSuggestTipCapSmallTips(t *testing.T) { } }, // NOTE: small tips do not bias estimate - expectedTip: big.NewInt(5_713_963_964), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -325,8 +327,8 @@ func TestSuggestTipCapExtDataUsage(t *testing.T) { chainConfig: params.TestChainConfig, numBlocks: 3, extDataGasUsage: big.NewInt(10_000), - genBlock: testGenBlock(t, 55, 370), - expectedTip: big.NewInt(5_706_726_650), + genBlock: testGenBlock(t, 55, 80), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -336,7 +338,7 @@ func TestSuggestTipCapMinGas(t *testing.T) { numBlocks: 3, extDataGasUsage: common.Big0, genBlock: testGenBlock(t, 500, 50), - expectedTip: big.NewInt(0), + expectedTip: big.NewInt(1), }, defaultOracleConfig()) } @@ -379,10 +381,10 @@ func TestSuggestGasPricePreAP3(t *testing.T) { func TestSuggestTipCapMaxBlocksLookback(t *testing.T) { applyGasPriceTest(t, suggestTipCapTest{ chainConfig: params.TestChainConfig, - numBlocks: 20, + numBlocks: 200, extDataGasUsage: common.Big0, - genBlock: testGenBlock(t, 550, 370), - expectedTip: big.NewInt(51_565_264_257), + genBlock: testGenBlock(t, 550, 80), + expectedTip: big.NewInt(3), }, defaultOracleConfig()) } @@ -391,20 +393,20 @@ func TestSuggestTipCapMaxBlocksSecondsLookback(t *testing.T) { chainConfig: params.TestChainConfig, numBlocks: 20, extDataGasUsage: big.NewInt(1), - genBlock: testGenBlock(t, 550, 370), - expectedTip: big.NewInt(92_212_529_424), + genBlock: testGenBlock(t, 550, 80), + expectedTip: big.NewInt(1), }, timeCrunchOracleConfig()) } func TestSuggestTipCapIncludesExtraDataGas(t *testing.T) { applyGasPriceTest(t, suggestTipCapTest{ chainConfig: params.TestChainConfig, - numBlocks: 20, - extDataGasUsage: DefaultMinGasUsed, + numBlocks: 1000, + extDataGasUsage: big.NewInt(acp176.MinMaxPerSecond - int64(params.TxGas)), // 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(83_603_561_239), - }, timeCrunchOracleConfig()) + expectedTip: big.NewInt(44_252), + }, defaultOracleConfig()) } diff --git a/ethclient/simulated/options_test.go b/ethclient/simulated/options_test.go index 26d20b11b9..cabf038eba 100644 --- a/ethclient/simulated/options_test.go +++ b/ethclient/simulated/options_test.go @@ -26,7 +26,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" ) // Tests that the simulator starts with the initial gas limit in the genesis block, @@ -50,8 +50,8 @@ func TestWithBlockGasLimitOption(t *testing.T) { if err != nil { t.Fatalf("failed to retrieve head block: %v", err) } - if head.GasLimit() != cortina.GasLimit { - t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), cortina.GasLimit) + if head.GasLimit() != acp176.MinMaxCapacity { + t.Errorf("head gas limit mismatch: have %v, want %v", head.GasLimit(), acp176.MinMaxCapacity) } } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 115451df64..ed6ee23b2e 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1022,7 +1022,10 @@ 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":"0x68c6171400","value":"0x1","input":"0x","accessList":[],"v":"0x1","r":"0x83cf4820cfd50fdd240fea74eaf7227e2e3919507cc567c885a6e6bf27543567","s":"0x899543bbe903a76b705e03cfba217e5cb91fc7204309170c0e91f34988d5fb2","yParity":"0x1","hash":"0x09572232b67f69faab343c5b417c8964b15263c5abbbcdb1ebf7f5eda8ed3a63"}` + // The expected result has deviated from upstream because the base fee, and + // therefore the `maxFeePerGas`, resulting from [params.TestChainConfig] is + // different. + 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 7e707bf092..2351e5e051 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-1.json @@ -1,14 +1,14 @@ { - "baseFeePerGas": "0x34630b8a00", + "baseFeePerGas": "0x1", "blockExtraData": "0x", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xcf8a94110956240b890d04288d8ee308e04ca5ce12b442679afa7dfc74c3abf5", + "hash": "0x1e07d8e1ae322e65557ce3de538dbb2a820c060c4f0d7cc72cc5fdda4d391219", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -17,13 +17,13 @@ "parentHash": "0x47f282f6a118c159de5d11a8ad6cc15f2a7bb0eee8e651c94702d9ff413d20b8", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2df", - "stateRoot": "0x060c7f976a708f443cb9b824aeb5b4bb0f3bf35d2c80ada9d329b511cf4f251f", + "size": "0x29d", + "stateRoot": "0xd2936a5affc08b2842ded96c61db43e85298ef604c36a07eab095a06130edc40", "timestamp": "0xa", "totalDifficulty": "0x1", "transactions": [ - "0x09220a8629fd020cbb341ab146e6acb4dc4811ab5fdf021bec3d3219c5a29ab3" + "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389" ], - "transactionsRoot": "0x272d13afea9f2f2c9b9ab3d8bbdb492ce5f7b215c493adaac5d98abc9ad62352", + "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 72dede0d90..639ad73bd2 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest-1-fullTx.json @@ -1,34 +1,34 @@ { - "baseFeePerGas": "0x29d101e35b", + "baseFeePerGas": "0x1", "blockExtraData": "0x", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "hash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", - "parentHash": "0x800fb44aa072cdae6ae48192a1ce9c147540304b59904ddff593de42e9a9e7d4", + "parentHash": "0x2509d3bbbff05cde63ff5583a7d8332a274a041f86a81f4d311ec344cd773a18", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2df", - "stateRoot": "0x7afe30d6f703bbdf57c04120e729a4b1d248ebc81da9bc1cb96b0491a421f15a", + "size": "0x29d", + "stateRoot": "0x0079c4f658ca6481223860cbe48a032a7b54de44ef980b1aa9b6be2859663fa4", "timestamp": "0x5a", "totalDifficulty": "0x9", "transactions": [ { - "blockHash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "blockHash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "blockNumber": "0x9", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gas": "0x5208", - "gasPrice": "0x29d101e35b", - "hash": "0xc187ad4e657c1a75234a6456f52bb6d8fe3a234729cec11afa46bea7ffbce0d7", + "gasPrice": "0x1", + "hash": "0x788f1d9b6ab5314ca3157e4e514b602d3d9cf98773402749cd0ea73d4f373330", "input": "0x", "nonce": "0x8", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", @@ -36,10 +36,10 @@ "value": "0x3e8", "type": "0x0", "v": "0x1b", - "r": "0xc3590d4884299ac2e6d6db2de1aa36caf8ce3630bd41a5dd862b7aa5820a8501", - "s": "0x72325946a27ab5b142405a4db54691fe00b2249eed6dd6667fe9d36f1412bd1" + "r": "0x405203de7391198cd3dd1bfc2b12201053a799be421d74a5d3bc1338e75abfed", + "s": "0x683e95bab8c6c2d757bdd5cd0d75dc2bc9e54d9066023935a5d2b93281bfd0a3" } ], - "transactionsRoot": "0x636f1c9b3e00b425fbab75c79989315b6f30c48f5a55ee636b1fc3805538c5f7", + "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 4218cb5ef0..5d9be256d0 100644 --- a/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByHash-hash-latest.json @@ -1,29 +1,29 @@ { - "baseFeePerGas": "0x28a7a56427", + "baseFeePerGas": "0x1", "blockExtraData": "0x", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0x27a110dbd61d8291cedc5561f462d0258f860809988bca7eec74abbc7e9c6e75", + "hash": "0x7a7b47b7b00ef40ae50fe5766e3049e6c224b6bb3b46615f8b62838daa208502", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", - "parentHash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "parentHash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2df", - "stateRoot": "0xa49730b1582776f571728ddb1858e048374f17223524d728274f57afbafd3893", + "size": "0x29d", + "stateRoot": "0x94868d1188e9d742248c280a147aac1fe9540029a00ac03f38d255c8701ef09a", "timestamp": "0x64", "totalDifficulty": "0xa", "transactions": [ - "0x2947d62ddb16c5312dc40e5d9b29d75447bc011e1393c5f1544144bc764e16f8" + "0x2019a52ff9645912a406c958eaf597be403ba9cadb25b981bcbdb2b38711c12d" ], - "transactionsRoot": "0xf578b0855e1c4509f5248387fcc5d3144552ade53be98825df0884f36fbc3ab9", + "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 7e707bf092..2351e5e051 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-1.json @@ -1,14 +1,14 @@ { - "baseFeePerGas": "0x34630b8a00", + "baseFeePerGas": "0x1", "blockExtraData": "0x", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xcf8a94110956240b890d04288d8ee308e04ca5ce12b442679afa7dfc74c3abf5", + "hash": "0x1e07d8e1ae322e65557ce3de538dbb2a820c060c4f0d7cc72cc5fdda4d391219", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -17,13 +17,13 @@ "parentHash": "0x47f282f6a118c159de5d11a8ad6cc15f2a7bb0eee8e651c94702d9ff413d20b8", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2df", - "stateRoot": "0x060c7f976a708f443cb9b824aeb5b4bb0f3bf35d2c80ada9d329b511cf4f251f", + "size": "0x29d", + "stateRoot": "0xd2936a5affc08b2842ded96c61db43e85298ef604c36a07eab095a06130edc40", "timestamp": "0xa", "totalDifficulty": "0x1", "transactions": [ - "0x09220a8629fd020cbb341ab146e6acb4dc4811ab5fdf021bec3d3219c5a29ab3" + "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389" ], - "transactionsRoot": "0x272d13afea9f2f2c9b9ab3d8bbdb492ce5f7b215c493adaac5d98abc9ad62352", + "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 72dede0d90..639ad73bd2 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-number-latest-1.json @@ -1,34 +1,34 @@ { - "baseFeePerGas": "0x29d101e35b", + "baseFeePerGas": "0x1", "blockExtraData": "0x", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "hash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", - "parentHash": "0x800fb44aa072cdae6ae48192a1ce9c147540304b59904ddff593de42e9a9e7d4", + "parentHash": "0x2509d3bbbff05cde63ff5583a7d8332a274a041f86a81f4d311ec344cd773a18", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2df", - "stateRoot": "0x7afe30d6f703bbdf57c04120e729a4b1d248ebc81da9bc1cb96b0491a421f15a", + "size": "0x29d", + "stateRoot": "0x0079c4f658ca6481223860cbe48a032a7b54de44ef980b1aa9b6be2859663fa4", "timestamp": "0x5a", "totalDifficulty": "0x9", "transactions": [ { - "blockHash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "blockHash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "blockNumber": "0x9", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gas": "0x5208", - "gasPrice": "0x29d101e35b", - "hash": "0xc187ad4e657c1a75234a6456f52bb6d8fe3a234729cec11afa46bea7ffbce0d7", + "gasPrice": "0x1", + "hash": "0x788f1d9b6ab5314ca3157e4e514b602d3d9cf98773402749cd0ea73d4f373330", "input": "0x", "nonce": "0x8", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", @@ -36,10 +36,10 @@ "value": "0x3e8", "type": "0x0", "v": "0x1b", - "r": "0xc3590d4884299ac2e6d6db2de1aa36caf8ce3630bd41a5dd862b7aa5820a8501", - "s": "0x72325946a27ab5b142405a4db54691fe00b2249eed6dd6667fe9d36f1412bd1" + "r": "0x405203de7391198cd3dd1bfc2b12201053a799be421d74a5d3bc1338e75abfed", + "s": "0x683e95bab8c6c2d757bdd5cd0d75dc2bc9e54d9066023935a5d2b93281bfd0a3" } ], - "transactionsRoot": "0x636f1c9b3e00b425fbab75c79989315b6f30c48f5a55ee636b1fc3805538c5f7", + "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 4218cb5ef0..5d9be256d0 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json @@ -1,29 +1,29 @@ { - "baseFeePerGas": "0x28a7a56427", + "baseFeePerGas": "0x1", "blockExtraData": "0x", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0x27a110dbd61d8291cedc5561f462d0258f860809988bca7eec74abbc7e9c6e75", + "hash": "0x7a7b47b7b00ef40ae50fe5766e3049e6c224b6bb3b46615f8b62838daa208502", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", - "parentHash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "parentHash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x2df", - "stateRoot": "0xa49730b1582776f571728ddb1858e048374f17223524d728274f57afbafd3893", + "size": "0x29d", + "stateRoot": "0x94868d1188e9d742248c280a147aac1fe9540029a00ac03f38d255c8701ef09a", "timestamp": "0x64", "totalDifficulty": "0xa", "transactions": [ - "0x2947d62ddb16c5312dc40e5d9b29d75447bc011e1393c5f1544144bc764e16f8" + "0x2019a52ff9645912a406c958eaf597be403ba9cadb25b981bcbdb2b38711c12d" ], - "transactionsRoot": "0xf578b0855e1c4509f5248387fcc5d3144552ade53be98825df0884f36fbc3ab9", + "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 f4da042d07..64daaa535a 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-block-with-blob-tx.json @@ -2,18 +2,18 @@ { "blobGasPrice": "0x1", "blobGasUsed": "0x20000", - "blockHash": "0x0415a36cd8c5f7531e835ebd048b31a2498307ff628a5360f1ea32cd505eca3c", + "blockHash": "0x86f00a75517589a3ef52cdfa3e9c074b7fefc35079e5d0bbb31987340f030ece", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x2d810ba348", + "effectiveGasPrice": "0x2", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xbd076c8bafdc7cf57e7b76aa11c41852383db7584d9ab4b6f1f99b93bdf415e5", + "transactionHash": "0x77255f1a75d6c0252a56539ad11edf9047df59dc390085946b410f406b9cd254", "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 a2a0e2dc97..37553c02b9 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,17 +1,17 @@ [ { - "blockHash": "0x536da302c391777506cb8eec39a41cef7425049c0de0e0def83f0932435c0f15", + "blockHash": "0x08bd14928be51a5496c0bdcccfc53184052485fa3bb8fa7b74f2ce7897036a0c", "blockNumber": "0x2", "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", "cumulativeGasUsed": "0xcf50", - "effectiveGasPrice": "0x32ee841b80", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0xcf50", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": null, - "transactionHash": "0x517f3174bd4501d55f0f93589ef0102152ab808f51bf595f2779461f04871a32", + "transactionHash": "0x3b727d5e08e2176d96ee1bea244f772b592acd2cda1acc3d822c8b7f3de362f9", "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 dbe0a314be..d742bc1ab8 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,17 +1,17 @@ [ { - "blockHash": "0x7efe824a4276eab14dfb5bbb617954582efad47350a962c795bb156ad61a2aea", + "blockHash": "0x7294998ab538f3755004483472027dd9eadc6e324b02afe45baba742a7ded838", "blockNumber": "0x4", "contractAddress": null, "cumulativeGasUsed": "0x538d", - "effectiveGasPrice": "0x302436f3a8", + "effectiveGasPrice": "0x1f5", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x538d", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x0", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0xcdd1122456f8ea113309e2ba5ecc8f389bbdc2e6bcced8eb103c6fdef201bf1a", + "transactionHash": "0x8416458a5e36b7b2f33020bd43d121c8d42c787d743b6eaf64ef09d663892b40", "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 4f8b9567c7..4abee9f202 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": "0xe9a180ae60cf1ecd8e7495c14539cd68f24903cf66cec6708b81f58a57597a96", + "blockHash": "0x8051807def728b06fe43be7d23b921c159200b3195f7a19f8e4d1131a0dae4fa", "blockNumber": "0x3", "contractAddress": null, "cumulativeGasUsed": "0x5e28", - "effectiveGasPrice": "0x318455c568", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5e28", "logs": [ @@ -17,9 +17,9 @@ ], "data": "0x000000000000000000000000000000000000000000000000000000000000000d", "blockNumber": "0x3", - "transactionHash": "0x0e9c460065fee166157eaadf702a01fb6ac1ce27b651e32850a8b09f71f93937", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", - "blockHash": "0xe9a180ae60cf1ecd8e7495c14539cd68f24903cf66cec6708b81f58a57597a96", + "blockHash": "0x8051807def728b06fe43be7d23b921c159200b3195f7a19f8e4d1131a0dae4fa", "logIndex": "0x0", "removed": false } @@ -27,7 +27,7 @@ "logsBloom": "0x00000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000000000000008000000000000000000000000000000000020000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000400000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000", "status": "0x1", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x0e9c460065fee166157eaadf702a01fb6ac1ce27b651e32850a8b09f71f93937", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", "type": "0x0" } 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 aee6d37182..7aa87697f0 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,17 +1,17 @@ [ { - "blockHash": "0x7f8cb96ca1d10b696b2a6c81765073c0f1a285583eb3257723315d59fbe99943", + "blockHash": "0x071ec1a535f3f40169bbd7ae0a92d2c9746a0bcfb252d1a4e890b09f445ca920", "blockNumber": "0x1", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x34630b8a00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x09220a8629fd020cbb341ab146e6acb4dc4811ab5fdf021bec3d3219c5a29ab3", + "transactionHash": "0x941d1c99ff85ba37ae992f86bc5467bdbaea402974f4703914e432ff82dd5389", "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 f4da042d07..64daaa535a 100644 --- a/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockReceipts-tag-latest.json @@ -2,18 +2,18 @@ { "blobGasPrice": "0x1", "blobGasUsed": "0x20000", - "blockHash": "0x0415a36cd8c5f7531e835ebd048b31a2498307ff628a5360f1ea32cd505eca3c", + "blockHash": "0x86f00a75517589a3ef52cdfa3e9c074b7fefc35079e5d0bbb31987340f030ece", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x2d810ba348", + "effectiveGasPrice": "0x2", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xbd076c8bafdc7cf57e7b76aa11c41852383db7584d9ab4b6f1f99b93bdf415e5", + "transactionHash": "0x77255f1a75d6c0252a56539ad11edf9047df59dc390085946b410f406b9cd254", "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 4423eb7ee6..a74b2b399a 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-1.json @@ -1,13 +1,13 @@ { - "baseFeePerGas": "0x34630b8a00", + "baseFeePerGas": "0x1", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xcf8a94110956240b890d04288d8ee308e04ca5ce12b442679afa7dfc74c3abf5", + "hash": "0x1e07d8e1ae322e65557ce3de538dbb2a820c060c4f0d7cc72cc5fdda4d391219", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -16,8 +16,8 @@ "parentHash": "0x47f282f6a118c159de5d11a8ad6cc15f2a7bb0eee8e651c94702d9ff413d20b8", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x060c7f976a708f443cb9b824aeb5b4bb0f3bf35d2c80ada9d329b511cf4f251f", + "stateRoot": "0xd2936a5affc08b2842ded96c61db43e85298ef604c36a07eab095a06130edc40", "timestamp": "0xa", "totalDifficulty": "0x1", - "transactionsRoot": "0x272d13afea9f2f2c9b9ab3d8bbdb492ce5f7b215c493adaac5d98abc9ad62352" + "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 091cb98bbd..79d5dc5409 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest-1.json @@ -1,23 +1,23 @@ { - "baseFeePerGas": "0x29d101e35b", + "baseFeePerGas": "0x1", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "hash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", - "parentHash": "0x800fb44aa072cdae6ae48192a1ce9c147540304b59904ddff593de42e9a9e7d4", + "parentHash": "0x2509d3bbbff05cde63ff5583a7d8332a274a041f86a81f4d311ec344cd773a18", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x7afe30d6f703bbdf57c04120e729a4b1d248ebc81da9bc1cb96b0491a421f15a", + "stateRoot": "0x0079c4f658ca6481223860cbe48a032a7b54de44ef980b1aa9b6be2859663fa4", "timestamp": "0x5a", "totalDifficulty": "0x9", - "transactionsRoot": "0x636f1c9b3e00b425fbab75c79989315b6f30c48f5a55ee636b1fc3805538c5f7" + "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 62dcf2a711..f179deeb27 100644 --- a/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByHash-hash-latest.json @@ -1,23 +1,23 @@ { - "baseFeePerGas": "0x28a7a56427", + "baseFeePerGas": "0x1", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0x27a110dbd61d8291cedc5561f462d0258f860809988bca7eec74abbc7e9c6e75", + "hash": "0x7a7b47b7b00ef40ae50fe5766e3049e6c224b6bb3b46615f8b62838daa208502", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", - "parentHash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "parentHash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0xa49730b1582776f571728ddb1858e048374f17223524d728274f57afbafd3893", + "stateRoot": "0x94868d1188e9d742248c280a147aac1fe9540029a00ac03f38d255c8701ef09a", "timestamp": "0x64", "totalDifficulty": "0xa", - "transactionsRoot": "0xf578b0855e1c4509f5248387fcc5d3144552ade53be98825df0884f36fbc3ab9" + "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 4423eb7ee6..a74b2b399a 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-1.json @@ -1,13 +1,13 @@ { - "baseFeePerGas": "0x34630b8a00", + "baseFeePerGas": "0x1", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xcf8a94110956240b890d04288d8ee308e04ca5ce12b442679afa7dfc74c3abf5", + "hash": "0x1e07d8e1ae322e65557ce3de538dbb2a820c060c4f0d7cc72cc5fdda4d391219", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -16,8 +16,8 @@ "parentHash": "0x47f282f6a118c159de5d11a8ad6cc15f2a7bb0eee8e651c94702d9ff413d20b8", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x060c7f976a708f443cb9b824aeb5b4bb0f3bf35d2c80ada9d329b511cf4f251f", + "stateRoot": "0xd2936a5affc08b2842ded96c61db43e85298ef604c36a07eab095a06130edc40", "timestamp": "0xa", "totalDifficulty": "0x1", - "transactionsRoot": "0x272d13afea9f2f2c9b9ab3d8bbdb492ce5f7b215c493adaac5d98abc9ad62352" + "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 091cb98bbd..79d5dc5409 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-number-latest-1.json @@ -1,23 +1,23 @@ { - "baseFeePerGas": "0x29d101e35b", + "baseFeePerGas": "0x1", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "hash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0x9", - "parentHash": "0x800fb44aa072cdae6ae48192a1ce9c147540304b59904ddff593de42e9a9e7d4", + "parentHash": "0x2509d3bbbff05cde63ff5583a7d8332a274a041f86a81f4d311ec344cd773a18", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x7afe30d6f703bbdf57c04120e729a4b1d248ebc81da9bc1cb96b0491a421f15a", + "stateRoot": "0x0079c4f658ca6481223860cbe48a032a7b54de44ef980b1aa9b6be2859663fa4", "timestamp": "0x5a", "totalDifficulty": "0x9", - "transactionsRoot": "0x636f1c9b3e00b425fbab75c79989315b6f30c48f5a55ee636b1fc3805538c5f7" + "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 62dcf2a711..f179deeb27 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-latest.json @@ -1,23 +1,23 @@ { - "baseFeePerGas": "0x28a7a56427", + "baseFeePerGas": "0x1", "blockGasCost": "0x0", "difficulty": "0x1", "extDataGasUsed": "0x0", "extDataHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0xe4e1c0", + "extraData": "0x000000000130daf800000000000052080000000000000000", + "gasLimit": "0x1312d00", "gasUsed": "0x5208", - "hash": "0x27a110dbd61d8291cedc5561f462d0258f860809988bca7eec74abbc7e9c6e75", + "hash": "0x7a7b47b7b00ef40ae50fe5766e3049e6c224b6bb3b46615f8b62838daa208502", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "number": "0xa", - "parentHash": "0xc2c901ff74a31cb1ca48a2cafc01c51636cef7452aeb759ab8248f529efe7593", + "parentHash": "0x6f7d78e6133e548774a2e3ee56f9f0e58329ce72a4f5822b2e0f50a5ffd26714", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0xa49730b1582776f571728ddb1858e048374f17223524d728274f57afbafd3893", + "stateRoot": "0x94868d1188e9d742248c280a147aac1fe9540029a00ac03f38d255c8701ef09a", "timestamp": "0x64", "totalDifficulty": "0xa", - "transactionsRoot": "0xf578b0855e1c4509f5248387fcc5d3144552ade53be98825df0884f36fbc3ab9" + "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 98a5bc0cee..8eb0d1936a 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": "0x0415a36cd8c5f7531e835ebd048b31a2498307ff628a5360f1ea32cd505eca3c", + "blockHash": "0x86f00a75517589a3ef52cdfa3e9c074b7fefc35079e5d0bbb31987340f030ece", "blockNumber": "0x6", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x2d810ba348", + "effectiveGasPrice": "0x2", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0xbd076c8bafdc7cf57e7b76aa11c41852383db7584d9ab4b6f1f99b93bdf415e5", + "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 60924bb834..26beb86955 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": "0x536da302c391777506cb8eec39a41cef7425049c0de0e0def83f0932435c0f15", + "blockHash": "0x08bd14928be51a5496c0bdcccfc53184052485fa3bb8fa7b74f2ce7897036a0c", "blockNumber": "0x2", "contractAddress": "0xae9bea628c4ce503dcfd7e305cab4e29e7476592", "cumulativeGasUsed": "0xcf50", - "effectiveGasPrice": "0x32ee841b80", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0xcf50", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": null, - "transactionHash": "0x517f3174bd4501d55f0f93589ef0102152ab808f51bf595f2779461f04871a32", + "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 3c7cc536ce..b17bd9d9dd 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": "0xc9352f0417114d8858cda8c8f2dff3796188519302d619df010fd683ea39594b", + "blockHash": "0x08f5ac7e425ecf9ffbca594f1b9fde8c7d42e4147641e27eed3fa5a9c7c21687", "blockNumber": "0x5", "contractAddress": "0xfdaa97661a584d977b4d3abb5370766ff5b86a18", "cumulativeGasUsed": "0xe01c", - "effectiveGasPrice": "0x2ecde015a8", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0xe01c", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": null, - "transactionHash": "0xa9616380994fd7502d0350ee57882bb6e95d6678fa6c4782f179c9f5f3529c48", + "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 fc09e7aee9..c12b2cff81 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": "0x7efe824a4276eab14dfb5bbb617954582efad47350a962c795bb156ad61a2aea", + "blockHash": "0x7294998ab538f3755004483472027dd9eadc6e324b02afe45baba742a7ded838", "blockNumber": "0x4", "contractAddress": null, "cumulativeGasUsed": "0x538d", - "effectiveGasPrice": "0x302436f3a8", + "effectiveGasPrice": "0x1f5", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x538d", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x0", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0xcdd1122456f8ea113309e2ba5ecc8f389bbdc2e6bcced8eb103c6fdef201bf1a", + "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 9bab6ca803..39a02dfea3 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": "0x7f8cb96ca1d10b696b2a6c81765073c0f1a285583eb3257723315d59fbe99943", + "blockHash": "0x071ec1a535f3f40169bbd7ae0a92d2c9746a0bcfb252d1a4e890b09f445ca920", "blockNumber": "0x1", "contractAddress": null, "cumulativeGasUsed": "0x5208", - "effectiveGasPrice": "0x34630b8a00", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", - "transactionHash": "0x09220a8629fd020cbb341ab146e6acb4dc4811ab5fdf021bec3d3219c5a29ab3", + "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 2f9b4c152f..418f7a630f 100644 --- a/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json +++ b/internal/ethapi/testdata/eth_getTransactionReceipt-with-logs.json @@ -1,9 +1,9 @@ { - "blockHash": "0xe9a180ae60cf1ecd8e7495c14539cd68f24903cf66cec6708b81f58a57597a96", + "blockHash": "0x8051807def728b06fe43be7d23b921c159200b3195f7a19f8e4d1131a0dae4fa", "blockNumber": "0x3", "contractAddress": null, "cumulativeGasUsed": "0x5e28", - "effectiveGasPrice": "0x318455c568", + "effectiveGasPrice": "0x1", "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", "gasUsed": "0x5e28", "logs": [ @@ -16,9 +16,9 @@ ], "data": "0x000000000000000000000000000000000000000000000000000000000000000d", "blockNumber": "0x3", - "transactionHash": "0x0e9c460065fee166157eaadf702a01fb6ac1ce27b651e32850a8b09f71f93937", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", - "blockHash": "0xe9a180ae60cf1ecd8e7495c14539cd68f24903cf66cec6708b81f58a57597a96", + "blockHash": "0x8051807def728b06fe43be7d23b921c159200b3195f7a19f8e4d1131a0dae4fa", "logIndex": "0x0", "removed": false } @@ -26,7 +26,7 @@ "logsBloom": "0x00000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000000000000008000000000000000000000000000000000020000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000400000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000", "status": "0x1", "to": "0x0000000000000000000000000000000000031ec7", - "transactionHash": "0x0e9c460065fee166157eaadf702a01fb6ac1ce27b651e32850a8b09f71f93937", + "transactionHash": "0x551ede5f333e69dfb59dd42f670dbe3f66bb694fafabe02b689436be7dc55421", "transactionIndex": "0x0", "type": "0x0" } \ No newline at end of file diff --git a/miner/worker.go b/miner/worker.go index b149e15444..d311b684f1 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -46,7 +46,7 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm/header" + customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/predicate" "github.com/ethereum/go-ethereum/common" @@ -146,8 +146,11 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte timestamp = parent.Time } - gasLimit := header.GasLimit(w.chainConfig, parent, timestamp) - baseFee, err := header.BaseFee(w.chainConfig, parent, timestamp) + gasLimit, err := customheader.GasLimit(w.chainConfig, parent, timestamp) + if err != nil { + return nil, fmt.Errorf("calculating new gas limit: %w", err) + } + baseFee, err := customheader.BaseFee(w.chainConfig, parent, timestamp) if err != nil { return nil, fmt.Errorf("failed to calculate new base fee: %w", err) } @@ -256,6 +259,10 @@ func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.Pre if err != nil { return nil, err } + capacity, err := customheader.GasCapacity(w.chainConfig, parent, header.Time) + if err != nil { + return nil, fmt.Errorf("calculating gas capacity: %w", err) + } numPrefetchers := w.chain.CacheConfig().TriePrefetcherParallelism currentState.StartPrefetcher("miner", state.WithConcurrentWorkers(numPrefetchers)) return &environment{ @@ -264,7 +271,7 @@ func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.Pre parent: parent, header: header, tcount: 0, - gasPool: new(core.GasPool).AddGas(header.GasLimit), + gasPool: new(core.GasPool).AddGas(capacity), rules: w.chainConfig.Rules(header.Number, header.Time), predicateContext: predicateContext, predicateResults: predicate.NewResults(), diff --git a/plugin/evm/block_verification.go b/plugin/evm/block_verification.go index cb42c88cc7..822754caee 100644 --- a/plugin/evm/block_verification.go +++ b/plugin/evm/block_verification.go @@ -180,7 +180,9 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { // If we are in ApricotPhase4, ensure that ExtDataGasUsed is populated correctly. if rules.IsApricotPhase4 { - if rules.IsApricotPhase5 { + // After the F upgrade, the extDataGasUsed field is validated by + // [header.VerifyGasUsed]. + if !rules.IsFUpgrade && rules.IsApricotPhase5 { if !utils.BigLessOrEqualUint64(ethHeader.ExtDataGasUsed, ap5.AtomicGasLimit) { return fmt.Errorf("too large extDataGasUsed: %d", ethHeader.ExtDataGasUsed) } diff --git a/plugin/evm/config/config.go b/plugin/evm/config/config.go index 3104b0faa9..9f1b5dad18 100644 --- a/plugin/evm/config/config.go +++ b/plugin/evm/config/config.go @@ -9,6 +9,7 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/spf13/cast" @@ -85,6 +86,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"` + // Coreth APIs SnowmanAPIEnabled bool `json:"snowman-api-enabled"` AdminAPIEnabled bool `json:"admin-api-enabled"` diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index 78fc9c3446..3d5846fadb 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/coreth/core/types" @@ -23,6 +24,13 @@ func BaseFee( timestamp uint64, ) (*big.Int, error) { switch { + case config.IsFUpgrade(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.IsApricotPhase3(timestamp): return baseFeeFromWindow(config, parent, timestamp) default: diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index d3dc3a5635..61304f36c6 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -7,8 +7,10 @@ import ( "math/big" "testing" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" @@ -314,6 +316,74 @@ func TestBaseFee(t *testing.T) { return big.NewInt(baseFee) }(), }, + { + name: "fupgrade_invalid_timestamp", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Time: 1, + Extra: (&acp176.State{}).Bytes(), + }, + timestamp: 0, + wantErr: errInvalidTimestamp, + }, + { + name: "fupgrade_first_block", + upgrades: params.NetworkUpgrades{ + FUpgradeTimestamp: utils.NewUint64(1), + }, + parent: &types.Header{ + Number: big.NewInt(1), + }, + timestamp: 1, + want: big.NewInt(acp176.MinGasPrice), + }, + { + name: "fupgrade_genesis_block", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + want: big.NewInt(acp176.MinGasPrice), + }, + { + name: "fupgrade_invalid_fee_state", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: make([]byte, acp176.StateSize-1), + }, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_current", + upgrades: params.TestFUpgradeChainConfig.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: "fupgrade_decrease", + upgrades: params.TestFUpgradeChainConfig.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..9ec661adb4 --- /dev/null +++ b/plugin/evm/header/dynamic_fee_state.go @@ -0,0 +1,73 @@ +// (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/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" + "github.com/ethereum/go-ethereum/common" +) + +// 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 *params.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.IsFUpgrade(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 *params.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 + if err := state.ConsumeGas(header.GasUsed, header.ExtDataGasUsed); 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/dynamic_fee_windower.go b/plugin/evm/header/dynamic_fee_windower.go index 6308c54b73..eb92512120 100644 --- a/plugin/evm/header/dynamic_fee_windower.go +++ b/plugin/evm/header/dynamic_fee_windower.go @@ -22,12 +22,9 @@ var ( maxUint256Plus1 = new(big.Int).Lsh(common.Big1, 256) maxUint256 = new(big.Int).Sub(maxUint256Plus1, common.Big1) - ap3MinBaseFee = big.NewInt(ap3.MinBaseFee) - ap4MinBaseFee = big.NewInt(ap4.MinBaseFee) - // EtnaMinBaseFee is exported so that it can be modified by tests. - // - // TODO: Unexport this. - EtnaMinBaseFee = big.NewInt(etna.MinBaseFee) + ap3MinBaseFee = big.NewInt(ap3.MinBaseFee) + ap4MinBaseFee = big.NewInt(ap4.MinBaseFee) + etnaMinBaseFee = big.NewInt(etna.MinBaseFee) ap3MaxBaseFee = big.NewInt(ap3.MaxBaseFee) ap4MaxBaseFee = big.NewInt(ap4.MaxBaseFee) @@ -131,7 +128,7 @@ func baseFeeFromWindow(config *params.ChainConfig, parent *types.Header, timesta // Ensure that the base fee does not increase/decrease outside of the bounds switch { case config.IsEtna(parent.Time): - baseFee = selectBigWithinBounds(EtnaMinBaseFee, baseFee, maxUint256) + baseFee = selectBigWithinBounds(etnaMinBaseFee, baseFee, maxUint256) case isApricotPhase5: baseFee = selectBigWithinBounds(ap4MinBaseFee, baseFee, maxUint256) case config.IsApricotPhase4(parent.Time): diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index 3d87d636b0..0400b7c57a 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -4,26 +4,47 @@ package header import ( + "bytes" "errors" "fmt" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" ) -var errInvalidExtraLength = errors.New("invalid header.Extra length") +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 *params.ChainConfig, parent *types.Header, - timestamp uint64, + header *types.Header, + desiredTargetExcess *gas.Gas, ) ([]byte, error) { switch { - case config.IsApricotPhase3(timestamp): - window, err := feeWindow(config, parent, timestamp) + case config.IsFUpgrade(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.IsApricotPhase3(header.Time): + window, err := feeWindow(config, parent, header.Time) if err != nil { return nil, fmt.Errorf("failed to calculate fee window: %w", err) } @@ -34,11 +55,75 @@ func ExtraPrefix( } } +// VerifyExtraPrefix verifies that the header's Extra field is correctly +// formatted. +func VerifyExtraPrefix( + config *params.ChainConfig, + parent *types.Header, + header *types.Header, +) error { + switch { + case config.IsFUpgrade(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.IsApricotPhase3(header.Time): + feeWindow, err := feeWindow(config, parent, header.Time) + if err != nil { + return fmt.Errorf("calculating expected fee window: %w", err) + } + feeWindowBytes := feeWindow.Bytes() + if !bytes.HasPrefix(header.Extra, feeWindowBytes) { + return fmt.Errorf("%w: expected %x as prefix, found %x", + errInvalidExtraPrefix, + feeWindowBytes, + header.Extra, + ) + } + } + return nil +} + // VerifyExtra verifies that the header's Extra field is correctly formatted for -// [rules]. +// rules. +// +// TODO: Should this be merged with VerifyExtraPrefix? func VerifyExtra(rules params.AvalancheRules, extra []byte) error { extraLen := len(extra) switch { + case rules.IsFUpgrade: + if extraLen < acp176.StateSize { + return fmt.Errorf( + "%w: expected >= %d but got %d", + errInvalidExtraLength, + acp176.StateSize, + extraLen, + ) + } case rules.IsDurango: if extraLen < ap3.WindowSize { return fmt.Errorf( @@ -80,13 +165,17 @@ func VerifyExtra(rules params.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(_ params.AvalancheRules, extra []byte) []byte { +func PredicateBytesFromExtra(rules params.AvalancheRules, extra []byte) []byte { + offset := ap3.WindowSize + if rules.IsFUpgrade { + offset = acp176.StateSize + } + // Prior to Durango, the VM enforces the extra data is smaller than or equal - // to this size. - // After Durango, the VM pre-verifies the extra data past the dynamic fee - // rollup window is valid. - if len(extra) <= ap3.WindowSize { + // to `offset`. + // After Durango, the VM pre-verifies the extra data past `offset` is valid. + if len(extra) <= offset { return nil } - return extra[ap3.WindowSize:] + return extra[offset:] } diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index 345c2b776d..2439d087b2 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -7,8 +7,10 @@ import ( "math/big" "testing" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" @@ -18,16 +20,18 @@ import ( func TestExtraPrefix(t *testing.T) { tests := []struct { - name string - upgrades params.NetworkUpgrades - parent *types.Header - timestamp uint64 - want []byte - wantErr error + name string + upgrades params.NetworkUpgrades + parent *types.Header + header *types.Header + desiredTargetExcess *gas.Gas + want []byte + wantErr error }{ { name: "ap2", upgrades: params.TestApricotPhase2Config.NetworkUpgrades, + header: &types.Header{}, want: nil, wantErr: nil, }, @@ -39,8 +43,10 @@ func TestExtraPrefix(t *testing.T) { parent: &types.Header{ Number: big.NewInt(1), }, - timestamp: 1, - want: (&ap3.Window{}).Bytes(), + header: &types.Header{ + Time: 1, + }, + want: (&ap3.Window{}).Bytes(), }, { name: "ap3_genesis_block", @@ -48,7 +54,8 @@ func TestExtraPrefix(t *testing.T) { parent: &types.Header{ Number: big.NewInt(0), }, - want: (&ap3.Window{}).Bytes(), + header: &types.Header{}, + want: (&ap3.Window{}).Bytes(), }, { name: "ap3_invalid_fee_window", @@ -56,6 +63,7 @@ func TestExtraPrefix(t *testing.T) { parent: &types.Header{ Number: big.NewInt(1), }, + header: &types.Header{}, wantErr: ap3.ErrWindowInsufficientLength, }, { @@ -66,8 +74,10 @@ func TestExtraPrefix(t *testing.T) { Time: 1, Extra: (&ap3.Window{}).Bytes(), }, - timestamp: 0, - wantErr: errInvalidTimestamp, + header: &types.Header{ + Time: 0, + }, + wantErr: errInvalidTimestamp, }, { name: "ap3_normal", @@ -79,7 +89,9 @@ func TestExtraPrefix(t *testing.T) { 1, 2, 3, 4, }).Bytes(), }, - timestamp: 1, + header: &types.Header{ + Time: 1, + }, want: func() []byte { window := ap3.Window{ 1, 2, 3, 4, @@ -95,7 +107,8 @@ func TestExtraPrefix(t *testing.T) { parent: &types.Header{ Number: big.NewInt(0), }, - want: (&ap3.Window{}).Bytes(), + header: &types.Header{}, + want: (&ap3.Window{}).Bytes(), }, { name: "ap4_no_block_gas_cost", @@ -105,7 +118,9 @@ func TestExtraPrefix(t *testing.T) { GasUsed: ap3.TargetGas, Extra: (&ap3.Window{}).Bytes(), }, - timestamp: 2, + header: &types.Header{ + Time: 2, + }, want: func() []byte { var window ap3.Window window.Add(ap3.TargetGas) @@ -122,7 +137,9 @@ func TestExtraPrefix(t *testing.T) { Extra: (&ap3.Window{}).Bytes(), BlockGasCost: big.NewInt(ap4.MinBlockGasCost), }, - timestamp: 1, + header: &types.Header{ + Time: 1, + }, want: func() []byte { var window ap3.Window window.Add( @@ -142,7 +159,9 @@ func TestExtraPrefix(t *testing.T) { Extra: (&ap3.Window{}).Bytes(), ExtDataGasUsed: big.NewInt(5), }, - timestamp: 1, + header: &types.Header{ + Time: 1, + }, want: func() []byte { var window ap3.Window window.Add( @@ -165,7 +184,9 @@ func TestExtraPrefix(t *testing.T) { ExtDataGasUsed: big.NewInt(5), BlockGasCost: big.NewInt(ap4.MinBlockGasCost), }, - timestamp: 1, + header: &types.Header{ + Time: 1, + }, want: func() []byte { window := ap3.Window{ 1, 2, 3, 4, @@ -188,7 +209,9 @@ func TestExtraPrefix(t *testing.T) { Extra: (&ap3.Window{}).Bytes(), BlockGasCost: big.NewInt(ap4.MinBlockGasCost), }, - timestamp: 1, + header: &types.Header{ + Time: 1, + }, want: func() []byte { var window ap3.Window window.Add(ap5.TargetGas) @@ -208,7 +231,9 @@ func TestExtraPrefix(t *testing.T) { ExtDataGasUsed: big.NewInt(5), BlockGasCost: big.NewInt(ap4.MinBlockGasCost), }, - timestamp: 1, + header: &types.Header{ + Time: 1, + }, want: func() []byte { window := ap3.Window{ 1, 2, 3, 4, @@ -221,6 +246,94 @@ func TestExtraPrefix(t *testing.T) { return window.Bytes() }(), }, + { + name: "fupgrade_first_block", + upgrades: params.NetworkUpgrades{ + FUpgradeTimestamp: utils.NewUint64(1), + }, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{ + Time: 1, + GasUsed: 1, + ExtDataGasUsed: big.NewInt(5), + }, + want: (&acp176.State{ + Gas: gas.State{ + Capacity: acp176.MinMaxPerSecond - 6, + Excess: 6, + }, + TargetExcess: 0, + }).Bytes(), + }, + { + name: "fupgrade_genesis_block", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: 2, + ExtDataGasUsed: big.NewInt(1), + }, + desiredTargetExcess: (*gas.Gas)(utils.NewUint64(3)), + want: (&acp176.State{ + Gas: gas.State{ + Capacity: acp176.MinMaxPerSecond - 3, + Excess: 3, + }, + TargetExcess: 3, + }).Bytes(), + }, + { + name: "fupgrade_invalid_fee_state", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_invalid_gas_used", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + Extra: (&acp176.State{}).Bytes(), + }, + header: &types.Header{ + GasUsed: 1, + }, + wantErr: gas.ErrInsufficientCapacity, + }, + { + name: "fupgrade_reduce_capacity", + upgrades: params.TestFUpgradeChainConfig.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, + ExtDataGasUsed: big.NewInt(1), + }, + 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) { @@ -229,13 +342,124 @@ func TestExtraPrefix(t *testing.T) { config := ¶ms.ChainConfig{ NetworkUpgrades: test.upgrades, } - got, err := ExtraPrefix(config, test.parent, test.timestamp) + got, err := ExtraPrefix(config, test.parent, test.header, test.desiredTargetExcess) require.ErrorIs(err, test.wantErr) require.Equal(test.want, got) }) } } +func TestVerifyExtraPrefix(t *testing.T) { + tests := []struct { + name string + upgrades params.NetworkUpgrades + parent *types.Header + header *types.Header + wantErr error + }{ + { + name: "ap2", + upgrades: params.TestApricotPhase2Config.NetworkUpgrades, + header: &types.Header{}, + wantErr: nil, + }, + { + name: "ap3_invalid_parent_header", + upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + wantErr: ap3.ErrWindowInsufficientLength, + }, + { + name: "ap3_invalid_header", + upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{}, + wantErr: errInvalidExtraPrefix, + }, + { + name: "ap3_valid", + upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Extra: (&ap3.Window{}).Bytes(), + }, + wantErr: nil, + }, + { + name: "fupgrade_invalid_header", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + header: &types.Header{}, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_invalid_gas_consumed", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasUsed: 1, + Extra: (&acp176.State{}).Bytes(), + }, + wantErr: gas.ErrInsufficientCapacity, + }, + { + name: "fupgrade_wrong_fee_state", + upgrades: params.TestFUpgradeChainConfig.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: "fupgrade_valid", + upgrades: params.TestFUpgradeChainConfig.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) { + config := ¶ms.ChainConfig{ + NetworkUpgrades: test.upgrades, + } + err := VerifyExtraPrefix(config, test.parent, test.header) + require.ErrorIs(t, err, test.wantErr) + }) + } +} + func TestVerifyExtra(t *testing.T) { tests := []struct { name string @@ -319,6 +543,30 @@ func TestVerifyExtra(t *testing.T) { extra: make([]byte, ap3.WindowSize-1), expected: errInvalidExtraLength, }, + { + name: "fupgrade_valid_min", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: make([]byte, acp176.StateSize), + expected: nil, + }, + { + name: "fupgrade_valid_extra", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: make([]byte, acp176.StateSize+1), + expected: nil, + }, + { + name: "fupgrade_invalid", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: make([]byte, acp176.StateSize-1), + expected: errInvalidExtraLength, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -357,6 +605,40 @@ func TestPredicateBytesFromExtra(t *testing.T) { }, expected: []byte{5}, }, + { + name: "fupgrade_empty_extra", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: nil, + expected: nil, + }, + { + name: "fupgrade_too_short", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: make([]byte, acp176.StateSize-1), + expected: nil, + }, + { + name: "fupgrade_empty_predicate", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: make([]byte, acp176.StateSize), + expected: nil, + }, + { + name: "fupgrade_non_empty_predicate", + rules: params.AvalancheRules{ + IsFUpgrade: true, + }, + extra: []byte{ + acp176.StateSize: 5, + }, + expected: []byte{5}, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index 2733c3ef9c..fd31d4c8e6 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -11,10 +11,15 @@ import ( "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" ) -var errInvalidGasLimit = errors.New("invalid gas limit") +var ( + errInvalidExtraDataGasUsed = errors.New("invalid extra data gas used") + 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 // calculates the gas limit for the child block. @@ -22,12 +27,22 @@ func GasLimit( config *params.ChainConfig, parent *types.Header, timestamp uint64, -) uint64 { +) (uint64, error) { switch { + case config.IsFUpgrade(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.IsCortina(timestamp): - return cortina.GasLimit + return cortina.GasLimit, nil case config.IsApricotPhase1(timestamp): - return ap1.GasLimit + return ap1.GasLimit, nil default: // The gas limit prior Apricot Phase 1 started at the genesis value and // migrated towards the [ap1.GasLimit] following the `core.CalcGasLimit` @@ -35,10 +50,46 @@ func GasLimit( // this code is not used in production. To avoid a dependency on the // `core` package, this code is modified to just return the parent gas // limit; which was valid to do prior to Apricot Phase 1. - return parent.GasLimit + return parent.GasLimit, nil } } +// VerifyGasUsed verifies that the gas used is less than or equal to the gas +// limit. +func VerifyGasUsed( + config *params.ChainConfig, + parent *types.Header, + header *types.Header, +) error { + gasUsed := header.GasUsed + if config.IsFUpgrade(header.Time) && header.ExtDataGasUsed != nil { + if !header.ExtDataGasUsed.IsUint64() { + return fmt.Errorf("%w: %d is not a uint64", + errInvalidExtraDataGasUsed, + header.ExtDataGasUsed, + ) + } + var err error + gasUsed, err = math.Add(gasUsed, header.ExtDataGasUsed.Uint64()) + if err != nil { + return fmt.Errorf("%w while calculating gas used", err) + } + } + + capacity, err := GasCapacity(config, parent, header.Time) + if err != nil { + return fmt.Errorf("calculating gas capacity: %w", err) + } + if gasUsed > capacity { + return fmt.Errorf("%w: have %d, capacity %d", + errInvalidGasUsed, + gasUsed, + capacity, + ) + } + return nil +} + // VerifyGasLimit verifies that the gas limit for the header is valid. func VerifyGasLimit( config *params.ChainConfig, @@ -46,6 +97,19 @@ func VerifyGasLimit( header *types.Header, ) error { switch { + case config.IsFUpgrade(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.IsCortina(header.Time): if header.GasLimit != cortina.GasLimit { return fmt.Errorf("%w: expected to be %d in Cortina, but found %d", @@ -86,3 +150,46 @@ func VerifyGasLimit( } return nil } + +// GasCapacity takes the previous header and the timestamp of its child block +// and calculates the available gas that can be consumed in the child block. +func GasCapacity( + config *params.ChainConfig, + parent *types.Header, + timestamp uint64, +) (uint64, error) { + // Prior to the F upgrade, the gas capacity is equal to the gas limit. + if !config.IsFUpgrade(timestamp) { + return GasLimit(config, 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 +} + +// RemainingAtomicGasCapacity returns the maximum amount ExtDataGasUsed could be +// on `header` while still being valid based on the initial capacity and +// consumed gas. +func RemainingAtomicGasCapacity( + config *params.ChainConfig, + parent *types.Header, + header *types.Header, +) (uint64, error) { + // Prior to the F upgrade, the atomic gas limit was a constant independent + // of the evm gas used. + if !config.IsFUpgrade(header.Time) { + return ap5.AtomicGasLimit, nil + } + + state, err := feeStateBeforeBlock(config, parent, header.Time) + if err != nil { + return 0, fmt.Errorf("calculating initial fee state: %w", err) + } + if err := state.ConsumeGas(header.GasUsed, nil); err != nil { + return 0, fmt.Errorf("%w while calculating available gas", 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 f02735848f..b4f45fdf1e 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -4,12 +4,18 @@ package header import ( + "math/big" "testing" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) @@ -20,7 +26,24 @@ func TestGasLimit(t *testing.T) { parent *types.Header timestamp uint64 want uint64 + wantErr error }{ + { + name: "fupgrade_invalid_parent_header", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_initial_max_capacity", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + want: acp176.MinMaxCapacity, + }, { name: "cortina", upgrades: params.TestCortinaChainConfig.NetworkUpgrades, @@ -42,11 +65,99 @@ func TestGasLimit(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { + require := require.New(t) + config := ¶ms.ChainConfig{ NetworkUpgrades: test.upgrades, } - got := GasLimit(config, test.parent, test.timestamp) - require.Equal(t, test.want, got) + got, err := GasLimit(config, test.parent, test.timestamp) + require.ErrorIs(err, test.wantErr) + require.Equal(test.want, got) + }) + } +} + +func TestVerifyGasUsed(t *testing.T) { + tests := []struct { + name string + upgrades params.NetworkUpgrades + parent *types.Header + header *types.Header + want error + }{ + { + name: "fupgrade_massive_extra_gas_used", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + header: &types.Header{ + ExtDataGasUsed: new(big.Int).Lsh(common.Big1, 64), + }, + want: errInvalidExtraDataGasUsed, + }, + { + name: "fupgrade_gas_used_overflow", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + header: &types.Header{ + GasUsed: math.MaxUint[uint64](), + ExtDataGasUsed: common.Big1, + }, + want: math.ErrOverflow, + }, + { + name: "fupgrade_invalid_capacity", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + want: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_invalid_usage", + upgrades: params.TestFUpgradeChainConfig.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: "fupgrade_max_consumption", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: acp176.MinMaxPerSecond, + }, + want: nil, + }, + { + name: "cortina_does_not_include_extra_gas_used", + upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasUsed: cortina.GasLimit, + ExtDataGasUsed: common.Big1, + }, + want: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + config := ¶ms.ChainConfig{ + NetworkUpgrades: test.upgrades, + } + err := VerifyGasUsed(config, test.parent, test.header) + require.ErrorIs(t, err, test.want) }) } } @@ -59,6 +170,36 @@ func TestVerifyGasLimit(t *testing.T) { header *types.Header want error }{ + { + name: "fupgrade_invalid_header", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + want: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_invalid", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasLimit: acp176.MinMaxCapacity + 1, + }, + want: errInvalidGasLimit, + }, + { + name: "fupgrade_valid", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasLimit: acp176.MinMaxCapacity, + }, + }, { name: "cortina_valid", upgrades: params.TestCortinaChainConfig.NetworkUpgrades, @@ -143,3 +284,111 @@ func TestVerifyGasLimit(t *testing.T) { }) } } + +func TestGasCapacity(t *testing.T) { + tests := []struct { + name string + upgrades params.NetworkUpgrades + parent *types.Header + timestamp uint64 + want uint64 + wantErr error + }{ + { + name: "cortina", + upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + want: cortina.GasLimit, + }, + { + name: "fupgrade_invalid_header", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_after_1s", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + timestamp: 1, + want: acp176.MinMaxPerSecond, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + config := ¶ms.ChainConfig{ + NetworkUpgrades: test.upgrades, + } + got, err := GasCapacity(config, test.parent, test.timestamp) + require.ErrorIs(err, test.wantErr) + require.Equal(test.want, got) + }) + } +} + +func TestRemainingAtomicGasCapacity(t *testing.T) { + tests := []struct { + name string + upgrades params.NetworkUpgrades + parent *types.Header + header *types.Header + want uint64 + wantErr error + }{ + { + name: "ap5", + upgrades: params.TestApricotPhase5Config.NetworkUpgrades, + header: &types.Header{}, + want: ap5.AtomicGasLimit, + }, + { + name: "fupgrade_invalid_header", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(1), + }, + header: &types.Header{}, + wantErr: acp176.ErrStateInsufficientLength, + }, + { + name: "fupgrade_negative_capacity", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + GasUsed: 1, + }, + wantErr: gas.ErrInsufficientCapacity, + }, + { + name: "f", + upgrades: params.TestFUpgradeChainConfig.NetworkUpgrades, + parent: &types.Header{ + Number: big.NewInt(0), + }, + header: &types.Header{ + Time: 1, + GasUsed: 1, + }, + want: acp176.MinMaxPerSecond - 1, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + config := ¶ms.ChainConfig{ + NetworkUpgrades: test.upgrades, + } + got, err := RemainingAtomicGasCapacity(config, test.parent, test.header) + require.ErrorIs(err, test.wantErr) + require.Equal(test.want, got) + }) + } +} diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 1ea093fe67..25342adfc5 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -41,10 +41,10 @@ import ( "github.com/ava-labs/coreth/peer" "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/plugin/evm/config" - "github.com/ava-labs/coreth/plugin/evm/header" + customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/message" + "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" - "github.com/ava-labs/coreth/plugin/evm/upgrade/etna" "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/hashdb" "github.com/ava-labs/coreth/utils" @@ -94,6 +94,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/chain" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/secp256k1fx" commonEng "github.com/ava-labs/avalanchego/snow/engine/common" @@ -131,6 +132,12 @@ const ( targetAtomicTxsSize = 40 * units.KiB + // maxAtomicTxMempoolGas is the maximum amount of gas that is allowed to be + // used by an atomic transaction in the mempool. It is allowed to build + // blocks with larger atomic transactions, but they will not be accepted + // into the mempool. + maxAtomicTxMempoolGas = ap5.AtomicGasLimit + // gossip constants pushGossipDiscardedElements = 16_384 txGossipTargetMessageSize = 20 * units.KiB @@ -647,6 +654,15 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash) error { return err } callbacks := vm.createConsensusCallbacks() + + // 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, @@ -654,7 +670,12 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash) error { vm.chaindb, eth.Settings{MaxBlocksPerRequest: vm.config.MaxBlocksPerRequest}, lastAcceptedHash, - dummy.NewFakerWithClock(callbacks, &vm.clock), + dummy.NewDummyEngine( + callbacks, + dummy.Mode{}, + &vm.clock, + desiredTargetExcess, + ), &vm.clock, ) if err != nil { @@ -668,7 +689,7 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash) error { // Set the gas parameters for the tx pool to the minimum gas price for the // latest upgrade. vm.txPool.SetGasTip(big.NewInt(0)) - vm.txPool.SetMinFee(big.NewInt(etna.MinBaseFee)) + vm.txPool.SetMinFee(big.NewInt(acp176.MinGasPrice)) vm.eth.Start() return vm.initChainState(vm.blockChain.LastAcceptedBlock()) @@ -814,7 +835,12 @@ func (vm *VM) preBatchOnFinalizeAndAssemble(header *types.Header, state *state.S } // assumes that we are in at least Apricot Phase 5. -func (vm *VM) postBatchOnFinalizeAndAssemble(header *types.Header, state *state.StateDB, txs []*types.Transaction) ([]byte, *big.Int, *big.Int, error) { +func (vm *VM) postBatchOnFinalizeAndAssemble( + header *types.Header, + parent *types.Header, + state *state.StateDB, + txs []*types.Transaction, +) ([]byte, *big.Int, *big.Int, error) { var ( batchAtomicTxs []*atomic.Tx batchAtomicUTXOs set.Set[ids.ID] @@ -824,6 +850,11 @@ func (vm *VM) postBatchOnFinalizeAndAssemble(header *types.Header, state *state. size int ) + atomicGasLimit, err := customheader.RemainingAtomicGasCapacity(vm.chainConfig, parent, header) + if err != nil { + return nil, nil, nil, err + } + for { tx, exists := vm.mempool.NextTx() if !exists { @@ -849,8 +880,8 @@ func (vm *VM) postBatchOnFinalizeAndAssemble(header *types.Header, state *state. if err != nil { return nil, nil, nil, err } - // ensure [gasUsed] + [batchGasUsed] doesnt exceed the [atomicGasLimit] - if totalGasUsed := new(big.Int).Add(batchGasUsed, txGasUsed); !utils.BigLessOrEqualUint64(totalGasUsed, ap5.AtomicGasLimit) { + // ensure `gasUsed + batchGasUsed` doesn't exceed `atomicGasLimit` + if totalGasUsed := new(big.Int).Add(batchGasUsed, txGasUsed); !utils.BigLessOrEqualUint64(totalGasUsed, atomicGasLimit) { // Send [tx] back to the mempool's tx heap. vm.mempool.CancelCurrentTx(tx.ID()) break @@ -914,14 +945,19 @@ func (vm *VM) postBatchOnFinalizeAndAssemble(header *types.Header, state *state. return nil, nil, nil, nil } -func (vm *VM) onFinalizeAndAssemble(header *types.Header, state *state.StateDB, txs []*types.Transaction) ([]byte, *big.Int, *big.Int, error) { +func (vm *VM) onFinalizeAndAssemble( + header *types.Header, + parent *types.Header, + state *state.StateDB, + txs []*types.Transaction, +) ([]byte, *big.Int, *big.Int, error) { if !vm.chainConfig.IsApricotPhase5(header.Time) { return vm.preBatchOnFinalizeAndAssemble(header, state, txs) } - return vm.postBatchOnFinalizeAndAssemble(header, state, txs) + return vm.postBatchOnFinalizeAndAssemble(header, parent, state, txs) } -func (vm *VM) onExtraStateChange(block *types.Block, state *state.StateDB) (*big.Int, *big.Int, error) { +func (vm *VM) onExtraStateChange(block *types.Block, parent *types.Header, state *state.StateDB) (*big.Int, *big.Int, error) { var ( batchContribution *big.Int = big.NewInt(0) batchGasUsed *big.Int = big.NewInt(0) @@ -973,14 +1009,18 @@ func (vm *VM) onExtraStateChange(block *types.Block, state *state.StateDB) (*big batchContribution.Add(batchContribution, contribution) batchGasUsed.Add(batchGasUsed, gasUsed) } + } - // If ApricotPhase5 is enabled, enforce that the atomic gas used does not exceed the - // atomic gas limit. - if rules.IsApricotPhase5 { - // Ensure that [tx] does not push [block] above the atomic gas limit. - if !utils.BigLessOrEqualUint64(batchGasUsed, ap5.AtomicGasLimit) { - return nil, nil, fmt.Errorf("atomic gas used (%d) by block (%s), exceeds atomic gas limit (%d)", batchGasUsed, block.Hash().Hex(), ap5.AtomicGasLimit) - } + // If ApricotPhase5 is enabled, enforce that the atomic gas used does not exceed the + // atomic gas limit. + if rules.IsApricotPhase5 { + atomicGasLimit, err := customheader.RemainingAtomicGasCapacity(vm.chainConfig, parent, header) + if err != nil { + return nil, nil, err + } + + if !utils.BigLessOrEqualUint64(batchGasUsed, atomicGasLimit) { + return nil, nil, fmt.Errorf("atomic gas used (%d) by block (%s), exceeds atomic gas limit (%d)", batchGasUsed, block.Hash().Hex(), atomicGasLimit) } } return batchContribution, batchGasUsed, nil @@ -1566,8 +1606,8 @@ func (vm *VM) verifyTxAtTip(tx *atomic.Tx) error { if err != nil { return err } - if gasUsed > ap5.AtomicGasLimit { - return fmt.Errorf("tx gas usage (%d) exceeds atomic gas limit (%d)", gasUsed, ap5.AtomicGasLimit) + if gasUsed > maxAtomicTxMempoolGas { + return fmt.Errorf("tx gas usage (%d) exceeds maximum allowed mempool gas usage (%d)", gasUsed, maxAtomicTxMempoolGas) } // Note: we fetch the current block and then the state at that block instead of the current state directly @@ -1582,7 +1622,7 @@ func (vm *VM) verifyTxAtTip(tx *atomic.Tx) error { var nextBaseFee *big.Int timestamp := uint64(vm.clock.Time().Unix()) if vm.chainConfig.IsApricotPhase3(timestamp) { - nextBaseFee, err = header.EstimateNextBaseFee(vm.chainConfig, parentHeader, timestamp) + nextBaseFee, err = customheader.EstimateNextBaseFee(vm.chainConfig, parentHeader, timestamp) if err != nil { // Return extremely detailed error since CalcBaseFee should never encounter an issue here return fmt.Errorf("failed to calculate base fee with parent timestamp (%d), parent ExtraData: (0x%x), and current timestamp (%d): %w", parentHeader.Time, parentHeader.Extra, timestamp, err) diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index 42a123f227..0f1049e892 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -3773,7 +3773,7 @@ func TestExtraStateChangeAtomicGasLimitExceeded(t *testing.T) { } // Hack: test [onExtraStateChange] directly to ensure it catches the atomic gas limit error correctly. - if _, _, err := vm2.onExtraStateChange(ethBlk2, state); err == nil || !strings.Contains(err.Error(), "exceeds atomic gas limit") { + if _, _, err := vm2.onExtraStateChange(ethBlk2, nil, state); err == nil || !strings.Contains(err.Error(), "exceeds atomic gas limit") { t.Fatalf("Expected block to fail verification due to exceeded atomic gas limit, but found error: %v", err) } }