From d120ff23cee3d602f608fc7fdc509ed2a6aa4e3c Mon Sep 17 00:00:00 2001 From: abelliu Date: Mon, 5 Feb 2024 15:22:27 +0800 Subject: [PATCH 01/13] R4R: mint eth to msg.from and transfer revertable (#31) --- core/genesis.go | 1 + core/mantle_upgrade.go | 24 ++++--- core/state_transition.go | 95 +++++++++++++++++++++++---- core/types/deposit_tx.go | 6 ++ core/types/transaction.go | 9 +++ core/types/transaction_marshalling.go | 6 ++ internal/ethapi/api.go | 2 + params/config.go | 44 +++++++------ 8 files changed, 148 insertions(+), 39 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index 2803902814..4ff4b1f8a0 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -310,6 +310,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen mantleUpgradeChainConfig := GetUpgradeConfigForMantle(config.ChainID) if mantleUpgradeChainConfig != nil { config.BaseFeeTime = mantleUpgradeChainConfig.BaseFeeTime + config.BVMETHMintUpgradeTime = mantleUpgradeChainConfig.BVMETHMintUpgradeTime } if overrides != nil && overrides.OverrideShanghai != nil { diff --git a/core/mantle_upgrade.go b/core/mantle_upgrade.go index f23fcd816d..c2a49fc783 100644 --- a/core/mantle_upgrade.go +++ b/core/mantle_upgrade.go @@ -8,26 +8,32 @@ import ( var ( MantleMainnetUpgradeConfig = MantleUpgradeChainConfig{ - ChainID: params.MantleMainnetChainId, - BaseFeeTime: u64Ptr(0), + ChainID: params.MantleMainnetChainId, + BaseFeeTime: u64Ptr(0), + BVMETHMintUpgradeTime: u64Ptr(0), } MantleSepoliaUpgradeConfig = MantleUpgradeChainConfig{ - ChainID: params.MantleSepoliaChainId, - BaseFeeTime: u64Ptr(1_704_891_600), + ChainID: params.MantleSepoliaChainId, + BaseFeeTime: u64Ptr(1_704_891_600), + BVMETHMintUpgradeTime: nil, //TODO set upgrade timestamp } MantleLocalUpgradeConfig = MantleUpgradeChainConfig{ - ChainID: params.MantleLocalChainId, - BaseFeeTime: u64Ptr(0), + ChainID: params.MantleLocalChainId, + BaseFeeTime: u64Ptr(0), + BVMETHMintUpgradeTime: u64Ptr(0), } MantleDefaultUpgradeConfig = MantleUpgradeChainConfig{ - BaseFeeTime: u64Ptr(0), + BaseFeeTime: u64Ptr(0), + BVMETHMintUpgradeTime: u64Ptr(0), } ) type MantleUpgradeChainConfig struct { - ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection - BaseFeeTime *uint64 `json:"BaseFeeTime"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) + ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection + + BaseFeeTime *uint64 `json:"BaseFeeTime"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) + BVMETHMintUpgradeTime *uint64 `json:"BVMETHMintUpgradeTime"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) } func GetUpgradeConfigForMantle(chainID *big.Int) *MantleUpgradeChainConfig { diff --git a/core/state_transition.go b/core/state_transition.go index 0566e9a4ab..352e79e386 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -161,6 +161,7 @@ type Message struct { IsDepositTx bool // IsDepositTx indicates the message is force-included and can persist a mint. Mint *big.Int // Mint is the amount to mint before EVM processing, or nil if there is no minting. ETHValue *big.Int // ETHValue is the amount to mint BVM_ETH before EVM processing, or nil if there is no minting. + ETHTxValue *big.Int // ETHTxValue is the amount to be transferred to msg.To before EVM processing, and the transfer will be reverted if EVM failed MetaTxParams *types.MetaTxParams // MetaTxParams contains necessary parameter to sponsor gas fee for msg.From. RollupDataGas types.RollupGasData // RollupDataGas indicates the rollup cost of the message, 0 if not a rollup or no cost. @@ -189,6 +190,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In Mint: tx.Mint(), RollupDataGas: tx.RollupDataGas(), ETHValue: tx.ETHValue(), + ETHTxValue: tx.ETHTxValue(), MetaTxParams: metaTxParams, SkipAccountChecks: false, RunMode: CommitMode, @@ -438,19 +440,18 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if mint := st.msg.Mint; mint != nil { st.state.AddBalance(st.msg.From, mint) } + + //Mint BVM_ETH + rules := st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time) //add eth value if ethValue := st.msg.ETHValue; ethValue != nil && ethValue.Cmp(big.NewInt(0)) != 0 { - var ethRecipient common.Address - if st.msg.To != nil { - ethRecipient = *st.msg.To - } else { - ethRecipient = crypto.CreateAddress(st.msg.From, st.evm.StateDB.GetNonce(st.msg.From)) - } - st.addBVMETHBalance(ethRecipient, ethValue) - st.addBVMETHTotalSupply(ethValue) - st.generateBVMETHMintEvent(ethRecipient, ethValue) + st.mintBVMETH(ethValue, rules) } snap := st.state.Snapshot() + // Will be reverted if failed + if ethTxValue := st.msg.ETHTxValue; ethTxValue != nil && ethTxValue.Cmp(big.NewInt(0)) != 0 { + st.transferBVMETH(ethTxValue, rules) + } result, err := st.innerTransitionDb() // Failed deposits must still be included. Unless we cannot produce the block at all due to the gas limit. @@ -671,12 +672,33 @@ func (st *StateTransition) gasUsed() uint64 { return st.initialGas - st.gasRemaining } -func (st *StateTransition) addBVMETHBalance(ethRecipient common.Address, ethValue *big.Int) { - key := getBVMETHBalanceKey(ethRecipient) +func (st *StateTransition) mintBVMETH(ethValue *big.Int, rules params.Rules) { + if !rules.IsMantleBVMETHMintUpgrade { + var key common.Hash + var ethRecipient common.Address + if st.msg.To != nil { + ethRecipient = *st.msg.To + } else { + ethRecipient = crypto.CreateAddress(st.msg.From, st.evm.StateDB.GetNonce(st.msg.From)) + } + key = getBVMETHBalanceKey(ethRecipient) + value := st.state.GetState(BVM_ETH_ADDR, key) + bal := value.Big() + bal = bal.Add(bal, ethValue) + st.state.SetState(BVM_ETH_ADDR, key, common.BigToHash(bal)) + + st.addBVMETHTotalSupply(ethValue) + st.generateBVMETHMintEvent(ethRecipient, ethValue) + return + } + key := getBVMETHBalanceKey(st.msg.From) value := st.state.GetState(BVM_ETH_ADDR, key) bal := value.Big() bal = bal.Add(bal, ethValue) st.state.SetState(BVM_ETH_ADDR, key, common.BigToHash(bal)) + + st.addBVMETHTotalSupply(ethValue) + st.generateBVMETHMintEvent(st.msg.From, ethValue) } func (st *StateTransition) addBVMETHTotalSupply(ethValue *big.Int) { @@ -687,6 +709,38 @@ func (st *StateTransition) addBVMETHTotalSupply(ethValue *big.Int) { st.state.SetState(BVM_ETH_ADDR, key, common.BigToHash(bal)) } +func (st *StateTransition) transferBVMETH(ethValue *big.Int, rules params.Rules) { + if !rules.IsMantleBVMETHMintUpgrade { + return + } + var ethRecipient common.Address + if st.msg.To != nil { + ethRecipient = *st.msg.To + } else { + ethRecipient = crypto.CreateAddress(st.msg.From, st.evm.StateDB.GetNonce(st.msg.From)) + } + if ethRecipient == st.msg.From { + return + } + + fromKey := getBVMETHBalanceKey(st.msg.From) + toKey := getBVMETHBalanceKey(ethRecipient) + + fromBalanceValue := st.state.GetState(BVM_ETH_ADDR, fromKey) + toBalanceValue := st.state.GetState(BVM_ETH_ADDR, toKey) + + fromBalance := fromBalanceValue.Big() + toBalance := toBalanceValue.Big() + + fromBalance = new(big.Int).Sub(fromBalance, ethValue) + toBalance = new(big.Int).Add(toBalance, ethValue) + + st.state.SetState(BVM_ETH_ADDR, fromKey, common.BigToHash(fromBalance)) + st.state.SetState(BVM_ETH_ADDR, toKey, common.BigToHash(toBalance)) + + st.generateBVMETHTransferEvent(st.msg.From, ethRecipient, ethValue) +} + func getBVMETHBalanceKey(addr common.Address) common.Hash { position := common.Big0 hasher := sha3.NewLegacyKeccak256() @@ -717,3 +771,22 @@ func (st *StateTransition) generateBVMETHMintEvent(mintAddress common.Address, m BlockNumber: st.evm.Context.BlockNumber.Uint64(), }) } + +func (st *StateTransition) generateBVMETHTransferEvent(from, to common.Address, amount *big.Int) { + // keccak("Transfer(address,address,uint256)") = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + methodHash := common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") + topics := make([]common.Hash, 3) + topics[0] = methodHash + topics[1] = from.Hash() + topics[2] = to.Hash() + //data means the transfer amount in Transfer EVENT. + data := common.HexToHash(common.Bytes2Hex(amount.Bytes())).Bytes() + st.evm.StateDB.AddLog(&types.Log{ + Address: BVM_ETH_ADDR, + Topics: topics, + Data: data, + // This is a non-consensus field, but assigned here because + // core/state doesn't know the current block number. + BlockNumber: st.evm.Context.BlockNumber.Uint64(), + }) +} diff --git a/core/types/deposit_tx.go b/core/types/deposit_tx.go index f4917a11f3..7dece4a6a1 100644 --- a/core/types/deposit_tx.go +++ b/core/types/deposit_tx.go @@ -43,6 +43,8 @@ type DepositTx struct { EthValue *big.Int `rlp:"nil"` // Normal Tx data Data []byte + // EthTxValue means L2 BVM_ETH tx tag, nil means that there is no need to transfer BVM_ETH to msg.To. + EthTxValue *big.Int `rlp:"optional"` } // copy creates a deep copy of the transaction data and initializes all fields. @@ -57,6 +59,7 @@ func (tx *DepositTx) copy() TxData { IsSystemTransaction: tx.IsSystemTransaction, Data: common.CopyBytes(tx.Data), EthValue: nil, + EthTxValue: nil, } if tx.Mint != nil { cpy.Mint = new(big.Int).Set(tx.Mint) @@ -67,6 +70,9 @@ func (tx *DepositTx) copy() TxData { if tx.EthValue != nil { cpy.EthValue = new(big.Int).Set(tx.EthValue) } + if tx.EthTxValue != nil { + cpy.EthTxValue = new(big.Int).Set(tx.EthTxValue) + } return cpy } diff --git a/core/types/transaction.go b/core/types/transaction.go index 02a7e1dca8..d4a6622056 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -354,6 +354,15 @@ func (tx *Transaction) ETHValue() *big.Int { return nil } +// ETHTxValue returns the BVM_ETH to be transferred in the deposit tx. +// This returns nil if there is nothing to transfer, or if this is not a deposit tx. +func (tx *Transaction) ETHTxValue() *big.Int { + if dep, ok := tx.inner.(*DepositTx); ok { + return dep.EthTxValue + } + return nil +} + // IsDepositTx returns true if the transaction is a deposit tx type. func (tx *Transaction) IsDepositTx() bool { return tx.Type() == DepositTxType diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index dcf0e2c921..4253380ec4 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -54,6 +54,7 @@ type txJSON struct { From *common.Address `json:"from,omitempty"` Mint *hexutil.Big `json:"mint,omitempty"` EthValue *hexutil.Big `json:"ethValue,omitempty"` + EthTxValue *hexutil.Big `json:"ethTxValue,omitempty"` IsSystemTx *bool `json:"isSystemTx,omitempty"` // Access list transaction fields: @@ -141,6 +142,9 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { if itx.EthValue != nil { enc.EthValue = (*hexutil.Big)(itx.EthValue) } + if itx.EthTxValue != nil { + enc.EthTxValue = (*hexutil.Big)(itx.EthTxValue) + } enc.IsSystemTx = &itx.IsSystemTransaction // other fields will show up as null. } @@ -419,6 +423,8 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.Mint = (*big.Int)(dec.Mint) // ethValue may be omitted or nil if there is nothing to mint. itx.EthValue = (*big.Int)(dec.EthValue) + // ethValue may be omitted or nil if there is nothing to transfer to msg.To. + itx.EthTxValue = (*big.Int)(dec.EthTxValue) if dec.Data == nil { return errors.New("missing required field 'input' in transaction") } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 9e2039c8d7..213dd990da 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1503,6 +1503,7 @@ type RPCTransaction struct { SourceHash *common.Hash `json:"sourceHash,omitempty"` Mint *hexutil.Big `json:"mint,omitempty"` EthValue *hexutil.Big `json:"ethValue,omitempty"` + EthTxValue *hexutil.Big `json:"ethTxValue,omitempty"` IsSystemTx *bool `json:"isSystemTx,omitempty"` } @@ -1543,6 +1544,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber } result.Mint = (*hexutil.Big)(tx.Mint()) result.EthValue = (*hexutil.Big)(tx.ETHValue()) + result.EthTxValue = (*hexutil.Big)(tx.ETHTxValue()) if receipt != nil && receipt.DepositNonce != nil { result.Nonce = hexutil.Uint64(*receipt.DepositNonce) } diff --git a/params/config.go b/params/config.go index a7aad50fff..d753381307 100644 --- a/params/config.go +++ b/params/config.go @@ -458,8 +458,8 @@ type ChainConfig struct { MergeNetsplitBlock *big.Int `json:"mergeNetsplitBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter // Mantle upgrade configs - BaseFeeTime *uint64 `json:"baseFeeTime,omitempty"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) - + BaseFeeTime *uint64 `json:"baseFeeTime,omitempty"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) + BVMETHMintUpgradeTime *uint64 `json:"bvmETHMintUpgradeTime,omitempty"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) // Fork scheduling was switched from blocks to timestamps here ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) @@ -677,6 +677,11 @@ func (c *ChainConfig) IsMantleBaseFee(time uint64) bool { return isTimestampForked(c.BaseFeeTime, time) } +// IsMantleBVMETHMintUpgrade returns whether time is either equal to the BVM_ETH mint upgrade fork time or greater. +func (c *ChainConfig) IsMantleBVMETHMintUpgrade(time uint64) bool { + return isTimestampForked(c.BVMETHMintUpgradeTime, time) +} + // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool { return isBlockForked(c.ArrowGlacierBlock, num) @@ -1046,7 +1051,7 @@ type Rules struct { IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge, IsShanghai, isCancun, isPrague bool - IsMantleBaseFee bool + IsMantleBaseFee, IsMantleBVMETHMintUpgrade bool IsOptimismBedrock, IsOptimismRegolith bool } @@ -1057,22 +1062,23 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules chainID = new(big.Int) } return Rules{ - ChainID: new(big.Int).Set(chainID), - IsHomestead: c.IsHomestead(num), - IsEIP150: c.IsEIP150(num), - IsEIP155: c.IsEIP155(num), - IsEIP158: c.IsEIP158(num), - IsByzantium: c.IsByzantium(num), - IsConstantinople: c.IsConstantinople(num), - IsPetersburg: c.IsPetersburg(num), - IsIstanbul: c.IsIstanbul(num), - IsBerlin: c.IsBerlin(num), - IsLondon: c.IsLondon(num), - IsMerge: isMerge, - IsMantleBaseFee: c.IsMantleBaseFee(timestamp), - IsShanghai: c.IsShanghai(timestamp), - isCancun: c.IsCancun(timestamp), - isPrague: c.IsPrague(timestamp), + ChainID: new(big.Int).Set(chainID), + IsHomestead: c.IsHomestead(num), + IsEIP150: c.IsEIP150(num), + IsEIP155: c.IsEIP155(num), + IsEIP158: c.IsEIP158(num), + IsByzantium: c.IsByzantium(num), + IsConstantinople: c.IsConstantinople(num), + IsPetersburg: c.IsPetersburg(num), + IsIstanbul: c.IsIstanbul(num), + IsBerlin: c.IsBerlin(num), + IsLondon: c.IsLondon(num), + IsMerge: isMerge, + IsMantleBaseFee: c.IsMantleBaseFee(timestamp), + IsMantleBVMETHMintUpgrade: c.IsMantleBVMETHMintUpgrade(timestamp), + IsShanghai: c.IsShanghai(timestamp), + isCancun: c.IsCancun(timestamp), + isPrague: c.IsPrague(timestamp), // Optimism IsOptimismBedrock: c.IsOptimismBedrock(num), IsOptimismRegolith: c.IsOptimismRegolith(timestamp), From 3645f7bee1c98f0b1cddb5684b963a33c1cbfd9a Mon Sep 17 00:00:00 2001 From: wwq Date: Wed, 31 Jan 2024 17:51:29 +0800 Subject: [PATCH 02/13] MetaTxSignData add fromAddr, signHash includes this field --- core/types/meta_transaction.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/types/meta_transaction.go b/core/types/meta_transaction.go index 945af8cc41..701acacb5e 100644 --- a/core/types/meta_transaction.go +++ b/core/types/meta_transaction.go @@ -44,6 +44,7 @@ type MetaTxParamsCache struct { } type MetaTxSignData struct { + From common.Address ChainID *big.Int Nonce uint64 GasTipCap *big.Int @@ -117,7 +118,13 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction) (*MetaTxParams, error) { return nil, ErrInvalidSponsorPercent } + txSender, err := Sender(LatestSignerForChainID(tx.ChainId()), tx) + if err != nil { + return nil, err + } + metaTxSignData := &MetaTxSignData{ + From: txSender, ChainID: tx.ChainId(), Nonce: tx.Nonce(), GasTipCap: tx.GasTipCap(), From 244fc78a8a53d1ebbe94e35827238c01e080bc0e Mon Sep 17 00:00:00 2001 From: wwq Date: Wed, 31 Jan 2024 23:25:18 +0800 Subject: [PATCH 03/13] metaTxSignData fork with metaTxUpdateHeight --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/state_prefetcher.go | 2 +- core/state_processor.go | 4 +- core/state_transition.go | 4 +- core/txpool/txpool.go | 4 +- core/types/meta_transaction.go | 165 ++++++++++++++++++++++---- eth/state_accessor.go | 2 +- eth/tracers/api.go | 12 +- les/state_accessor.go | 2 +- light/txpool.go | 2 +- 10 files changed, 157 insertions(+), 42 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 5f796c1d66..97f1f9325c 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -163,7 +163,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } for i, tx := range txs { - msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee) + msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, pre.Env.Number) if err != nil { log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 72cb249f22..11a74306ea 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -63,7 +63,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c return } // Convert the transaction into an executable message and pre-cache its sender - msg, err := TransactionToMessage(tx, signer, header.BaseFee) + msg, err := TransactionToMessage(tx, signer, header.BaseFee, header.Number.Uint64()) if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index 9ab96672b8..0148750044 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -74,7 +74,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { - msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee) + msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, header.Number.Uint64()) if err != nil { return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } @@ -171,7 +171,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee) + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, header.Number.Uint64()) if err != nil { return nil, err } diff --git a/core/state_transition.go b/core/state_transition.go index 352e79e386..8e4b334639 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -170,8 +170,8 @@ type Message struct { } // TransactionToMessage converts a transaction into a Message. -func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx) +func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int, currentHeight uint64) (*Message, error) { + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, currentHeight) if err != nil { return nil, err } diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 4dda873e44..c693392d8c 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -689,7 +689,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { cost = cost.Add(cost, l1Cost) } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chain.CurrentBlock().Number.Uint64()) if err != nil { return err } @@ -1480,7 +1480,7 @@ func (pool *TxPool) validateMetaTxList(list *list) ([]*types.Transaction, *big.I var invalidMetaTxs []*types.Transaction sponsorCostSum := big.NewInt(0) for _, tx := range list.txs.Flatten() { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, currHeight) if err != nil { invalidMetaTxs = append(invalidMetaTxs, tx) continue diff --git a/core/types/meta_transaction.go b/core/types/meta_transaction.go index 701acacb5e..d64f7e0b8e 100644 --- a/core/types/meta_transaction.go +++ b/core/types/meta_transaction.go @@ -3,6 +3,7 @@ package types import ( "bytes" "errors" + "math" "math/big" "github.com/ethereum/go-ethereum/common" @@ -39,11 +40,39 @@ type MetaTxParams struct { S *big.Int } +//type MetaTxParamsV2 struct { +// ExpireHeight uint64 +// SponsorPercent uint64 +// Payload []byte +// From common.Address +// +// // In tx simulation, Signature will be empty, user can specify GasFeeSponsor to sponsor gas fee +// GasFeeSponsor common.Address +// // Signature values +// V *big.Int +// R *big.Int +// S *big.Int +//} + type MetaTxParamsCache struct { metaTxParams *MetaTxParams } type MetaTxSignData struct { + ChainID *big.Int + Nonce uint64 + GasTipCap *big.Int + GasFeeCap *big.Int + Gas uint64 + To *common.Address `rlp:"nil"` + Value *big.Int + Data []byte + AccessList AccessList + ExpireHeight uint64 + SponsorPercent uint64 +} + +type MetaTxSignDataV2 struct { From common.Address ChainID *big.Int Nonce uint64 @@ -90,7 +119,7 @@ func DecodeMetaTxParams(txData []byte) (*MetaTxParams, error) { return &metaTxParams, nil } -func DecodeAndVerifyMetaTxParams(tx *Transaction) (*MetaTxParams, error) { +func DecodeAndVerifyMetaTxParams(tx *Transaction, currentHeight uint64) (*MetaTxParams, error) { if tx.Type() != DynamicFeeTxType { return nil, nil } @@ -118,42 +147,128 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction) (*MetaTxParams, error) { return nil, ErrInvalidSponsorPercent } - txSender, err := Sender(LatestSignerForChainID(tx.ChainId()), tx) - if err != nil { + var updateHeight uint64 = math.MaxUint64 + + //args := []uint64{updateHeight} + //if currentHeight != nil && len(currentHeight) > 0 { + // args = append(args, currentHeight[0]) + //} + if err := checkSponsorSignature(tx, metaTxParams, updateHeight, currentHeight); err != nil { return nil, err } - metaTxSignData := &MetaTxSignData{ - From: txSender, - ChainID: tx.ChainId(), - Nonce: tx.Nonce(), - GasTipCap: tx.GasTipCap(), - GasFeeCap: tx.GasFeeCap(), - Gas: tx.Gas(), - To: tx.To(), - Value: tx.Value(), - Data: metaTxParams.Payload, - AccessList: tx.AccessList(), - ExpireHeight: metaTxParams.ExpireHeight, - SponsorPercent: metaTxParams.SponsorPercent, + tx.metaTxParams.Store(&MetaTxParamsCache{ + metaTxParams: metaTxParams, + }) + + return metaTxParams, nil +} + +func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, args ...uint64) error { + var ( + gasFeeSponsorSigner common.Address + updateHeight, currentHeight uint64 + ) + if args != nil { + if len(args) == 2 { + updateHeight, currentHeight = args[0], args[1] + } else if len(args) > 2 { + return errors.New("wrong args number") + } } - gasFeeSponsorSigner, err := recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) + txSender, err := Sender(LatestSignerForChainID(tx.ChainId()), tx) if err != nil { - return nil, ErrInvalidGasFeeSponsorSig + return err } - if gasFeeSponsorSigner != metaTxParams.GasFeeSponsor { - return nil, ErrGasFeeSponsorMismatch - } + if args == nil || len(args) < 2 { + metaTxSignData := &MetaTxSignDataV2{ + From: txSender, + ChainID: tx.ChainId(), + Nonce: tx.Nonce(), + GasTipCap: tx.GasTipCap(), + GasFeeCap: tx.GasFeeCap(), + Gas: tx.Gas(), + To: tx.To(), + Value: tx.Value(), + Data: metaTxParams.Payload, + AccessList: tx.AccessList(), + ExpireHeight: metaTxParams.ExpireHeight, + SponsorPercent: metaTxParams.SponsorPercent, + } - tx.metaTxParams.Store(&MetaTxParamsCache{ - metaTxParams: metaTxParams, - }) + gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) + if err != nil { + metaTxSignData := &MetaTxSignData{ + ChainID: tx.ChainId(), + Nonce: tx.Nonce(), + GasTipCap: tx.GasTipCap(), + GasFeeCap: tx.GasFeeCap(), + Gas: tx.Gas(), + To: tx.To(), + Value: tx.Value(), + Data: metaTxParams.Payload, + AccessList: tx.AccessList(), + ExpireHeight: metaTxParams.ExpireHeight, + SponsorPercent: metaTxParams.SponsorPercent, + } - return metaTxParams, nil + gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) + if err != nil { + return ErrInvalidGasFeeSponsorSig + } + } + } else if currentHeight >= updateHeight { + metaTxSignData := &MetaTxSignDataV2{ + From: txSender, + ChainID: tx.ChainId(), + Nonce: tx.Nonce(), + GasTipCap: tx.GasTipCap(), + GasFeeCap: tx.GasFeeCap(), + Gas: tx.Gas(), + To: tx.To(), + Value: tx.Value(), + Data: metaTxParams.Payload, + AccessList: tx.AccessList(), + ExpireHeight: metaTxParams.ExpireHeight, + SponsorPercent: metaTxParams.SponsorPercent, + } + + gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) + if err != nil { + return ErrInvalidGasFeeSponsorSig + } + } else { + metaTxSignData := &MetaTxSignData{ + ChainID: tx.ChainId(), + Nonce: tx.Nonce(), + GasTipCap: tx.GasTipCap(), + GasFeeCap: tx.GasFeeCap(), + Gas: tx.Gas(), + To: tx.To(), + Value: tx.Value(), + Data: metaTxParams.Payload, + AccessList: tx.AccessList(), + ExpireHeight: metaTxParams.ExpireHeight, + SponsorPercent: metaTxParams.SponsorPercent, + } + + gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) + if err != nil { + return ErrInvalidGasFeeSponsorSig + } + } + + if gasFeeSponsorSigner != metaTxParams.GasFeeSponsor { + return ErrGasFeeSponsorMismatch + } + return nil } func (metaTxSignData *MetaTxSignData) Hash() common.Hash { return rlpHash(metaTxSignData) } +func (metaTxSignData *MetaTxSignDataV2) Hash() common.Hash { + return rlpHash(metaTxSignData) +} diff --git a/eth/state_accessor.go b/eth/state_accessor.go index c5f34822e1..c9f250d9de 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -212,7 +212,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, signer := types.MakeSigner(eth.blockchain.Config(), block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb) if idx == txIndex { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 1e831ef40b..ff2ed0d987 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -294,7 +294,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { - msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee()) + msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), task.block.NumberU64()) txctx := &Context{ BlockHash: task.block.Hash(), BlockNumber: task.block.Number(), @@ -584,7 +584,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config return nil, err } var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) txContext = core.NewEVMTxContext(msg) vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{}) ) @@ -658,7 +658,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac ) for i, tx := range txs { // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -701,7 +701,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat // Fetch and execute the next transaction trace tasks for task := range jobs { blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) - msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee()) + msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee(), block.NumberU64()) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -733,7 +733,7 @@ txloop: } // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) statedb.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { @@ -813,7 +813,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block for i, tx := range block.Transactions() { // Prepare the transaction for un-traced execution var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) txContext = core.NewEVMTxContext(msg) vmConf vm.Config dump *os.File diff --git a/les/state_accessor.go b/les/state_accessor.go index b6ba7f8f04..899f241eb2 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -60,7 +60,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. signer := types.MakeSigner(leth.blockchain.Config(), block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil, leth.blockchain.Config(), statedb) statedb.SetTxContext(tx.Hash(), idx) diff --git a/light/txpool.go b/light/txpool.go index 6c79e6ecfb..e8594ef104 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -379,7 +379,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error return txpool.ErrNegativeValue } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, header.Number.Uint64()) if err != nil { return err } From 21cfd30571aef6cd59ad112f13344cc80dd52a39 Mon Sep 17 00:00:00 2001 From: wwq Date: Wed, 31 Jan 2024 23:27:34 +0800 Subject: [PATCH 04/13] change var name --- core/types/meta_transaction.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/types/meta_transaction.go b/core/types/meta_transaction.go index d64f7e0b8e..71a58794c8 100644 --- a/core/types/meta_transaction.go +++ b/core/types/meta_transaction.go @@ -147,13 +147,13 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction, currentHeight uint64) (*MetaTx return nil, ErrInvalidSponsorPercent } - var updateHeight uint64 = math.MaxUint64 + var metaTxUpdataHeight uint64 = math.MaxUint64 //args := []uint64{updateHeight} //if currentHeight != nil && len(currentHeight) > 0 { // args = append(args, currentHeight[0]) //} - if err := checkSponsorSignature(tx, metaTxParams, updateHeight, currentHeight); err != nil { + if err := checkSponsorSignature(tx, metaTxParams, metaTxUpdataHeight, currentHeight); err != nil { return nil, err } From 25af21f5ea6729125d4de10515431e8ddb8bdcbb Mon Sep 17 00:00:00 2001 From: wwq Date: Sun, 4 Feb 2024 10:10:14 +0800 Subject: [PATCH 05/13] metatx upgrade with config --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/genesis.go | 1 + core/mantle_upgrade.go | 9 +- core/state_prefetcher.go | 2 +- core/state_processor.go | 5 +- core/state_transition.go | 4 +- core/txpool/txpool.go | 4 +- core/types/meta_transaction.go | 167 +++++++++++++++++--------- eth/state_accessor.go | 3 +- eth/tracers/api.go | 33 ++--- les/state_accessor.go | 3 +- light/txpool.go | 2 +- params/config.go | 19 +++ 13 files changed, 169 insertions(+), 85 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 97f1f9325c..27c1ffb923 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -163,7 +163,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } for i, tx := range txs { - msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, pre.Env.Number) + msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, chainConfig.IsMetaTxUpgraded(new(big.Int).SetUint64(pre.Env.Number))) if err != nil { log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/core/genesis.go b/core/genesis.go index 4ff4b1f8a0..4b4b1820d6 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -311,6 +311,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen if mantleUpgradeChainConfig != nil { config.BaseFeeTime = mantleUpgradeChainConfig.BaseFeeTime config.BVMETHMintUpgradeTime = mantleUpgradeChainConfig.BVMETHMintUpgradeTime + config.MetaTxUpgradeBlock = mantleUpgradeChainConfig.MetaTxUpgradeBlock } if overrides != nil && overrides.OverrideShanghai != nil { diff --git a/core/mantle_upgrade.go b/core/mantle_upgrade.go index c2a49fc783..bfb99d8126 100644 --- a/core/mantle_upgrade.go +++ b/core/mantle_upgrade.go @@ -11,29 +11,34 @@ var ( ChainID: params.MantleMainnetChainId, BaseFeeTime: u64Ptr(0), BVMETHMintUpgradeTime: u64Ptr(0), + MetaTxUpgradeBlock: u64Ptr(0), } MantleSepoliaUpgradeConfig = MantleUpgradeChainConfig{ ChainID: params.MantleSepoliaChainId, BaseFeeTime: u64Ptr(1_704_891_600), BVMETHMintUpgradeTime: nil, //TODO set upgrade timestamp + MetaTxUpgradeBlock: nil, } MantleLocalUpgradeConfig = MantleUpgradeChainConfig{ ChainID: params.MantleLocalChainId, BaseFeeTime: u64Ptr(0), BVMETHMintUpgradeTime: u64Ptr(0), + MetaTxUpgradeBlock: u64Ptr(0), } MantleDefaultUpgradeConfig = MantleUpgradeChainConfig{ BaseFeeTime: u64Ptr(0), BVMETHMintUpgradeTime: u64Ptr(0), + MetaTxUpgradeBlock: u64Ptr(0), } ) type MantleUpgradeChainConfig struct { ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection - BaseFeeTime *uint64 `json:"BaseFeeTime"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) - BVMETHMintUpgradeTime *uint64 `json:"BVMETHMintUpgradeTime"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) + BaseFeeTime *uint64 `json:"BaseFeeTime"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) + BVMETHMintUpgradeTime *uint64 `json:"BVMETHMintUpgradeTime"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) + MetaTxUpgradeBlock *big.Int `json:"metaTxUpgradeBlock"` // MetaTxUpgradeBlock identifies the current block height is using metaTx with MetaTxSignDataV2 } func GetUpgradeConfigForMantle(chainID *big.Int) *MantleUpgradeChainConfig { diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 11a74306ea..49bcdf21db 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -63,7 +63,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c return } // Convert the transaction into an executable message and pre-cache its sender - msg, err := TransactionToMessage(tx, signer, header.BaseFee, header.Number.Uint64()) + msg, err := TransactionToMessage(tx, signer, header.BaseFee, evm.ChainConfig().IsMetaTxUpgraded(header.Number)) if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index 0148750044..0e941ebcc3 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -72,9 +72,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } blockContext := NewEVMBlockContext(header, p.bc, nil, p.config, statedb) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) + isMetaTxUpgraded := vmenv.ChainConfig().IsMetaTxUpgraded(header.Number) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { - msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, header.Number.Uint64()) + msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, isMetaTxUpgraded) if err != nil { return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } @@ -171,7 +172,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, header.Number.Uint64()) + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, config.IsMetaTxUpgraded(header.Number)) if err != nil { return nil, err } diff --git a/core/state_transition.go b/core/state_transition.go index 8e4b334639..94de728454 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -170,8 +170,8 @@ type Message struct { } // TransactionToMessage converts a transaction into a Message. -func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int, currentHeight uint64) (*Message, error) { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, currentHeight) +func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int, isMetaTxUpgraded bool) (*Message, error) { + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, isMetaTxUpgraded) if err != nil { return nil, err } diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index c693392d8c..be6257afdd 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -689,7 +689,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { cost = cost.Add(cost, l1Cost) } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chain.CurrentBlock().Number.Uint64()) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxUpgraded(pool.chain.CurrentBlock().Number)) if err != nil { return err } @@ -1480,7 +1480,7 @@ func (pool *TxPool) validateMetaTxList(list *list) ([]*types.Transaction, *big.I var invalidMetaTxs []*types.Transaction sponsorCostSum := big.NewInt(0) for _, tx := range list.txs.Flatten() { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, currHeight) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxUpgraded(pool.chain.CurrentBlock().Number)) if err != nil { invalidMetaTxs = append(invalidMetaTxs, tx) continue diff --git a/core/types/meta_transaction.go b/core/types/meta_transaction.go index 71a58794c8..b7bcf004b7 100644 --- a/core/types/meta_transaction.go +++ b/core/types/meta_transaction.go @@ -3,7 +3,6 @@ package types import ( "bytes" "errors" - "math" "math/big" "github.com/ethereum/go-ethereum/common" @@ -119,7 +118,7 @@ func DecodeMetaTxParams(txData []byte) (*MetaTxParams, error) { return &metaTxParams, nil } -func DecodeAndVerifyMetaTxParams(tx *Transaction, currentHeight uint64) (*MetaTxParams, error) { +func DecodeAndVerifyMetaTxParams(tx *Transaction, isMetaTxUpgraded bool) (*MetaTxParams, error) { if tx.Type() != DynamicFeeTxType { return nil, nil } @@ -147,13 +146,7 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction, currentHeight uint64) (*MetaTx return nil, ErrInvalidSponsorPercent } - var metaTxUpdataHeight uint64 = math.MaxUint64 - - //args := []uint64{updateHeight} - //if currentHeight != nil && len(currentHeight) > 0 { - // args = append(args, currentHeight[0]) - //} - if err := checkSponsorSignature(tx, metaTxParams, metaTxUpdataHeight, currentHeight); err != nil { + if err = checkSponsorSignature(tx, metaTxParams, isMetaTxUpgraded); err != nil { return nil, err } @@ -164,62 +157,18 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction, currentHeight uint64) (*MetaTx return metaTxParams, nil } -func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, args ...uint64) error { +func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, isMetaTxUpgraded bool) error { var ( - gasFeeSponsorSigner common.Address - updateHeight, currentHeight uint64 + txSender, gasFeeSponsorSigner common.Address + err error ) - if args != nil { - if len(args) == 2 { - updateHeight, currentHeight = args[0], args[1] - } else if len(args) > 2 { - return errors.New("wrong args number") - } - } - txSender, err := Sender(LatestSignerForChainID(tx.ChainId()), tx) + txSender, err = Sender(LatestSignerForChainID(tx.ChainId()), tx) if err != nil { return err } - if args == nil || len(args) < 2 { - metaTxSignData := &MetaTxSignDataV2{ - From: txSender, - ChainID: tx.ChainId(), - Nonce: tx.Nonce(), - GasTipCap: tx.GasTipCap(), - GasFeeCap: tx.GasFeeCap(), - Gas: tx.Gas(), - To: tx.To(), - Value: tx.Value(), - Data: metaTxParams.Payload, - AccessList: tx.AccessList(), - ExpireHeight: metaTxParams.ExpireHeight, - SponsorPercent: metaTxParams.SponsorPercent, - } - - gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) - if err != nil { - metaTxSignData := &MetaTxSignData{ - ChainID: tx.ChainId(), - Nonce: tx.Nonce(), - GasTipCap: tx.GasTipCap(), - GasFeeCap: tx.GasFeeCap(), - Gas: tx.Gas(), - To: tx.To(), - Value: tx.Value(), - Data: metaTxParams.Payload, - AccessList: tx.AccessList(), - ExpireHeight: metaTxParams.ExpireHeight, - SponsorPercent: metaTxParams.SponsorPercent, - } - - gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) - if err != nil { - return ErrInvalidGasFeeSponsorSig - } - } - } else if currentHeight >= updateHeight { + if isMetaTxUpgraded { metaTxSignData := &MetaTxSignDataV2{ From: txSender, ChainID: tx.ChainId(), @@ -266,6 +215,108 @@ func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, args ... return nil } +//func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, isMetaTxUpgraded bool) error { +// var ( +// gasFeeSponsorSigner common.Address +// updateHeight, currentHeight uint64 +// ) +// if args != nil { +// if len(args) == 2 { +// updateHeight, currentHeight = args[0], args[1] +// } else if len(args) > 2 { +// return errors.New("wrong args number") +// } +// } +// +// txSender, err := Sender(LatestSignerForChainID(tx.ChainId()), tx) +// if err != nil { +// return err +// } +// +// if args == nil || len(args) < 2 { +// metaTxSignData := &MetaTxSignDataV2{ +// From: txSender, +// ChainID: tx.ChainId(), +// Nonce: tx.Nonce(), +// GasTipCap: tx.GasTipCap(), +// GasFeeCap: tx.GasFeeCap(), +// Gas: tx.Gas(), +// To: tx.To(), +// Value: tx.Value(), +// Data: metaTxParams.Payload, +// AccessList: tx.AccessList(), +// ExpireHeight: metaTxParams.ExpireHeight, +// SponsorPercent: metaTxParams.SponsorPercent, +// } +// +// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) +// if err != nil { +// metaTxSignData := &MetaTxSignData{ +// ChainID: tx.ChainId(), +// Nonce: tx.Nonce(), +// GasTipCap: tx.GasTipCap(), +// GasFeeCap: tx.GasFeeCap(), +// Gas: tx.Gas(), +// To: tx.To(), +// Value: tx.Value(), +// Data: metaTxParams.Payload, +// AccessList: tx.AccessList(), +// ExpireHeight: metaTxParams.ExpireHeight, +// SponsorPercent: metaTxParams.SponsorPercent, +// } +// +// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) +// if err != nil { +// return ErrInvalidGasFeeSponsorSig +// } +// } +// } else if currentHeight >= updateHeight { +// metaTxSignData := &MetaTxSignDataV2{ +// From: txSender, +// ChainID: tx.ChainId(), +// Nonce: tx.Nonce(), +// GasTipCap: tx.GasTipCap(), +// GasFeeCap: tx.GasFeeCap(), +// Gas: tx.Gas(), +// To: tx.To(), +// Value: tx.Value(), +// Data: metaTxParams.Payload, +// AccessList: tx.AccessList(), +// ExpireHeight: metaTxParams.ExpireHeight, +// SponsorPercent: metaTxParams.SponsorPercent, +// } +// +// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) +// if err != nil { +// return ErrInvalidGasFeeSponsorSig +// } +// } else { +// metaTxSignData := &MetaTxSignData{ +// ChainID: tx.ChainId(), +// Nonce: tx.Nonce(), +// GasTipCap: tx.GasTipCap(), +// GasFeeCap: tx.GasFeeCap(), +// Gas: tx.Gas(), +// To: tx.To(), +// Value: tx.Value(), +// Data: metaTxParams.Payload, +// AccessList: tx.AccessList(), +// ExpireHeight: metaTxParams.ExpireHeight, +// SponsorPercent: metaTxParams.SponsorPercent, +// } +// +// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) +// if err != nil { +// return ErrInvalidGasFeeSponsorSig +// } +// } +// +// if gasFeeSponsorSigner != metaTxParams.GasFeeSponsor { +// return ErrGasFeeSponsorMismatch +// } +// return nil +//} + func (metaTxSignData *MetaTxSignData) Hash() common.Hash { return rlpHash(metaTxSignData) } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index c9f250d9de..3daef74304 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -210,9 +210,10 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, } // Recompute transactions up to the target index. signer := types.MakeSigner(eth.blockchain.Config(), block.Number()) + isMetaTxUpgraded := eth.blockchain.Config().IsMetaTxUpgraded(block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb) if idx == txIndex { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index ff2ed0d987..5faa5788da 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -289,12 +289,13 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed // Fetch and execute the block trace taskCh for task := range taskCh { var ( - signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number()) - blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) + signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number()) + blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxUpgraded(task.block.Number()) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { - msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), task.block.NumberU64()) + msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), isMetaTxUpgraded) txctx := &Context{ BlockHash: task.block.Hash(), BlockNumber: task.block.Number(), @@ -578,13 +579,14 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config chainConfig = api.backend.ChainConfig() vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxUpgraded(block.Number()) ) for i, tx := range block.Transactions() { if err := ctx.Err(); err != nil { return nil, err } var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) + msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) txContext = core.NewEVMTxContext(msg) vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{}) ) @@ -649,16 +651,17 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac } // Native tracers have low overhead var ( - txs = block.Transactions() - blockHash = block.Hash() - is158 = api.backend.ChainConfig().IsEIP158(block.Number()) - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) - signer = types.MakeSigner(api.backend.ChainConfig(), block.Number()) - results = make([]*txTraceResult, len(txs)) + txs = block.Transactions() + blockHash = block.Hash() + is158 = api.backend.ChainConfig().IsEIP158(block.Number()) + blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) + signer = types.MakeSigner(api.backend.ChainConfig(), block.Number()) + results = make([]*txTraceResult, len(txs)) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxUpgraded(block.Number()) ) for i, tx := range txs { // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -698,10 +701,11 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat pend.Add(1) go func() { defer pend.Done() + isMetaTxUpgraded := api.backend.ChainConfig().IsMetaTxUpgraded(block.Number()) // Fetch and execute the next transaction trace tasks for task := range jobs { blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) - msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee(), block.NumberU64()) + msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee(), isMetaTxUpgraded) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -733,7 +737,7 @@ txloop: } // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), api.backend.ChainConfig().IsMetaTxUpgraded(block.Number())) statedb.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { @@ -810,10 +814,11 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Note: This copies the config, to not screw up the main config chainConfig, canon = overrideConfig(chainConfig, config.Overrides) } + isMetaTxUpgraded := chainConfig.IsMetaTxUpgraded(block.Number()) for i, tx := range block.Transactions() { // Prepare the transaction for un-traced execution var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) + msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) txContext = core.NewEVMTxContext(msg) vmConf vm.Config dump *os.File diff --git a/les/state_accessor.go b/les/state_accessor.go index 899f241eb2..e5d970c8a6 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -58,9 +58,10 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. } // Recompute transactions up to the target index. signer := types.MakeSigner(leth.blockchain.Config(), block.Number()) + isMetaTxUpgraded := leth.chainConfig.IsMetaTxUpgraded(block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), block.NumberU64()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil, leth.blockchain.Config(), statedb) statedb.SetTxContext(tx.Hash(), idx) diff --git a/light/txpool.go b/light/txpool.go index e8594ef104..5b3470611d 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -379,7 +379,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error return txpool.ErrNegativeValue } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, header.Number.Uint64()) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.config.IsMetaTxUpgraded(header.Number)) if err != nil { return err } diff --git a/params/config.go b/params/config.go index d753381307..9f0a10b07c 100644 --- a/params/config.go +++ b/params/config.go @@ -94,6 +94,7 @@ var ( TerminalTotalDifficultyPassed: true, ShanghaiTime: newUint64(1681338455), Ethash: new(EthashConfig), + MetaTxUpgradeBlock: big.NewInt(100), // 这里 } // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. @@ -460,6 +461,10 @@ type ChainConfig struct { // Mantle upgrade configs BaseFeeTime *uint64 `json:"baseFeeTime,omitempty"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) BVMETHMintUpgradeTime *uint64 `json:"bvmETHMintUpgradeTime,omitempty"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) + + // MetaTx upgrade config + MetaTxUpgradeBlock *big.Int `json:"metaTxUpgradeBlock,omitempty"` // MetaTxUpgradeBlock switch block ( nil = no fork, 0 = already forked) + // Fork scheduling was switched from blocks to timestamps here ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) @@ -682,6 +687,11 @@ func (c *ChainConfig) IsMantleBVMETHMintUpgrade(time uint64) bool { return isTimestampForked(c.BVMETHMintUpgradeTime, time) } +// IsMetaTxUpgraded returns whether time is either equal to the MetaTx fork time or greater. +func (c *ChainConfig) IsMetaTxUpgraded(num *big.Int) bool { + return isMetaTxForked(c.MetaTxUpgradeBlock, num) +} + // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool { return isBlockForked(c.ArrowGlacierBlock, num) @@ -935,6 +945,13 @@ func isBlockForked(s, head *big.Int) bool { return s.Cmp(head) <= 0 } +func isMetaTxForked(s, head *big.Int) bool { + if s == nil || head == nil { + return false + } + return s.Cmp(head) <= 0 +} + func configBlockEqual(x, y *big.Int) bool { if x == nil { return y == nil @@ -1053,6 +1070,7 @@ type Rules struct { IsMerge, IsShanghai, isCancun, isPrague bool IsMantleBaseFee, IsMantleBVMETHMintUpgrade bool IsOptimismBedrock, IsOptimismRegolith bool + IsMetaTxV2 bool } // Rules ensures c's ChainID is not nil. @@ -1079,6 +1097,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsShanghai: c.IsShanghai(timestamp), isCancun: c.IsCancun(timestamp), isPrague: c.IsPrague(timestamp), + IsMetaTxV2: c.IsMetaTxUpgraded(num), // Optimism IsOptimismBedrock: c.IsOptimismBedrock(num), IsOptimismRegolith: c.IsOptimismRegolith(timestamp), From 23a74e2430ca6b760b0857a380c31c0c39808d25 Mon Sep 17 00:00:00 2001 From: wwq Date: Sun, 4 Feb 2024 10:16:16 +0800 Subject: [PATCH 06/13] set metatx upgrade blkNum 2744121 --- params/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/config.go b/params/config.go index 9f0a10b07c..c20562e829 100644 --- a/params/config.go +++ b/params/config.go @@ -94,7 +94,7 @@ var ( TerminalTotalDifficultyPassed: true, ShanghaiTime: newUint64(1681338455), Ethash: new(EthashConfig), - MetaTxUpgradeBlock: big.NewInt(100), // 这里 + MetaTxUpgradeBlock: big.NewInt(2744121), } // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. From 020aff671c158ec59bd101048eac68e026148078 Mon Sep 17 00:00:00 2001 From: wwq Date: Sun, 4 Feb 2024 16:35:08 +0800 Subject: [PATCH 07/13] update func name IsMetaTxUpgraded to IsMetaTxV2 --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/state_prefetcher.go | 2 +- core/state_processor.go | 4 +- core/txpool/txpool.go | 4 +- core/types/meta_transaction.go | 116 -------------------------- eth/state_accessor.go | 2 +- eth/tracers/api.go | 12 +-- les/state_accessor.go | 2 +- light/txpool.go | 2 +- params/config.go | 7 +- 10 files changed, 19 insertions(+), 134 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 27c1ffb923..665432406e 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -163,7 +163,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } for i, tx := range txs { - msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, chainConfig.IsMetaTxUpgraded(new(big.Int).SetUint64(pre.Env.Number))) + msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, chainConfig.IsMetaTxV2(new(big.Int).SetUint64(pre.Env.Number))) if err != nil { log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 49bcdf21db..9166f7f4c1 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -63,7 +63,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c return } // Convert the transaction into an executable message and pre-cache its sender - msg, err := TransactionToMessage(tx, signer, header.BaseFee, evm.ChainConfig().IsMetaTxUpgraded(header.Number)) + msg, err := TransactionToMessage(tx, signer, header.BaseFee, evm.ChainConfig().IsMetaTxV2(header.Number)) if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index 0e941ebcc3..cadbbd5fb2 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -72,7 +72,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } blockContext := NewEVMBlockContext(header, p.bc, nil, p.config, statedb) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) - isMetaTxUpgraded := vmenv.ChainConfig().IsMetaTxUpgraded(header.Number) + isMetaTxUpgraded := vmenv.ChainConfig().IsMetaTxV2(header.Number) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, isMetaTxUpgraded) @@ -172,7 +172,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, config.IsMetaTxUpgraded(header.Number)) + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, config.IsMetaTxV2(header.Number)) if err != nil { return nil, err } diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index be6257afdd..3ae6142ddf 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -689,7 +689,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { cost = cost.Add(cost, l1Cost) } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxUpgraded(pool.chain.CurrentBlock().Number)) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Number)) if err != nil { return err } @@ -1480,7 +1480,7 @@ func (pool *TxPool) validateMetaTxList(list *list) ([]*types.Transaction, *big.I var invalidMetaTxs []*types.Transaction sponsorCostSum := big.NewInt(0) for _, tx := range list.txs.Flatten() { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxUpgraded(pool.chain.CurrentBlock().Number)) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Number)) if err != nil { invalidMetaTxs = append(invalidMetaTxs, tx) continue diff --git a/core/types/meta_transaction.go b/core/types/meta_transaction.go index b7bcf004b7..5511256f72 100644 --- a/core/types/meta_transaction.go +++ b/core/types/meta_transaction.go @@ -39,20 +39,6 @@ type MetaTxParams struct { S *big.Int } -//type MetaTxParamsV2 struct { -// ExpireHeight uint64 -// SponsorPercent uint64 -// Payload []byte -// From common.Address -// -// // In tx simulation, Signature will be empty, user can specify GasFeeSponsor to sponsor gas fee -// GasFeeSponsor common.Address -// // Signature values -// V *big.Int -// R *big.Int -// S *big.Int -//} - type MetaTxParamsCache struct { metaTxParams *MetaTxParams } @@ -215,108 +201,6 @@ func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, isMetaTx return nil } -//func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, isMetaTxUpgraded bool) error { -// var ( -// gasFeeSponsorSigner common.Address -// updateHeight, currentHeight uint64 -// ) -// if args != nil { -// if len(args) == 2 { -// updateHeight, currentHeight = args[0], args[1] -// } else if len(args) > 2 { -// return errors.New("wrong args number") -// } -// } -// -// txSender, err := Sender(LatestSignerForChainID(tx.ChainId()), tx) -// if err != nil { -// return err -// } -// -// if args == nil || len(args) < 2 { -// metaTxSignData := &MetaTxSignDataV2{ -// From: txSender, -// ChainID: tx.ChainId(), -// Nonce: tx.Nonce(), -// GasTipCap: tx.GasTipCap(), -// GasFeeCap: tx.GasFeeCap(), -// Gas: tx.Gas(), -// To: tx.To(), -// Value: tx.Value(), -// Data: metaTxParams.Payload, -// AccessList: tx.AccessList(), -// ExpireHeight: metaTxParams.ExpireHeight, -// SponsorPercent: metaTxParams.SponsorPercent, -// } -// -// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) -// if err != nil { -// metaTxSignData := &MetaTxSignData{ -// ChainID: tx.ChainId(), -// Nonce: tx.Nonce(), -// GasTipCap: tx.GasTipCap(), -// GasFeeCap: tx.GasFeeCap(), -// Gas: tx.Gas(), -// To: tx.To(), -// Value: tx.Value(), -// Data: metaTxParams.Payload, -// AccessList: tx.AccessList(), -// ExpireHeight: metaTxParams.ExpireHeight, -// SponsorPercent: metaTxParams.SponsorPercent, -// } -// -// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) -// if err != nil { -// return ErrInvalidGasFeeSponsorSig -// } -// } -// } else if currentHeight >= updateHeight { -// metaTxSignData := &MetaTxSignDataV2{ -// From: txSender, -// ChainID: tx.ChainId(), -// Nonce: tx.Nonce(), -// GasTipCap: tx.GasTipCap(), -// GasFeeCap: tx.GasFeeCap(), -// Gas: tx.Gas(), -// To: tx.To(), -// Value: tx.Value(), -// Data: metaTxParams.Payload, -// AccessList: tx.AccessList(), -// ExpireHeight: metaTxParams.ExpireHeight, -// SponsorPercent: metaTxParams.SponsorPercent, -// } -// -// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) -// if err != nil { -// return ErrInvalidGasFeeSponsorSig -// } -// } else { -// metaTxSignData := &MetaTxSignData{ -// ChainID: tx.ChainId(), -// Nonce: tx.Nonce(), -// GasTipCap: tx.GasTipCap(), -// GasFeeCap: tx.GasFeeCap(), -// Gas: tx.Gas(), -// To: tx.To(), -// Value: tx.Value(), -// Data: metaTxParams.Payload, -// AccessList: tx.AccessList(), -// ExpireHeight: metaTxParams.ExpireHeight, -// SponsorPercent: metaTxParams.SponsorPercent, -// } -// -// gasFeeSponsorSigner, err = recoverPlain(metaTxSignData.Hash(), metaTxParams.R, metaTxParams.S, metaTxParams.V, true) -// if err != nil { -// return ErrInvalidGasFeeSponsorSig -// } -// } -// -// if gasFeeSponsorSigner != metaTxParams.GasFeeSponsor { -// return ErrGasFeeSponsorMismatch -// } -// return nil -//} - func (metaTxSignData *MetaTxSignData) Hash() common.Hash { return rlpHash(metaTxSignData) } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 3daef74304..7c11972467 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -210,7 +210,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, } // Recompute transactions up to the target index. signer := types.MakeSigner(eth.blockchain.Config(), block.Number()) - isMetaTxUpgraded := eth.blockchain.Config().IsMetaTxUpgraded(block.Number()) + isMetaTxUpgraded := eth.blockchain.Config().IsMetaTxV2(block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 5faa5788da..947eada2b0 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -291,7 +291,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed var ( signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number()) blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxUpgraded(task.block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(task.block.Number()) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { @@ -579,7 +579,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config chainConfig = api.backend.ChainConfig() vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxUpgraded(block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Number()) ) for i, tx := range block.Transactions() { if err := ctx.Err(); err != nil { @@ -657,7 +657,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number()) results = make([]*txTraceResult, len(txs)) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxUpgraded(block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Number()) ) for i, tx := range txs { // Generate the next state snapshot fast without tracing @@ -701,7 +701,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat pend.Add(1) go func() { defer pend.Done() - isMetaTxUpgraded := api.backend.ChainConfig().IsMetaTxUpgraded(block.Number()) + isMetaTxUpgraded := api.backend.ChainConfig().IsMetaTxV2(block.Number()) // Fetch and execute the next transaction trace tasks for task := range jobs { blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) @@ -737,7 +737,7 @@ txloop: } // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), api.backend.ChainConfig().IsMetaTxUpgraded(block.Number())) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), api.backend.ChainConfig().IsMetaTxV2(block.Number())) statedb.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { @@ -814,7 +814,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Note: This copies the config, to not screw up the main config chainConfig, canon = overrideConfig(chainConfig, config.Overrides) } - isMetaTxUpgraded := chainConfig.IsMetaTxUpgraded(block.Number()) + isMetaTxUpgraded := chainConfig.IsMetaTxV2(block.Number()) for i, tx := range block.Transactions() { // Prepare the transaction for un-traced execution var ( diff --git a/les/state_accessor.go b/les/state_accessor.go index e5d970c8a6..24a6527ce7 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -58,7 +58,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. } // Recompute transactions up to the target index. signer := types.MakeSigner(leth.blockchain.Config(), block.Number()) - isMetaTxUpgraded := leth.chainConfig.IsMetaTxUpgraded(block.Number()) + isMetaTxUpgraded := leth.chainConfig.IsMetaTxV2(block.Number()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) diff --git a/light/txpool.go b/light/txpool.go index 5b3470611d..dbe53b720b 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -379,7 +379,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error return txpool.ErrNegativeValue } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.config.IsMetaTxUpgraded(header.Number)) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.config.IsMetaTxV2(header.Number)) if err != nil { return err } diff --git a/params/config.go b/params/config.go index c20562e829..8564a03dc6 100644 --- a/params/config.go +++ b/params/config.go @@ -139,6 +139,7 @@ var ( MergeNetsplitBlock: big.NewInt(1735371), ShanghaiTime: newUint64(1677557088), Ethash: new(EthashConfig), + MetaTxUpgradeBlock: big.NewInt(2744121), } // SepoliaTrustedCheckpoint contains the light client trusted checkpoint for the Sepolia test network. @@ -687,8 +688,8 @@ func (c *ChainConfig) IsMantleBVMETHMintUpgrade(time uint64) bool { return isTimestampForked(c.BVMETHMintUpgradeTime, time) } -// IsMetaTxUpgraded returns whether time is either equal to the MetaTx fork time or greater. -func (c *ChainConfig) IsMetaTxUpgraded(num *big.Int) bool { +// IsMetaTxV2 returns whether time is either equal to the MetaTx fork time or greater. +func (c *ChainConfig) IsMetaTxV2(num *big.Int) bool { return isMetaTxForked(c.MetaTxUpgradeBlock, num) } @@ -1097,7 +1098,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsShanghai: c.IsShanghai(timestamp), isCancun: c.IsCancun(timestamp), isPrague: c.IsPrague(timestamp), - IsMetaTxV2: c.IsMetaTxUpgraded(num), + IsMetaTxV2: c.IsMetaTxV2(num), // Optimism IsOptimismBedrock: c.IsOptimismBedrock(num), IsOptimismRegolith: c.IsOptimismRegolith(timestamp), From eb6b730cff7e65b9890dc6ad321252e8ea870f78 Mon Sep 17 00:00:00 2001 From: wwq Date: Sun, 4 Feb 2024 19:52:42 +0800 Subject: [PATCH 08/13] metatxV2 upgrade by timestamp --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/genesis.go | 2 +- core/mantle_upgrade.go | 14 +++++++------- core/state_prefetcher.go | 2 +- core/state_processor.go | 4 ++-- core/txpool/txpool.go | 4 ++-- eth/state_accessor.go | 2 +- eth/tracers/api.go | 12 ++++++------ les/state_accessor.go | 2 +- light/txpool.go | 2 +- params/config.go | 18 +++++++++--------- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 665432406e..75528bd6ca 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -163,7 +163,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } for i, tx := range txs { - msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, chainConfig.IsMetaTxV2(new(big.Int).SetUint64(pre.Env.Number))) + msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, chainConfig.IsMetaTxV2(pre.Env.Timestamp)) if err != nil { log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/core/genesis.go b/core/genesis.go index 4b4b1820d6..265cbb130a 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -311,7 +311,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen if mantleUpgradeChainConfig != nil { config.BaseFeeTime = mantleUpgradeChainConfig.BaseFeeTime config.BVMETHMintUpgradeTime = mantleUpgradeChainConfig.BVMETHMintUpgradeTime - config.MetaTxUpgradeBlock = mantleUpgradeChainConfig.MetaTxUpgradeBlock + config.MetaTxUpgradeTime = mantleUpgradeChainConfig.MetaTxUpgradeTime } if overrides != nil && overrides.OverrideShanghai != nil { diff --git a/core/mantle_upgrade.go b/core/mantle_upgrade.go index bfb99d8126..20d5c47b58 100644 --- a/core/mantle_upgrade.go +++ b/core/mantle_upgrade.go @@ -11,34 +11,34 @@ var ( ChainID: params.MantleMainnetChainId, BaseFeeTime: u64Ptr(0), BVMETHMintUpgradeTime: u64Ptr(0), - MetaTxUpgradeBlock: u64Ptr(0), + MetaTxUpgradeTime: u64Ptr(0), } MantleSepoliaUpgradeConfig = MantleUpgradeChainConfig{ ChainID: params.MantleSepoliaChainId, BaseFeeTime: u64Ptr(1_704_891_600), BVMETHMintUpgradeTime: nil, //TODO set upgrade timestamp - MetaTxUpgradeBlock: nil, + MetaTxUpgradeTime: nil, } MantleLocalUpgradeConfig = MantleUpgradeChainConfig{ ChainID: params.MantleLocalChainId, BaseFeeTime: u64Ptr(0), BVMETHMintUpgradeTime: u64Ptr(0), - MetaTxUpgradeBlock: u64Ptr(0), + MetaTxUpgradeTime: u64Ptr(0), } MantleDefaultUpgradeConfig = MantleUpgradeChainConfig{ BaseFeeTime: u64Ptr(0), BVMETHMintUpgradeTime: u64Ptr(0), - MetaTxUpgradeBlock: u64Ptr(0), + MetaTxUpgradeTime: u64Ptr(0), } ) type MantleUpgradeChainConfig struct { ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection - BaseFeeTime *uint64 `json:"BaseFeeTime"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) - BVMETHMintUpgradeTime *uint64 `json:"BVMETHMintUpgradeTime"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) - MetaTxUpgradeBlock *big.Int `json:"metaTxUpgradeBlock"` // MetaTxUpgradeBlock identifies the current block height is using metaTx with MetaTxSignDataV2 + BaseFeeTime *uint64 `json:"BaseFeeTime"` // Mantle BaseFee switch time (nil = no fork, 0 = already on mantle baseFee) + BVMETHMintUpgradeTime *uint64 `json:"BVMETHMintUpgradeTime"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) + MetaTxUpgradeTime *uint64 `json:"metaTxUpgradeTime"` // MetaTxUpgradeBlock identifies the current block height is using metaTx with MetaTxSignDataV2 } func GetUpgradeConfigForMantle(chainID *big.Int) *MantleUpgradeChainConfig { diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 9166f7f4c1..fa11d244ba 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -63,7 +63,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c return } // Convert the transaction into an executable message and pre-cache its sender - msg, err := TransactionToMessage(tx, signer, header.BaseFee, evm.ChainConfig().IsMetaTxV2(header.Number)) + msg, err := TransactionToMessage(tx, signer, header.BaseFee, evm.ChainConfig().IsMetaTxV2(header.Time)) if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index cadbbd5fb2..a77dd17fbe 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -72,7 +72,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } blockContext := NewEVMBlockContext(header, p.bc, nil, p.config, statedb) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) - isMetaTxUpgraded := vmenv.ChainConfig().IsMetaTxV2(header.Number) + isMetaTxUpgraded := vmenv.ChainConfig().IsMetaTxV2(header.Time) // Iterate over and process the individual transactions for i, tx := range block.Transactions() { msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, isMetaTxUpgraded) @@ -172,7 +172,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, config.IsMetaTxV2(header.Number)) + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, config.IsMetaTxV2(header.Time)) if err != nil { return nil, err } diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 3ae6142ddf..a1c10fcb0a 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -689,7 +689,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { cost = cost.Add(cost, l1Cost) } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Number)) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Time)) if err != nil { return err } @@ -1480,7 +1480,7 @@ func (pool *TxPool) validateMetaTxList(list *list) ([]*types.Transaction, *big.I var invalidMetaTxs []*types.Transaction sponsorCostSum := big.NewInt(0) for _, tx := range list.txs.Flatten() { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Number)) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Time)) if err != nil { invalidMetaTxs = append(invalidMetaTxs, tx) continue diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 7c11972467..e796a30c57 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -210,7 +210,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, } // Recompute transactions up to the target index. signer := types.MakeSigner(eth.blockchain.Config(), block.Number()) - isMetaTxUpgraded := eth.blockchain.Config().IsMetaTxV2(block.Number()) + isMetaTxUpgraded := eth.blockchain.Config().IsMetaTxV2(block.Time()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 947eada2b0..9c144bc6f2 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -291,7 +291,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed var ( signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number()) blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(task.block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(task.block.Time()) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { @@ -579,7 +579,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config chainConfig = api.backend.ChainConfig() vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Time()) ) for i, tx := range block.Transactions() { if err := ctx.Err(); err != nil { @@ -657,7 +657,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) signer = types.MakeSigner(api.backend.ChainConfig(), block.Number()) results = make([]*txTraceResult, len(txs)) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Number()) + isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Time()) ) for i, tx := range txs { // Generate the next state snapshot fast without tracing @@ -701,7 +701,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat pend.Add(1) go func() { defer pend.Done() - isMetaTxUpgraded := api.backend.ChainConfig().IsMetaTxV2(block.Number()) + isMetaTxUpgraded := api.backend.ChainConfig().IsMetaTxV2(block.Time()) // Fetch and execute the next transaction trace tasks for task := range jobs { blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) @@ -737,7 +737,7 @@ txloop: } // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), api.backend.ChainConfig().IsMetaTxV2(block.Number())) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), api.backend.ChainConfig().IsMetaTxV2(block.Time())) statedb.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { @@ -814,7 +814,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Note: This copies the config, to not screw up the main config chainConfig, canon = overrideConfig(chainConfig, config.Overrides) } - isMetaTxUpgraded := chainConfig.IsMetaTxV2(block.Number()) + isMetaTxUpgraded := chainConfig.IsMetaTxV2(block.Time()) for i, tx := range block.Transactions() { // Prepare the transaction for un-traced execution var ( diff --git a/les/state_accessor.go b/les/state_accessor.go index 24a6527ce7..9307a799c3 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -58,7 +58,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. } // Recompute transactions up to the target index. signer := types.MakeSigner(leth.blockchain.Config(), block.Number()) - isMetaTxUpgraded := leth.chainConfig.IsMetaTxV2(block.Number()) + isMetaTxUpgraded := leth.chainConfig.IsMetaTxV2(block.Time()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) diff --git a/light/txpool.go b/light/txpool.go index dbe53b720b..5a122089d0 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -379,7 +379,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error return txpool.ErrNegativeValue } - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.config.IsMetaTxV2(header.Number)) + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, pool.config.IsMetaTxV2(header.Time)) if err != nil { return err } diff --git a/params/config.go b/params/config.go index 8564a03dc6..50605b43ed 100644 --- a/params/config.go +++ b/params/config.go @@ -94,7 +94,7 @@ var ( TerminalTotalDifficultyPassed: true, ShanghaiTime: newUint64(1681338455), Ethash: new(EthashConfig), - MetaTxUpgradeBlock: big.NewInt(2744121), + MetaTxUpgradeTime: newUint64(0), //newUint64(1707152400), } // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. @@ -139,7 +139,7 @@ var ( MergeNetsplitBlock: big.NewInt(1735371), ShanghaiTime: newUint64(1677557088), Ethash: new(EthashConfig), - MetaTxUpgradeBlock: big.NewInt(2744121), + MetaTxUpgradeTime: newUint64(0), // newUint64(1707152400), } // SepoliaTrustedCheckpoint contains the light client trusted checkpoint for the Sepolia test network. @@ -464,7 +464,7 @@ type ChainConfig struct { BVMETHMintUpgradeTime *uint64 `json:"bvmETHMintUpgradeTime,omitempty"` // BVM_ETH mint upgrade switch time (nil = no fork, 0 = already on) // MetaTx upgrade config - MetaTxUpgradeBlock *big.Int `json:"metaTxUpgradeBlock,omitempty"` // MetaTxUpgradeBlock switch block ( nil = no fork, 0 = already forked) + MetaTxUpgradeTime *uint64 `json:"metaTxUpgradeTime,omitempty"` // MetaTxUpgradeTime switch time ( nil = no fork, 0 = already forked) // Fork scheduling was switched from blocks to timestamps here @@ -689,8 +689,8 @@ func (c *ChainConfig) IsMantleBVMETHMintUpgrade(time uint64) bool { } // IsMetaTxV2 returns whether time is either equal to the MetaTx fork time or greater. -func (c *ChainConfig) IsMetaTxV2(num *big.Int) bool { - return isMetaTxForked(c.MetaTxUpgradeBlock, num) +func (c *ChainConfig) IsMetaTxV2(time uint64) bool { + return isMetaTxForked(c.MetaTxUpgradeTime, time) } // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. @@ -946,11 +946,11 @@ func isBlockForked(s, head *big.Int) bool { return s.Cmp(head) <= 0 } -func isMetaTxForked(s, head *big.Int) bool { - if s == nil || head == nil { +func isMetaTxForked(s *uint64, head uint64) bool { + if s == nil { return false } - return s.Cmp(head) <= 0 + return *s <= head } func configBlockEqual(x, y *big.Int) bool { @@ -1098,7 +1098,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsShanghai: c.IsShanghai(timestamp), isCancun: c.IsCancun(timestamp), isPrague: c.IsPrague(timestamp), - IsMetaTxV2: c.IsMetaTxV2(num), + IsMetaTxV2: c.IsMetaTxV2(timestamp), // Optimism IsOptimismBedrock: c.IsOptimismBedrock(num), IsOptimismRegolith: c.IsOptimismRegolith(timestamp), From 15367979db01b716b5ac1e6e7685a0739d8dbdf0 Mon Sep 17 00:00:00 2001 From: wwq Date: Mon, 5 Feb 2024 14:06:18 +0800 Subject: [PATCH 09/13] add rules into TransactionToMessage params, set metaTxUpgradeTime nil --- cmd/evm/internal/t8ntool/execution.go | 3 +- core/mantle_upgrade.go | 2 +- core/state_prefetcher.go | 4 +- core/state_processor.go | 8 +- core/state_transition.go | 8 +- core/types/meta_transaction_test.go | 135 +++++++++++++++++- eth/state_accessor.go | 5 +- eth/tracers/api.go | 39 ++--- eth/tracers/api_test.go | 2 +- .../internal/tracetest/calltrace_test.go | 6 +- .../internal/tracetest/flat_calltrace_test.go | 4 +- .../internal/tracetest/prestate_test.go | 3 +- eth/tracers/tracers_test.go | 2 +- les/state_accessor.go | 4 +- 14 files changed, 182 insertions(+), 43 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 75528bd6ca..78a067cfb0 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -162,8 +162,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, misc.ApplyDAOHardFork(statedb) } + rules := chainConfig.Rules(new(big.Int).SetUint64(pre.Env.Number), false, pre.Env.Timestamp) for i, tx := range txs { - msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, chainConfig.IsMetaTxV2(pre.Env.Timestamp)) + msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, &rules) if err != nil { log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/core/mantle_upgrade.go b/core/mantle_upgrade.go index 20d5c47b58..ce033805d0 100644 --- a/core/mantle_upgrade.go +++ b/core/mantle_upgrade.go @@ -18,7 +18,7 @@ var ( ChainID: params.MantleSepoliaChainId, BaseFeeTime: u64Ptr(1_704_891_600), BVMETHMintUpgradeTime: nil, //TODO set upgrade timestamp - MetaTxUpgradeTime: nil, + MetaTxUpgradeTime: nil, //TODO set upgrade timestamp } MantleLocalUpgradeConfig = MantleUpgradeChainConfig{ ChainID: params.MantleLocalChainId, diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index fa11d244ba..0141049773 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -57,13 +57,15 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c ) // Iterate over and process the individual transactions byzantium := p.config.IsByzantium(block.Number()) + rules := evm.ChainConfig().Rules(block.Number(), false, header.Time) + for i, tx := range block.Transactions() { // If block precaching was interrupted, abort if interrupt != nil && atomic.LoadUint32(interrupt) == 1 { return } // Convert the transaction into an executable message and pre-cache its sender - msg, err := TransactionToMessage(tx, signer, header.BaseFee, evm.ChainConfig().IsMetaTxV2(header.Time)) + msg, err := TransactionToMessage(tx, signer, header.BaseFee, &rules) if err != nil { return // Also invalid block, bail out } diff --git a/core/state_processor.go b/core/state_processor.go index a77dd17fbe..a8a0543202 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -72,10 +72,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } blockContext := NewEVMBlockContext(header, p.bc, nil, p.config, statedb) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) - isMetaTxUpgraded := vmenv.ChainConfig().IsMetaTxV2(header.Time) + rules := vmenv.ChainConfig().Rules(header.Number, false, header.Time) + // Iterate over and process the individual transactions for i, tx := range block.Transactions() { - msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, isMetaTxUpgraded) + msg, err := TransactionToMessage(tx, types.MakeSigner(p.config, header.Number), header.BaseFee, &rules) if err != nil { return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } @@ -172,7 +173,8 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { - msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, config.IsMetaTxV2(header.Time)) + rules := config.Rules(header.Number, false, header.Time) + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee, &rules) if err != nil { return nil, err } diff --git a/core/state_transition.go b/core/state_transition.go index 94de728454..860f3c28b3 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -17,6 +17,7 @@ package core import ( + "errors" "fmt" "math" "math/big" @@ -170,8 +171,11 @@ type Message struct { } // TransactionToMessage converts a transaction into a Message. -func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int, isMetaTxUpgraded bool) (*Message, error) { - metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, isMetaTxUpgraded) +func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int, rules *params.Rules) (*Message, error) { + if rules == nil { + return nil, errors.New("param rules is nil pointer") + } + metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx, rules.IsMetaTxV2) if err != nil { return nil, err } diff --git a/core/types/meta_transaction_test.go b/core/types/meta_transaction_test.go index 84cd6b12bf..e6fc819334 100644 --- a/core/types/meta_transaction_test.go +++ b/core/types/meta_transaction_test.go @@ -101,6 +101,48 @@ func generateMetaTxDataWithMockSig(dynamicTx *DynamicFeeTx, expireHeight uint64, return append(MetaTxPrefix, metaTxDataBz...), nil } +func generateMetaTxDataV2(dynamicTx *DynamicFeeTx, expireHeight uint64, sponsorPercent uint64, + gasFeeSponsorAddr common.Address, privateKey *ecdsa.PrivateKey) ([]byte, error) { + from := crypto.PubkeyToAddress(userKey.PublicKey) + metaTxSignData := &MetaTxSignDataV2{ + From: from, + ChainID: dynamicTx.ChainID, + Nonce: dynamicTx.Nonce, + GasTipCap: dynamicTx.GasTipCap, + GasFeeCap: dynamicTx.GasFeeCap, + Gas: dynamicTx.Gas, + To: dynamicTx.To, + Value: dynamicTx.Value, + Data: dynamicTx.Data, + AccessList: dynamicTx.AccessList, + ExpireHeight: expireHeight, + SponsorPercent: sponsorPercent, + } + + sponsorSig, err := crypto.Sign(metaTxSignData.Hash().Bytes(), privateKey) + if err != nil { + return nil, err + } + + r, s, v := decodeSignature(sponsorSig) + + metaTxData := &MetaTxParams{ + ExpireHeight: expireHeight, + Payload: metaTxSignData.Data, + GasFeeSponsor: gasFeeSponsorAddr, + SponsorPercent: sponsorPercent, + R: r, + S: s, + V: v, + } + + metaTxDataBz, err := rlp.EncodeToBytes(metaTxData) + if err != nil { + return nil, err + } + + return append(MetaTxPrefix, metaTxDataBz...), nil +} func TestDecodeMetaTxParams(t *testing.T) { gasFeeSponsorPublicKey := gasFeeSponsorKey1.Public() pubKeyECDSA, _ := gasFeeSponsorPublicKey.(*ecdsa.PublicKey) @@ -190,7 +232,7 @@ func TestDecodeAndVerifyMetaTxParams(t *testing.T) { require.NoError(t, err) // test normal metaTx - metaTxParams, err := DecodeAndVerifyMetaTxParams(signedTx) + metaTxParams, err := DecodeAndVerifyMetaTxParams(signedTx, false) require.NoError(t, err) require.Equal(t, gasFeeSponsorAddr.String(), metaTxParams.GasFeeSponsor.String()) @@ -208,7 +250,7 @@ func TestDecodeAndVerifyMetaTxParams(t *testing.T) { signedTx, err = tx.WithSignature(signer, txSignature) require.NoError(t, err) - _, err = DecodeAndVerifyMetaTxParams(signedTx) + _, err = DecodeAndVerifyMetaTxParams(signedTx, false) require.Equal(t, err, ErrInvalidGasFeeSponsorSig) // Test ErrGasFeeSponsorMismatch @@ -223,7 +265,92 @@ func TestDecodeAndVerifyMetaTxParams(t *testing.T) { signedTx, err = tx.WithSignature(signer, txSignature) require.NoError(t, err) - _, err = DecodeAndVerifyMetaTxParams(signedTx) + _, err = DecodeAndVerifyMetaTxParams(signedTx, true) + require.Equal(t, err, ErrGasFeeSponsorMismatch) + + // Test ErrGasFeeSponsorMismatch + dynamicTx.Data = depositABICalldata + payload, err = generateMetaTxData(dynamicTx, expireHeight, 101, gasFeeSponsorAddr, gasFeeSponsorKey2) + require.NoError(t, err) + + dynamicTx.Data = payload + tx = NewTx(dynamicTx) + txSignature, err = crypto.Sign(signer.Hash(tx).Bytes(), userKey) + require.NoError(t, err) + signedTx, err = tx.WithSignature(signer, txSignature) + require.NoError(t, err) + + _, err = DecodeAndVerifyMetaTxParams(signedTx, false) + require.Equal(t, err, ErrInvalidSponsorPercent) +} + +func TestDecodeAndVerifyMetaTxParamsV2(t *testing.T) { + gasFeeSponsorPublicKey := gasFeeSponsorKey1.Public() + pubKeyECDSA, _ := gasFeeSponsorPublicKey.(*ecdsa.PublicKey) + gasFeeSponsorAddr := crypto.PubkeyToAddress(*pubKeyECDSA) + + chainId := big.NewInt(1) + depositABICalldata, _ := hexutil.Decode("0xd0e30db0") + to := common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") + expireHeight := uint64(20_000_010) + dynamicTx := &DynamicFeeTx{ + ChainID: chainId, + Nonce: 100, + GasTipCap: big.NewInt(1e9), + GasFeeCap: big.NewInt(1e15), + Gas: 4700000, + To: &to, + Value: big.NewInt(1e18), + Data: depositABICalldata, + AccessList: nil, + } + + payload, err := generateMetaTxDataV2(dynamicTx, expireHeight, 50, gasFeeSponsorAddr, gasFeeSponsorKey1) + require.NoError(t, err) + + dynamicTx.Data = payload + tx := NewTx(dynamicTx) + signer := LatestSignerForChainID(chainId) + txSignature, err := crypto.Sign(signer.Hash(tx).Bytes(), userKey) + require.NoError(t, err) + signedTx, err := tx.WithSignature(signer, txSignature) + require.NoError(t, err) + + // test normal metaTx + metaTxParams, err := DecodeAndVerifyMetaTxParams(signedTx, true) + require.NoError(t, err) + + require.Equal(t, gasFeeSponsorAddr.String(), metaTxParams.GasFeeSponsor.String()) + require.Equal(t, hexutil.Encode(depositABICalldata), hexutil.Encode(metaTxParams.Payload)) + + // Test ErrInvalidGasFeeSponsorSig + dynamicTx.Data = depositABICalldata + payload, err = generateMetaTxDataWithMockSig(dynamicTx, expireHeight, 100, gasFeeSponsorAddr, gasFeeSponsorKey1) + require.NoError(t, err) + + dynamicTx.Data = payload + tx = NewTx(dynamicTx) + txSignature, err = crypto.Sign(signer.Hash(tx).Bytes(), userKey) + require.NoError(t, err) + signedTx, err = tx.WithSignature(signer, txSignature) + require.NoError(t, err) + + _, err = DecodeAndVerifyMetaTxParams(signedTx, true) + require.Equal(t, err, ErrInvalidGasFeeSponsorSig) + + // Test ErrGasFeeSponsorMismatch + dynamicTx.Data = depositABICalldata + payload, err = generateMetaTxDataV2(dynamicTx, expireHeight, 80, gasFeeSponsorAddr, gasFeeSponsorKey2) + require.NoError(t, err) + + dynamicTx.Data = payload + tx = NewTx(dynamicTx) + txSignature, err = crypto.Sign(signer.Hash(tx).Bytes(), userKey) + require.NoError(t, err) + signedTx, err = tx.WithSignature(signer, txSignature) + require.NoError(t, err) + + _, err = DecodeAndVerifyMetaTxParams(signedTx, true) require.Equal(t, err, ErrGasFeeSponsorMismatch) // Test ErrGasFeeSponsorMismatch @@ -238,6 +365,6 @@ func TestDecodeAndVerifyMetaTxParams(t *testing.T) { signedTx, err = tx.WithSignature(signer, txSignature) require.NoError(t, err) - _, err = DecodeAndVerifyMetaTxParams(signedTx) + _, err = DecodeAndVerifyMetaTxParams(signedTx, false) require.Equal(t, err, ErrInvalidSponsorPercent) } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index e796a30c57..d5eff61744 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -210,10 +210,11 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, } // Recompute transactions up to the target index. signer := types.MakeSigner(eth.blockchain.Config(), block.Number()) - isMetaTxUpgraded := eth.blockchain.Config().IsMetaTxV2(block.Time()) + rules := eth.blockchain.Config().Rules(block.Number(), false, block.Time()) + for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), &rules) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil, eth.blockchain.Config(), statedb) if idx == txIndex { diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 9c144bc6f2..28c4c2ca5c 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -289,13 +289,13 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed // Fetch and execute the block trace taskCh for task := range taskCh { var ( - signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number()) - blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(task.block.Time()) + signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number()) + blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) + rules = api.backend.ChainConfig().Rules(task.block.Number(), false, task.block.Time()) ) // Trace all the transactions contained within for i, tx := range task.block.Transactions() { - msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), isMetaTxUpgraded) + msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), &rules) txctx := &Context{ BlockHash: task.block.Hash(), BlockNumber: task.block.Number(), @@ -579,14 +579,14 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config chainConfig = api.backend.ChainConfig() vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, chainConfig, statedb) deleteEmptyObjects = chainConfig.IsEIP158(block.Number()) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Time()) + rules = api.backend.ChainConfig().Rules(block.Number(), false, block.Time()) ) for i, tx := range block.Transactions() { if err := ctx.Err(); err != nil { return nil, err } var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) + msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), &rules) txContext = core.NewEVMTxContext(msg) vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{}) ) @@ -651,17 +651,17 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac } // Native tracers have low overhead var ( - txs = block.Transactions() - blockHash = block.Hash() - is158 = api.backend.ChainConfig().IsEIP158(block.Number()) - blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) - signer = types.MakeSigner(api.backend.ChainConfig(), block.Number()) - results = make([]*txTraceResult, len(txs)) - isMetaTxUpgraded = api.backend.ChainConfig().IsMetaTxV2(block.Time()) + txs = block.Transactions() + blockHash = block.Hash() + is158 = api.backend.ChainConfig().IsEIP158(block.Number()) + blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) + signer = types.MakeSigner(api.backend.ChainConfig(), block.Number()) + results = make([]*txTraceResult, len(txs)) + rules = api.backend.ChainConfig().Rules(block.Number(), false, block.Time()) ) for i, tx := range txs { // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), &rules) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -701,11 +701,11 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat pend.Add(1) go func() { defer pend.Done() - isMetaTxUpgraded := api.backend.ChainConfig().IsMetaTxV2(block.Time()) + rules := api.backend.ChainConfig().Rules(block.Number(), false, block.Time()) // Fetch and execute the next transaction trace tasks for task := range jobs { blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), task.statedb) - msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee(), isMetaTxUpgraded) + msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee(), &rules) txctx := &Context{ BlockHash: blockHash, BlockNumber: block.Number(), @@ -725,6 +725,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat // Feed the transactions into the tracers and return var failed error blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil, api.backend.ChainConfig(), statedb) + rules := api.backend.ChainConfig().Rules(block.Number(), false, block.Time()) txloop: for i, tx := range txs { // Send the trace task over for execution @@ -737,7 +738,7 @@ txloop: } // Generate the next state snapshot fast without tracing - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), api.backend.ChainConfig().IsMetaTxV2(block.Time())) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), &rules) statedb.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { @@ -814,11 +815,11 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Note: This copies the config, to not screw up the main config chainConfig, canon = overrideConfig(chainConfig, config.Overrides) } - isMetaTxUpgraded := chainConfig.IsMetaTxV2(block.Time()) + rules := chainConfig.Rules(block.Number(), false, block.Time()) for i, tx := range block.Transactions() { // Prepare the transaction for un-traced execution var ( - msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) + msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), &rules) txContext = core.NewEVMTxContext(msg) vmConf vm.Config dump *os.File diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index a2d00f3edc..de8b60ca6c 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -253,7 +253,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block // Recompute transactions up to the target index. signer := types.MakeSigner(b.chainConfig, block.Number()) for idx, tx := range block.Transactions() { - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), ¶ms.Rules{}) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), b.chain, nil, b.chainConfig, statedb) if idx == txIndex { diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 62182e3a82..8c32b16cbe 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -145,7 +145,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { t.Fatalf("failed to create call tracer: %v", err) } evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) - msg, err := core.TransactionToMessage(tx, signer, nil) + msg, err := core.TransactionToMessage(tx, signer, nil, ¶ms.Rules{}) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } @@ -220,7 +220,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { b.Fatalf("failed to parse testcase input: %v", err) } signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number))) - msg, err := core.TransactionToMessage(tx, signer, nil) + msg, err := core.TransactionToMessage(tx, signer, nil, ¶ms.Rules{}) if err != nil { b.Fatalf("failed to prepare transaction for tracing: %v", err) } @@ -314,7 +314,7 @@ func TestZeroValueToNotExitCall(t *testing.T) { t.Fatalf("failed to create call tracer: %v", err) } evm := vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer}) - msg, err := core.TransactionToMessage(tx, signer, nil) + msg, err := core.TransactionToMessage(tx, signer, nil, ¶ms.Rules{}) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go index 8cd5a42bc0..25cc0a2d13 100644 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests" @@ -108,8 +109,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string return fmt.Errorf("failed to create call tracer: %v", err) } evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) - - msg, err := core.TransactionToMessage(tx, signer, nil) + msg, err := core.TransactionToMessage(tx, signer, nil, ¶ms.Rules{}) if err != nil { return fmt.Errorf("failed to prepare transaction for tracing: %v", err) } diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index f578e2f0f5..3972d4cb95 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests" ) @@ -115,7 +116,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { t.Fatalf("failed to create call tracer: %v", err) } evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) - msg, err := core.TransactionToMessage(tx, signer, nil) + msg, err := core.TransactionToMessage(tx, signer, nil, ¶ms.Rules{}) if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 7c5ec65650..835dfa9448 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -88,7 +88,7 @@ func BenchmarkTransactionTrace(b *testing.B) { //EnableReturnData: false, }) evm := vm.NewEVM(context, txContext, statedb, params.AllEthashProtocolChanges, vm.Config{Debug: true, Tracer: tracer}) - msg, err := core.TransactionToMessage(tx, signer, nil) + msg, err := core.TransactionToMessage(tx, signer, nil, ¶ms.Rules{}) if err != nil { b.Fatalf("failed to prepare transaction for tracing: %v", err) } diff --git a/les/state_accessor.go b/les/state_accessor.go index 9307a799c3..a7065fcaca 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -58,10 +58,10 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. } // Recompute transactions up to the target index. signer := types.MakeSigner(leth.blockchain.Config(), block.Number()) - isMetaTxUpgraded := leth.chainConfig.IsMetaTxV2(block.Time()) + rules := leth.chainConfig.Rules(block.Number(), false, block.Time()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset - msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), isMetaTxUpgraded) + msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), &rules) txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil, leth.blockchain.Config(), statedb) statedb.SetTxContext(tx.Hash(), idx) From 86ac3fd82facc60499701c56d7c30dcae9b0aaf1 Mon Sep 17 00:00:00 2001 From: wwq Date: Mon, 5 Feb 2024 15:47:40 +0800 Subject: [PATCH 10/13] del metatx upgradeTime from mainnet config --- params/config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/params/config.go b/params/config.go index 50605b43ed..41799faaab 100644 --- a/params/config.go +++ b/params/config.go @@ -94,7 +94,6 @@ var ( TerminalTotalDifficultyPassed: true, ShanghaiTime: newUint64(1681338455), Ethash: new(EthashConfig), - MetaTxUpgradeTime: newUint64(0), //newUint64(1707152400), } // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. From 74937cb764837a68937039049d44522d23b21165 Mon Sep 17 00:00:00 2001 From: wwq Date: Mon, 5 Feb 2024 17:38:36 +0800 Subject: [PATCH 11/13] del useless config --- params/config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/params/config.go b/params/config.go index 41799faaab..1c05e374a8 100644 --- a/params/config.go +++ b/params/config.go @@ -138,7 +138,6 @@ var ( MergeNetsplitBlock: big.NewInt(1735371), ShanghaiTime: newUint64(1677557088), Ethash: new(EthashConfig), - MetaTxUpgradeTime: newUint64(0), // newUint64(1707152400), } // SepoliaTrustedCheckpoint contains the light client trusted checkpoint for the Sepolia test network. From 19660a89d1cf008947f81570589329c70fe32d6e Mon Sep 17 00:00:00 2001 From: wwq Date: Mon, 5 Feb 2024 18:17:49 +0800 Subject: [PATCH 12/13] IsMetaTxV2 func use isTimestampForked instead of isMetaTxForked --- params/config.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/params/config.go b/params/config.go index 1c05e374a8..924ffced7d 100644 --- a/params/config.go +++ b/params/config.go @@ -688,7 +688,7 @@ func (c *ChainConfig) IsMantleBVMETHMintUpgrade(time uint64) bool { // IsMetaTxV2 returns whether time is either equal to the MetaTx fork time or greater. func (c *ChainConfig) IsMetaTxV2(time uint64) bool { - return isMetaTxForked(c.MetaTxUpgradeTime, time) + return isTimestampForked(c.MetaTxUpgradeTime, time) } // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. @@ -944,13 +944,6 @@ func isBlockForked(s, head *big.Int) bool { return s.Cmp(head) <= 0 } -func isMetaTxForked(s *uint64, head uint64) bool { - if s == nil { - return false - } - return *s <= head -} - func configBlockEqual(x, y *big.Int) bool { if x == nil { return y == nil From 8824dc5a1a8a00401cc784e9584127adcfabd7e3 Mon Sep 17 00:00:00 2001 From: wwq Date: Tue, 6 Feb 2024 11:29:59 +0800 Subject: [PATCH 13/13] validateTx reject BlobTxType txs, Receipt.MarshalJSON check EffectiveGasPrice and BlobGasPrice --- core/txpool/txpool.go | 3 +++ core/types/gen_receipt_json.go | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index a1c10fcb0a..3ef8d598cd 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -633,6 +633,9 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if tx.Type() == types.DepositTxType { return core.ErrTxTypeNotSupported } + if tx.Type() == types.BlobTxType { + return errors.New("BlobTxType of transaction is currently not supported.") + } // Accept only legacy transactions until EIP-2718/2930 activates. if !pool.eip2718 && tx.Type() != types.LegacyTxType { return core.ErrTxTypeNotSupported diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index dd7fc41fe1..bf6789976e 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -48,11 +48,19 @@ func (r Receipt) MarshalJSON() ([]byte, error) { enc.TxHash = r.TxHash enc.ContractAddress = r.ContractAddress enc.GasUsed = hexutil.Uint64(r.GasUsed) - effectiveGasPrice := hexutil.Big(*r.EffectiveGasPrice) - enc.EffectiveGasPrice = &effectiveGasPrice + if r.EffectiveGasPrice != nil{ + effectiveGasPrice := hexutil.Big(*r.EffectiveGasPrice) + enc.EffectiveGasPrice = &effectiveGasPrice + } else { + enc.EffectiveGasPrice = nil + } enc.BlobGasUsed = hexutil.Uint64(r.BlobGasUsed) - blobGasPrice := hexutil.Big(*r.BlobGasPrice) - enc.BlobGasPrice = &blobGasPrice + if r.BlobGasPrice != nil{ + blobGasPrice := hexutil.Big(*r.BlobGasPrice) + enc.BlobGasPrice = &blobGasPrice + } else { + enc.BlobGasPrice = nil + } if r.DepositNonce != nil { depositNonce := hexutil.Uint64(*r.DepositNonce) enc.DepositNonce = &depositNonce