mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32: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
|
SenderValidUntil uint64
|
||||||
PmValidAfter uint64
|
PmValidAfter uint64
|
||||||
PmValidUntil uint64
|
PmValidUntil uint64
|
||||||
IsEOA bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleRip7560Transactions apply state changes of all sequential RIP-7560 transactions and return
|
// 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)
|
receipts := make([]*types.Receipt, 0)
|
||||||
allLogs := make([]*types.Log, 0)
|
allLogs := make([]*types.Log, 0)
|
||||||
|
|
||||||
i := index
|
iTransactions, iReceipts, iLogs, err := handleRip7560Transactions(transactions, index, statedb, coinbase, header, gp, chainConfig, bc, cfg)
|
||||||
for {
|
if err != nil {
|
||||||
if i >= len(transactions) {
|
return nil, nil, nil, err
|
||||||
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...)
|
|
||||||
}
|
}
|
||||||
|
validatedTransactions = append(validatedTransactions, iTransactions...)
|
||||||
|
receipts = append(receipts, iReceipts...)
|
||||||
|
allLogs = append(allLogs, iLogs...)
|
||||||
return validatedTransactions, receipts, allLogs, nil
|
return validatedTransactions, receipts, allLogs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,47 +52,31 @@ func handleRip7560Transactions(transactions []*types.Transaction, index int, sta
|
||||||
validatedTransactions := make([]*types.Transaction, 0)
|
validatedTransactions := make([]*types.Transaction, 0)
|
||||||
receipts := make([]*types.Receipt, 0)
|
receipts := make([]*types.Receipt, 0)
|
||||||
allLogs := make([]*types.Log, 0)
|
allLogs := make([]*types.Log, 0)
|
||||||
signer := types.MakeSigner(chainConfig, header.Number, header.Time)
|
|
||||||
for i, tx := range transactions[index:] {
|
for i, tx := range transactions[index:] {
|
||||||
if tx.Type() != types.Rip7560Type {
|
if tx.Type() != types.Rip7560Type {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
aatx := tx.Rip7560TransactionData()
|
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 {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
statedb.SetTxContext(tx.Hash(), index+i)
|
vpr, err = ApplyRip7560ValidationPhases(chainConfig, bc, coinbase, gp, statedb, header, tx, cfg)
|
||||||
err = BuyGasRip7560Transaction(aatx, statedb)
|
if err != nil {
|
||||||
var vpr *ValidationPhaseResult
|
return nil, nil, nil, err
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
validationPhaseResults = append(validationPhaseResults, vpr)
|
validationPhaseResults = append(validationPhaseResults, vpr)
|
||||||
validatedTransactions = append(validatedTransactions, tx)
|
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'
|
// 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)
|
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
|
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) {
|
func ApplyRip7560FrameMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) {
|
||||||
return NewRip7560StateTransition(evm, msg, gp).TransitionDb()
|
return NewRip7560StateTransition(evm, msg, gp).TransitionDb()
|
||||||
}
|
}
|
||||||
|
|
@ -311,7 +242,6 @@ func ApplyRip7560ValidationPhases(chainConfig *params.ChainConfig, bc ChainConte
|
||||||
SenderValidUntil: validUntil,
|
SenderValidUntil: validUntil,
|
||||||
PmValidAfter: pmValidAfter,
|
PmValidAfter: pmValidAfter,
|
||||||
PmValidUntil: pmValidUntil,
|
PmValidUntil: pmValidUntil,
|
||||||
IsEOA: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vpr, nil
|
return vpr, nil
|
||||||
|
|
@ -373,15 +303,7 @@ func ApplyRip7560ExecutionPhase(config *params.ChainConfig, vpr *ValidationPhase
|
||||||
txContext.Origin = *vpr.Tx.Rip7560TransactionData().Sender
|
txContext.Origin = *vpr.Tx.Rip7560TransactionData().Sender
|
||||||
evm := vm.NewEVM(blockContext, txContext, statedb, config, cfg)
|
evm := vm.NewEVM(blockContext, txContext, statedb, config, cfg)
|
||||||
|
|
||||||
var accountExecutionMsg *Message
|
accountExecutionMsg := prepareAccountExecutionMessage(vpr.Tx, evm.ChainConfig())
|
||||||
if vpr.IsEOA {
|
|
||||||
accountExecutionMsg, err = prepareEOATargetExecutionMessage(vpr.Tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
accountExecutionMsg = prepareAccountExecutionMessage(vpr.Tx, evm.ChainConfig())
|
|
||||||
}
|
|
||||||
executionResult, err := ApplyRip7560FrameMessage(evm, accountExecutionMsg, gp)
|
executionResult, err := ApplyRip7560FrameMessage(evm, accountExecutionMsg, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,8 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
|
||||||
inner = new(DynamicFeeTx)
|
inner = new(DynamicFeeTx)
|
||||||
case BlobTxType:
|
case BlobTxType:
|
||||||
inner = new(BlobTx)
|
inner = new(BlobTx)
|
||||||
|
case Rip7560Type:
|
||||||
|
inner = new(Rip7560AccountAbstractionTx)
|
||||||
default:
|
default:
|
||||||
return nil, ErrTxTypeNotSupported
|
return nil, ErrTxTypeNotSupported
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ type sigCache struct {
|
||||||
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
|
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
|
||||||
var signer Signer
|
var signer Signer
|
||||||
switch {
|
switch {
|
||||||
|
case config.IsRIP7560(blockNumber):
|
||||||
|
signer = NewRIP7560Signer(config.ChainID)
|
||||||
case config.IsCancun(blockNumber, blockTime):
|
case config.IsCancun(blockNumber, blockTime):
|
||||||
signer = NewCancunSigner(config.ChainID)
|
signer = NewCancunSigner(config.ChainID)
|
||||||
case config.IsLondon(blockNumber):
|
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.
|
// This configures whether blobs are allowed to be passed.
|
||||||
blobSidecarAllowed bool
|
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.
|
// 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 {
|
func (args *TransactionArgs) ToTransaction() *types.Transaction {
|
||||||
var data types.TxData
|
var data types.TxData
|
||||||
switch {
|
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:
|
case args.BlobHashes != nil:
|
||||||
al := types.AccessList{}
|
al := types.AccessList{}
|
||||||
if args.AccessList != nil {
|
if args.AccessList != nil {
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ var (
|
||||||
EIP150Block: big.NewInt(0),
|
EIP150Block: big.NewInt(0),
|
||||||
EIP155Block: big.NewInt(0),
|
EIP155Block: big.NewInt(0),
|
||||||
EIP158Block: big.NewInt(0),
|
EIP158Block: big.NewInt(0),
|
||||||
|
RIP7560Block: big.NewInt(0),
|
||||||
ByzantiumBlock: big.NewInt(0),
|
ByzantiumBlock: big.NewInt(0),
|
||||||
ConstantinopleBlock: big.NewInt(0),
|
ConstantinopleBlock: big.NewInt(0),
|
||||||
PetersburgBlock: big.NewInt(0),
|
PetersburgBlock: big.NewInt(0),
|
||||||
|
|
@ -336,6 +337,8 @@ type ChainConfig struct {
|
||||||
EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
|
EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
|
||||||
EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 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)
|
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)
|
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)
|
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)
|
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
|
// CheckCompatible checks whether scheduled fork transitions have been imported
|
||||||
// with a mismatching chain configuration.
|
// with a mismatching chain configuration.
|
||||||
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
|
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue