mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
Remove code related to EOA-based RIP-7560 transactions
This commit is contained in:
parent
bcca728d62
commit
75fd756a25
6 changed files with 116 additions and 96 deletions
|
|
@ -27,7 +27,6 @@ type ValidationPhaseResult struct {
|
|||
SenderValidUntil uint64
|
||||
PmValidAfter uint64
|
||||
PmValidUntil uint64
|
||||
IsEOA bool
|
||||
}
|
||||
|
||||
// HandleRip7560Transactions apply state changes of all sequential RIP-7560 transactions and return
|
||||
|
|
@ -38,22 +37,13 @@ func HandleRip7560Transactions(transactions []*types.Transaction, index int, sta
|
|||
receipts := make([]*types.Receipt, 0)
|
||||
allLogs := make([]*types.Log, 0)
|
||||
|
||||
i := index
|
||||
for {
|
||||
if i >= len(transactions) {
|
||||
break
|
||||
}
|
||||
if transactions[i].Type() != types.Rip7560Type {
|
||||
break
|
||||
}
|
||||
iTransactions, iReceipts, iLogs, err := handleRip7560Transactions(transactions, index, statedb, coinbase, header, gp, chainConfig, bc, cfg)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
validatedTransactions = append(validatedTransactions, iTransactions...)
|
||||
receipts = append(receipts, iReceipts...)
|
||||
allLogs = append(allLogs, iLogs...)
|
||||
iTransactions, iReceipts, iLogs, err := handleRip7560Transactions(transactions, index, statedb, coinbase, header, gp, chainConfig, bc, cfg)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
validatedTransactions = append(validatedTransactions, iTransactions...)
|
||||
receipts = append(receipts, iReceipts...)
|
||||
allLogs = append(allLogs, iLogs...)
|
||||
return validatedTransactions, receipts, allLogs, nil
|
||||
}
|
||||
|
||||
|
|
@ -62,47 +52,31 @@ func handleRip7560Transactions(transactions []*types.Transaction, index int, sta
|
|||
validatedTransactions := make([]*types.Transaction, 0)
|
||||
receipts := make([]*types.Receipt, 0)
|
||||
allLogs := make([]*types.Log, 0)
|
||||
signer := types.MakeSigner(chainConfig, header.Number, header.Time)
|
||||
for i, tx := range transactions[index:] {
|
||||
if tx.Type() != types.Rip7560Type {
|
||||
break
|
||||
}
|
||||
|
||||
aatx := tx.Rip7560TransactionData()
|
||||
isEoa, err := isTransactionEOA(tx, statedb, signer)
|
||||
statedb.SetTxContext(tx.Hash(), index+i)
|
||||
err := BuyGasRip7560Transaction(aatx, statedb)
|
||||
var vpr *ValidationPhaseResult
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
statedb.SetTxContext(tx.Hash(), index+i)
|
||||
err = BuyGasRip7560Transaction(aatx, statedb)
|
||||
var vpr *ValidationPhaseResult
|
||||
if isEoa {
|
||||
blockContext := NewEVMBlockContext(header, bc, coinbase)
|
||||
tmpMsg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
||||
txContext := NewEVMTxContext(tmpMsg)
|
||||
evm := vm.NewEVM(blockContext, txContext, statedb, chainConfig, cfg)
|
||||
//signer := types.MakeSigner(chainConfig, header.Number, header.Time)
|
||||
signingHash := signer.Hash(tx)
|
||||
vpr, err = validateRip7560TransactionFromEOA(tx, signingHash, statedb, evm, coinbase, header, gp, chainConfig)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
vpr, err = ApplyRip7560ValidationPhases(chainConfig, bc, coinbase, gp, statedb, header, tx, cfg)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
vpr, err = ApplyRip7560ValidationPhases(chainConfig, bc, coinbase, gp, statedb, header, tx, cfg)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
validationPhaseResults = append(validationPhaseResults, vpr)
|
||||
validatedTransactions = append(validatedTransactions, tx)
|
||||
}
|
||||
for i, vpr := range validationPhaseResults {
|
||||
|
||||
// This is the line separating the Validation and Execution phases
|
||||
// It should be separated to implement the mempool-friendly AA RIP (number not assigned yet)
|
||||
// for i, vpr := range validationPhaseResults
|
||||
|
||||
// TODO: this will miss all validation phase events - pass in 'vpr'
|
||||
statedb.SetTxContext(vpr.Tx.Hash(), i)
|
||||
// statedb.SetTxContext(vpr.Tx.Hash(), i)
|
||||
|
||||
receipt, err := ApplyRip7560ExecutionPhase(chainConfig, vpr, bc, coinbase, gp, statedb, header, cfg)
|
||||
|
||||
|
|
@ -139,49 +113,6 @@ func BuyGasRip7560Transaction(st *types.Rip7560AccountAbstractionTx, state vm.St
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO: not needed with subtype - only use to validate transaction, maybe
|
||||
func isTransactionEOA(tx *types.Transaction, statedb *state.StateDB, signer types.Signer) (bool, error) {
|
||||
aatx := tx.Rip7560TransactionData()
|
||||
senderHasCode := statedb.GetCodeSize(*aatx.Sender) != 0 || len(aatx.DeployerData) != 0
|
||||
if senderHasCode {
|
||||
return false, nil
|
||||
}
|
||||
address, err := signer.Sender(tx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if address.Cmp(*tx.Rip7560TransactionData().Sender) != 0 {
|
||||
return false, errors.New("recovered signature does not match the claimed EOA sender")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func validateRip7560TransactionFromEOA(tx *types.Transaction, signingHash common.Hash, statedb *state.StateDB, evm *vm.EVM, coinbase *common.Address, header *types.Header, gp *GasPool, chainConfig *params.ChainConfig) (*ValidationPhaseResult, error) {
|
||||
// TODO: paymaste is actually optional for eoa-type-4 -> check paymaster data len()
|
||||
paymasterContext, pmValidationUsedGas, pmValidAfter, pmValidUntil, err := applyPaymasterValidationFrame(tx, chainConfig, signingHash, evm, gp, statedb, header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = validateValidityTimeRange(header.Time, pmValidAfter, pmValidUntil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vpr := &ValidationPhaseResult{
|
||||
Tx: tx,
|
||||
TxHash: tx.Hash(),
|
||||
PaymasterContext: paymasterContext,
|
||||
DeploymentUsedGas: 0,
|
||||
ValidationUsedGas: 0,
|
||||
PmValidationUsedGas: pmValidationUsedGas,
|
||||
SenderValidAfter: 0,
|
||||
SenderValidUntil: 0,
|
||||
PmValidAfter: pmValidAfter,
|
||||
PmValidUntil: pmValidUntil,
|
||||
IsEOA: true,
|
||||
}
|
||||
return vpr, nil
|
||||
}
|
||||
|
||||
func ApplyRip7560FrameMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) {
|
||||
return NewRip7560StateTransition(evm, msg, gp).TransitionDb()
|
||||
}
|
||||
|
|
@ -311,7 +242,6 @@ func ApplyRip7560ValidationPhases(chainConfig *params.ChainConfig, bc ChainConte
|
|||
SenderValidUntil: validUntil,
|
||||
PmValidAfter: pmValidAfter,
|
||||
PmValidUntil: pmValidUntil,
|
||||
IsEOA: false,
|
||||
}
|
||||
|
||||
return vpr, nil
|
||||
|
|
@ -373,15 +303,7 @@ func ApplyRip7560ExecutionPhase(config *params.ChainConfig, vpr *ValidationPhase
|
|||
txContext.Origin = *vpr.Tx.Rip7560TransactionData().Sender
|
||||
evm := vm.NewEVM(blockContext, txContext, statedb, config, cfg)
|
||||
|
||||
var accountExecutionMsg *Message
|
||||
if vpr.IsEOA {
|
||||
accountExecutionMsg, err = prepareEOATargetExecutionMessage(vpr.Tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
accountExecutionMsg = prepareAccountExecutionMessage(vpr.Tx, evm.ChainConfig())
|
||||
}
|
||||
accountExecutionMsg := prepareAccountExecutionMessage(vpr.Tx, evm.ChainConfig())
|
||||
executionResult, err := ApplyRip7560FrameMessage(evm, accountExecutionMsg, gp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -207,6 +207,8 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
|
|||
inner = new(DynamicFeeTx)
|
||||
case BlobTxType:
|
||||
inner = new(BlobTx)
|
||||
case Rip7560Type:
|
||||
inner = new(Rip7560AccountAbstractionTx)
|
||||
default:
|
||||
return nil, ErrTxTypeNotSupported
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ type sigCache struct {
|
|||
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
|
||||
var signer Signer
|
||||
switch {
|
||||
case config.IsRIP7560(blockNumber):
|
||||
signer = NewRIP7560Signer(config.ChainID)
|
||||
case config.IsCancun(blockNumber, blockTime):
|
||||
signer = NewCancunSigner(config.ChainID)
|
||||
case config.IsLondon(blockNumber):
|
||||
|
|
|
|||
47
core/types/transaction_signing_rip7560.go
Normal file
47
core/types/transaction_signing_rip7560.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type rip7560Signer struct{ londonSigner }
|
||||
|
||||
func NewRIP7560Signer(chainId *big.Int) Signer {
|
||||
return rip7560Signer{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}}
|
||||
}
|
||||
|
||||
func (s rip7560Signer) Sender(tx *Transaction) (common.Address, error) {
|
||||
if tx.Type() != Rip7560Type {
|
||||
return s.londonSigner.Sender(tx)
|
||||
}
|
||||
return [20]byte{}, nil
|
||||
}
|
||||
|
||||
// Hash returns the hash to be signed by the sender.
|
||||
// It does not uniquely identify the transaction.
|
||||
func (s rip7560Signer) Hash(tx *Transaction) common.Hash {
|
||||
if tx.Type() != Rip7560Type {
|
||||
return s.londonSigner.Hash(tx)
|
||||
}
|
||||
aatx := tx.Rip7560TransactionData()
|
||||
return prefixedRlpHash(
|
||||
tx.Type(),
|
||||
[]interface{}{
|
||||
s.chainId,
|
||||
tx.GasTipCap(),
|
||||
tx.GasFeeCap(),
|
||||
tx.Gas(),
|
||||
//tx.To(),
|
||||
tx.Data(),
|
||||
tx.AccessList(),
|
||||
|
||||
aatx.Sender,
|
||||
aatx.PaymasterData,
|
||||
aatx.DeployerData,
|
||||
aatx.BuilderFee,
|
||||
aatx.ValidationGas,
|
||||
aatx.PaymasterGas,
|
||||
aatx.BigNonce,
|
||||
})
|
||||
}
|
||||
|
|
@ -74,6 +74,17 @@ type TransactionArgs struct {
|
|||
|
||||
// This configures whether blobs are allowed to be passed.
|
||||
blobSidecarAllowed bool
|
||||
|
||||
// Introduced by RIP-7560 Transaction
|
||||
Subtype *hexutil.Uint64
|
||||
Sender *common.Address `json:"sender"`
|
||||
Signature *hexutil.Bytes
|
||||
PaymasterData *hexutil.Bytes `json:"paymasterData"`
|
||||
DeployerData *hexutil.Bytes
|
||||
BuilderFee *hexutil.Big
|
||||
ValidationGas *hexutil.Uint64
|
||||
PaymasterGas *hexutil.Uint64
|
||||
BigNonce *hexutil.Big // AA nonce is 256 bits wide
|
||||
}
|
||||
|
||||
// from retrieves the transaction sender address.
|
||||
|
|
@ -472,6 +483,34 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int) *core.Message {
|
|||
func (args *TransactionArgs) ToTransaction() *types.Transaction {
|
||||
var data types.TxData
|
||||
switch {
|
||||
case args.Sender != nil:
|
||||
al := types.AccessList{}
|
||||
if args.AccessList != nil {
|
||||
al = *args.AccessList
|
||||
}
|
||||
aatx := types.Rip7560AccountAbstractionTx{
|
||||
Subtype: byte(*args.Subtype),
|
||||
To: &common.Address{},
|
||||
ChainID: (*big.Int)(args.ChainID),
|
||||
Gas: uint64(*args.Gas),
|
||||
GasFeeCap: (*big.Int)(args.MaxFeePerGas),
|
||||
GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas),
|
||||
Value: (*big.Int)(args.Value),
|
||||
Data: args.data(),
|
||||
AccessList: al,
|
||||
// RIP-7560 parameters
|
||||
Sender: args.Sender,
|
||||
Signature: *args.Signature,
|
||||
PaymasterData: *args.PaymasterData,
|
||||
DeployerData: *args.DeployerData,
|
||||
BuilderFee: (*big.Int)(args.BuilderFee),
|
||||
ValidationGas: uint64(*args.ValidationGas),
|
||||
PaymasterGas: uint64(*args.PaymasterGas),
|
||||
BigNonce: (*big.Int)(args.BigNonce),
|
||||
}
|
||||
data = &aatx
|
||||
hash := types.NewTx(data).Hash()
|
||||
log.Error("RIP-7560 transaction created", "sender", aatx.Sender.Hex(), "hash", hash)
|
||||
case args.BlobHashes != nil:
|
||||
al := types.AccessList{}
|
||||
if args.AccessList != nil {
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ var (
|
|||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
RIP7560Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
|
|
@ -336,6 +337,8 @@ type ChainConfig struct {
|
|||
EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
|
||||
EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
|
||||
|
||||
RIP7560Block *big.Int `json:"rip7560block,omitempty"` // RIP7560 HF block
|
||||
|
||||
ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
|
||||
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
|
||||
PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople)
|
||||
|
|
@ -586,6 +589,11 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
|
|||
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
|
||||
}
|
||||
|
||||
// IsRIP7560 returns whether num is either equal to the RIP7560 fork block or greater.
|
||||
func (c *ChainConfig) IsRIP7560(num *big.Int) bool {
|
||||
return isBlockForked(c.RIP7560Block, num)
|
||||
}
|
||||
|
||||
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||
// with a mismatching chain configuration.
|
||||
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
|
||||
|
|
|
|||
Loading…
Reference in a new issue