Skip to content

Commit

Permalink
Merge pull request #37 from mantlenetworkio/wwq/metatx-signFromAddr
Browse files Browse the repository at this point in the history
R4R: metatx add from field into MetaTxSignData, so that to sign hash with from's addr
  • Loading branch information
wwqicode-blkchain authored Feb 6, 2024
2 parents d120ff2 + 8824dc5 commit 4d05b2c
Show file tree
Hide file tree
Showing 20 changed files with 287 additions and 55 deletions.
3 changes: 2 additions & 1 deletion cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
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()})
Expand Down
1 change: 1 addition & 0 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.MetaTxUpgradeTime = mantleUpgradeChainConfig.MetaTxUpgradeTime
}

if overrides != nil && overrides.OverrideShanghai != nil {
Expand Down
5 changes: 5 additions & 0 deletions core/mantle_upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@ var (
ChainID: params.MantleMainnetChainId,
BaseFeeTime: u64Ptr(0),
BVMETHMintUpgradeTime: u64Ptr(0),
MetaTxUpgradeTime: u64Ptr(0),
}

MantleSepoliaUpgradeConfig = MantleUpgradeChainConfig{
ChainID: params.MantleSepoliaChainId,
BaseFeeTime: u64Ptr(1_704_891_600),
BVMETHMintUpgradeTime: nil, //TODO set upgrade timestamp
MetaTxUpgradeTime: nil, //TODO set upgrade timestamp
}
MantleLocalUpgradeConfig = MantleUpgradeChainConfig{
ChainID: params.MantleLocalChainId,
BaseFeeTime: u64Ptr(0),
BVMETHMintUpgradeTime: u64Ptr(0),
MetaTxUpgradeTime: u64Ptr(0),
}
MantleDefaultUpgradeConfig = MantleUpgradeChainConfig{
BaseFeeTime: u64Ptr(0),
BVMETHMintUpgradeTime: u64Ptr(0),
MetaTxUpgradeTime: u64Ptr(0),
}
)

Expand All @@ -34,6 +38,7 @@ type MantleUpgradeChainConfig struct {

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 {
Expand Down
4 changes: 3 additions & 1 deletion core/state_prefetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
msg, err := TransactionToMessage(tx, signer, header.BaseFee, &rules)
if err != nil {
return // Also invalid block, bail out
}
Expand Down
7 changes: 5 additions & 2 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +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)
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)
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)
}
Expand Down Expand Up @@ -171,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)
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
}
Expand Down
8 changes: 6 additions & 2 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package core

import (
"errors"
"fmt"
"math"
"math/big"
Expand Down Expand Up @@ -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) (*Message, error) {
metaTxParams, err := types.DecodeAndVerifyMetaTxParams(tx)
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
}
Expand Down
7 changes: 5 additions & 2 deletions core/txpool/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -689,7 +692,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.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Time))
if err != nil {
return err
}
Expand Down Expand Up @@ -1480,7 +1483,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, pool.chainconfig.IsMetaTxV2(pool.chain.CurrentBlock().Time))
if err != nil {
invalidMetaTxs = append(invalidMetaTxs, tx)
continue
Expand Down
16 changes: 12 additions & 4 deletions core/types/gen_receipt_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 79 additions & 22 deletions core/types/meta_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ type MetaTxSignData struct {
SponsorPercent uint64
}

type MetaTxSignDataV2 struct {
From common.Address
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
}

func CalculateSponsorPercentAmount(mxParams *MetaTxParams, amount *big.Int) (*big.Int, *big.Int) {
if mxParams == nil {
return nil, nil
Expand Down Expand Up @@ -89,7 +104,7 @@ func DecodeMetaTxParams(txData []byte) (*MetaTxParams, error) {
return &metaTxParams, nil
}

func DecodeAndVerifyMetaTxParams(tx *Transaction) (*MetaTxParams, error) {
func DecodeAndVerifyMetaTxParams(tx *Transaction, isMetaTxUpgraded bool) (*MetaTxParams, error) {
if tx.Type() != DynamicFeeTxType {
return nil, nil
}
Expand Down Expand Up @@ -117,27 +132,8 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction) (*MetaTxParams, error) {
return nil, ErrInvalidSponsorPercent
}

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 nil, ErrInvalidGasFeeSponsorSig
}

if gasFeeSponsorSigner != metaTxParams.GasFeeSponsor {
return nil, ErrGasFeeSponsorMismatch
if err = checkSponsorSignature(tx, metaTxParams, isMetaTxUpgraded); err != nil {
return nil, err
}

tx.metaTxParams.Store(&MetaTxParamsCache{
Expand All @@ -147,6 +143,67 @@ func DecodeAndVerifyMetaTxParams(tx *Transaction) (*MetaTxParams, error) {
return metaTxParams, nil
}

func checkSponsorSignature(tx *Transaction, metaTxParams *MetaTxParams, isMetaTxUpgraded bool) error {
var (
txSender, gasFeeSponsorSigner common.Address
err error
)

txSender, err = Sender(LatestSignerForChainID(tx.ChainId()), tx)
if err != nil {
return err
}

if isMetaTxUpgraded {
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)
}
Loading

0 comments on commit 4d05b2c

Please sign in to comment.