AA-378: Completing native tracer (#15)

* Renaming, Adding tstore/tload support

* Fixing tracer wip

* Adding handling of value, onExit

* Removing method id

* Fix abi encoding of nil fields

* typo

* Removing logs
This commit is contained in:
shahafn 2024-07-29 13:29:44 +03:00 committed by GitHub
parent 52f50471f2
commit d450ade0af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 251 additions and 176 deletions

View file

@ -129,7 +129,7 @@ func handleRip7560Transactions(transactions []*types.Transaction, index int, sta
// todo: move to a suitable interface, whatever that is // todo: move to a suitable interface, whatever that is
// todo 2: maybe handle the "shared gas pool" situation instead of just overriding it completely? // todo 2: maybe handle the "shared gas pool" situation instead of just overriding it completely?
func BuyGasRip7560Transaction(st *types.Rip7560AccountAbstractionTx, state vm.StateDB) error { func BuyGasRip7560Transaction(st *types.Rip7560AccountAbstractionTx, state vm.StateDB) error {
gasLimit := st.Gas + st.ValidationGas + st.PaymasterGas + st.PostOpGas gasLimit := st.Gas + st.ValidationGasLimit + st.PaymasterValidationGasLimit + st.PostOpGas
mgval := new(uint256.Int).SetUint64(gasLimit) mgval := new(uint256.Int).SetUint64(gasLimit)
gasFeeCap, _ := uint256.FromBig(st.GasFeeCap) gasFeeCap, _ := uint256.FromBig(st.GasFeeCap)
mgval = mgval.Mul(mgval, gasFeeCap) mgval = mgval.Mul(mgval, gasFeeCap)
@ -363,7 +363,7 @@ func prepareDeployerMessage(baseTx *types.Transaction, config *params.ChainConfi
From: AA_SENDER_CREATOR, From: AA_SENDER_CREATOR,
To: tx.Deployer, To: tx.Deployer,
Value: big.NewInt(0), Value: big.NewInt(0),
GasLimit: tx.ValidationGas, GasLimit: tx.ValidationGasLimit,
GasPrice: tx.GasFeeCap, GasPrice: tx.GasFeeCap,
GasFeeCap: tx.GasFeeCap, GasFeeCap: tx.GasFeeCap,
GasTipCap: tx.GasTipCap, GasTipCap: tx.GasTipCap,
@ -390,7 +390,7 @@ func prepareAccountValidationMessage(baseTx *types.Transaction, chainConfig *par
From: AA_ENTRY_POINT, From: AA_ENTRY_POINT,
To: tx.Sender, To: tx.Sender,
Value: big.NewInt(0), Value: big.NewInt(0),
GasLimit: tx.ValidationGas - deploymentUsedGas, GasLimit: tx.ValidationGasLimit - deploymentUsedGas,
GasPrice: tx.GasFeeCap, GasPrice: tx.GasFeeCap,
GasFeeCap: tx.GasFeeCap, GasFeeCap: tx.GasFeeCap,
GasTipCap: tx.GasTipCap, GasTipCap: tx.GasTipCap,
@ -421,7 +421,7 @@ func preparePaymasterValidationMessage(baseTx *types.Transaction, config *params
From: config.EntryPointAddress, From: config.EntryPointAddress,
To: tx.Paymaster, To: tx.Paymaster,
Value: big.NewInt(0), Value: big.NewInt(0),
GasLimit: tx.PaymasterGas, GasLimit: tx.PaymasterValidationGasLimit,
GasPrice: tx.GasFeeCap, GasPrice: tx.GasFeeCap,
GasFeeCap: tx.GasFeeCap, GasFeeCap: tx.GasFeeCap,
GasTipCap: tx.GasTipCap, GasTipCap: tx.GasTipCap,
@ -470,7 +470,7 @@ func preparePostOpMessage(vpr *ValidationPhaseResult, chainConfig *params.ChainC
From: AA_ENTRY_POINT, From: AA_ENTRY_POINT,
To: tx.Paymaster, To: tx.Paymaster,
Value: big.NewInt(0), Value: big.NewInt(0),
GasLimit: tx.PaymasterGas - executionResult.UsedGas, GasLimit: tx.PaymasterValidationGasLimit - executionResult.UsedGas,
GasPrice: tx.GasFeeCap, GasPrice: tx.GasFeeCap,
GasFeeCap: tx.GasFeeCap, GasFeeCap: tx.GasFeeCap,
GasTipCap: tx.GasTipCap, GasTipCap: tx.GasTipCap,

View file

@ -40,7 +40,7 @@ func (s rip7560Signer) Hash(tx *Transaction) common.Hash {
aatx.PaymasterData, aatx.PaymasterData,
aatx.DeployerData, aatx.DeployerData,
aatx.BuilderFee, aatx.BuilderFee,
aatx.ValidationGas, aatx.ValidationGasLimit,
aatx.PaymasterGas, aatx.PaymasterValidationGasLimit,
}) })
} }

View file

@ -35,16 +35,16 @@ type Rip7560AccountAbstractionTx struct {
AccessList AccessList AccessList AccessList
// extra fields // extra fields
Sender *common.Address Sender *common.Address
Signature []byte Signature []byte
Paymaster *common.Address `rlp:"nil"` Paymaster *common.Address `rlp:"nil"`
PaymasterData []byte PaymasterData []byte
Deployer *common.Address `rlp:"nil"` Deployer *common.Address `rlp:"nil"`
DeployerData []byte DeployerData []byte
BuilderFee *big.Int BuilderFee *big.Int
ValidationGas uint64 ValidationGasLimit uint64
PaymasterGas uint64 PaymasterValidationGasLimit uint64
PostOpGas uint64 PostOpGas uint64
// removed fields // removed fields
To *common.Address `rlp:"nil"` To *common.Address `rlp:"nil"`
@ -66,16 +66,16 @@ func (tx *Rip7560AccountAbstractionTx) copy() TxData {
GasTipCap: new(big.Int), GasTipCap: new(big.Int),
GasFeeCap: new(big.Int), GasFeeCap: new(big.Int),
Sender: copyAddressPtr(tx.Sender), Sender: copyAddressPtr(tx.Sender),
Signature: common.CopyBytes(tx.Signature), Signature: common.CopyBytes(tx.Signature),
Paymaster: copyAddressPtr(tx.Paymaster), Paymaster: copyAddressPtr(tx.Paymaster),
PaymasterData: common.CopyBytes(tx.PaymasterData), PaymasterData: common.CopyBytes(tx.PaymasterData),
Deployer: copyAddressPtr(tx.Deployer), Deployer: copyAddressPtr(tx.Deployer),
DeployerData: common.CopyBytes(tx.DeployerData), DeployerData: common.CopyBytes(tx.DeployerData),
BuilderFee: new(big.Int), BuilderFee: new(big.Int),
ValidationGas: tx.ValidationGas, ValidationGasLimit: tx.ValidationGasLimit,
PaymasterGas: tx.PaymasterGas, PaymasterValidationGasLimit: tx.PaymasterValidationGasLimit,
PostOpGas: tx.PostOpGas, PostOpGas: tx.PostOpGas,
} }
copy(cpy.AccessList, tx.AccessList) copy(cpy.AccessList, tx.AccessList)
if tx.Value != nil { if tx.Value != nil {
@ -151,21 +151,21 @@ func (tx *Rip7560AccountAbstractionTx) decode(input []byte) error {
// Rip7560Transaction an equivalent of a solidity struct only used to encode the 'transaction' parameter // Rip7560Transaction an equivalent of a solidity struct only used to encode the 'transaction' parameter
type Rip7560Transaction struct { type Rip7560Transaction struct {
Sender common.Address Sender common.Address
Nonce *big.Int Nonce *big.Int
ValidationGasLimit *big.Int ValidationGasLimit *big.Int
PaymasterGasLimit *big.Int PaymasterValidationGasLimit *big.Int
PostOpGasLimit *big.Int PostOpGasLimit *big.Int
CallGasLimit *big.Int CallGasLimit *big.Int
MaxFeePerGas *big.Int MaxFeePerGas *big.Int
MaxPriorityFeePerGas *big.Int MaxPriorityFeePerGas *big.Int
BuilderFee *big.Int BuilderFee *big.Int
Paymaster *common.Address Paymaster common.Address
PaymasterData []byte PaymasterData []byte
Deployer *common.Address Deployer common.Address
DeployerData []byte DeployerData []byte
CallData []byte CallData []byte
Signature []byte Signature []byte
} }
func (tx *Rip7560AccountAbstractionTx) AbiEncode() ([]byte, error) { func (tx *Rip7560AccountAbstractionTx) AbiEncode() ([]byte, error) {
@ -173,12 +173,15 @@ func (tx *Rip7560AccountAbstractionTx) AbiEncode() ([]byte, error) {
{Name: "sender", Type: "address"}, {Name: "sender", Type: "address"},
{Name: "nonce", Type: "uint256"}, {Name: "nonce", Type: "uint256"},
{Name: "validationGasLimit", Type: "uint256"}, {Name: "validationGasLimit", Type: "uint256"},
{Name: "paymasterGasLimit", Type: "uint256"}, {Name: "paymasterValidationGasLimit", Type: "uint256"},
{Name: "postOpGasLimit", Type: "uint256"},
{Name: "callGasLimit", Type: "uint256"}, {Name: "callGasLimit", Type: "uint256"},
{Name: "maxFeePerGas", Type: "uint256"}, {Name: "maxFeePerGas", Type: "uint256"},
{Name: "maxPriorityFeePerGas", Type: "uint256"}, {Name: "maxPriorityFeePerGas", Type: "uint256"},
{Name: "builderFee", Type: "uint256"}, {Name: "builderFee", Type: "uint256"},
{Name: "paymaster", Type: "address"},
{Name: "paymasterData", Type: "bytes"}, {Name: "paymasterData", Type: "bytes"},
{Name: "deployer", Type: "address"},
{Name: "deployerData", Type: "bytes"}, {Name: "deployerData", Type: "bytes"},
{Name: "callData", Type: "bytes"}, {Name: "callData", Type: "bytes"},
{Name: "signature", Type: "bytes"}, {Name: "signature", Type: "bytes"},
@ -187,19 +190,32 @@ func (tx *Rip7560AccountAbstractionTx) AbiEncode() ([]byte, error) {
args := abi.Arguments{ args := abi.Arguments{
{Type: structThing, Name: "param_one"}, {Type: structThing, Name: "param_one"},
} }
paymaster := tx.Paymaster
if paymaster == nil {
paymaster = &common.Address{}
}
deployer := tx.Deployer
if deployer == nil {
deployer = &common.Address{}
}
record := &Rip7560Transaction{ record := &Rip7560Transaction{
Sender: *tx.Sender, Sender: *tx.Sender,
Nonce: big.NewInt(int64(tx.Nonce)), Nonce: big.NewInt(int64(tx.Nonce)),
ValidationGasLimit: big.NewInt(int64(tx.ValidationGas)), ValidationGasLimit: big.NewInt(int64(tx.ValidationGasLimit)),
PaymasterGasLimit: big.NewInt(int64(tx.PaymasterGas)), PaymasterValidationGasLimit: big.NewInt(int64(tx.PaymasterValidationGasLimit)),
CallGasLimit: big.NewInt(int64(tx.Gas)), PostOpGasLimit: big.NewInt(int64(tx.PostOpGas)),
MaxFeePerGas: tx.GasFeeCap, CallGasLimit: big.NewInt(int64(tx.Gas)),
MaxPriorityFeePerGas: tx.GasTipCap, MaxFeePerGas: tx.GasFeeCap,
BuilderFee: tx.BuilderFee, MaxPriorityFeePerGas: tx.GasTipCap,
PaymasterData: tx.PaymasterData, BuilderFee: tx.BuilderFee,
DeployerData: tx.DeployerData, Paymaster: *paymaster,
CallData: tx.Data, PaymasterData: tx.PaymasterData,
Signature: tx.Signature, Deployer: *deployer,
DeployerData: tx.DeployerData,
CallData: tx.Data,
Signature: tx.Signature,
} }
packed, err := args.Pack(&record) packed, err := args.Pack(&record)
return packed, err return packed, err

View file

@ -11,6 +11,7 @@ import (
"github.com/holiman/uint256" "github.com/holiman/uint256"
"math/big" "math/big"
"regexp" "regexp"
"strconv"
"strings" "strings"
) )
@ -33,8 +34,10 @@ type contractSizeVal struct {
} }
type access struct { type access struct {
Reads map[string]string `json:"reads"` Reads map[string]string `json:"reads"`
Writes map[string]uint64 `json:"writes"` Writes map[string]uint64 `json:"writes"`
TransientReads map[string]uint64 `json:"transientReads"`
TransientWrites map[string]uint64 `json:"transientWrites"`
} }
// note - this means an individual 'frame' in 7560 (validate, execute, postOp) // note - this means an individual 'frame' in 7560 (validate, execute, postOp)
@ -87,6 +90,7 @@ func newRip7560Tracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Trace
OnTxStart: t.OnTxStart, OnTxStart: t.OnTxStart,
OnTxEnd: t.OnTxEnd, OnTxEnd: t.OnTxEnd,
OnOpcode: t.OnOpcode, OnOpcode: t.OnOpcode,
OnExit: t.OnExit,
}, },
GetResult: t.GetResult, GetResult: t.GetResult,
Stop: t.Stop, Stop: t.Stop,
@ -142,6 +146,27 @@ func (b *rip7560ValidationTracer) OnEnter(depth int, typ byte, from common.Addre
if depth == 0 { if depth == 0 {
b.createNewTopLevelFrame(to) b.createNewTopLevelFrame(to)
} }
b.Calls = append(b.Calls, &callsItem{
Type: vm.OpCode(typ).String(),
From: from,
To: to,
//Method: input[0:10],
Value: (*hexutil.Big)(value),
Gas: gas,
Data: input,
})
}
func (b *rip7560ValidationTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
typ := "RETURN"
if err != nil {
typ = "REVERT"
}
b.Calls = append(b.Calls, &callsItem{
Type: typ,
GasUsed: gasUsed,
Data: output,
})
} }
func (b *rip7560ValidationTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { func (b *rip7560ValidationTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) {
@ -251,14 +276,16 @@ func (b *rip7560ValidationTracer) OnOpcode(pc uint64, op byte, gas, cost uint64,
} }
b.lastOp = opcode b.lastOp = opcode
if opcode == "SLOAD" || opcode == "SSTORE" { if opcode == "SLOAD" || opcode == "SSTORE" || opcode == "TLOAD" || opcode == "TSTORE" {
slot := common.BytesToHash(StackBack(scope.StackData(), 0).Bytes()) slot := common.BytesToHash(StackBack(scope.StackData(), 0).Bytes())
slotHex := slot.Hex() slotHex := slot.Hex()
addr := scope.Address() addr := scope.Address()
if _, ok := b.CurrentLevel.Access[addr]; !ok { if _, ok := b.CurrentLevel.Access[addr]; !ok {
b.CurrentLevel.Access[addr] = &access{ b.CurrentLevel.Access[addr] = &access{
Reads: map[string]string{}, Reads: map[string]string{},
Writes: map[string]uint64{}, Writes: map[string]uint64{},
TransientReads: map[string]uint64{},
TransientWrites: map[string]uint64{},
} }
} }
access := *b.CurrentLevel.Access[addr] access := *b.CurrentLevel.Access[addr]
@ -271,34 +298,44 @@ func (b *rip7560ValidationTracer) OnOpcode(pc uint64, op byte, gas, cost uint64,
if !rOk && !wOk { if !rOk && !wOk {
access.Reads[slotHex] = b.env.StateDB.GetState(addr, slot).Hex() access.Reads[slotHex] = b.env.StateDB.GetState(addr, slot).Hex()
} }
} else { } else if opcode == "SSTORE" {
b.incrementCount(access.Writes, slotHex) b.incrementCount(access.Writes, slotHex)
} else if opcode == "TLOAD" {
b.incrementCount(access.TransientReads, slotHex)
} else if opcode == "TSTORE" {
b.incrementCount(access.TransientWrites, slotHex)
} }
} }
if opcode == "KECCAK256" { if opcode == "KECCAK256" {
// TODO: uncomment and fix with StackBack // TODO: uncomment and fix with StackBack
// collect keccak on 64-byte blocks // collect keccak on 64-byte blocks
// ofs := scope.Stack.Back(0).ToBig().Int64() ofs := StackBack(scope.StackData(), 0)
// len := scope.Stack.Back(1).ToBig().Int64() len := StackBack(scope.StackData(), 1)
memory := scope.MemoryData()
// // currently, solidity uses only 2-word (6-byte) for a key. this might change..still, no need to // // currently, solidity uses only 2-word (6-byte) for a key. this might change..still, no need to
// // return too much // // return too much
// if len > 20 && len < 512 { if len.Uint64() > 20 && len.Uint64() < 512 {
// b.Keccak = append(b.Keccak, scope.Memory.GetCopy(ofs, len)) keccak := make([]byte, len.Uint64())
// } copy(keccak, memory[ofs.Uint64():ofs.Uint64()+len.Uint64()])
//} else if strings.HasPrefix(opcode, "LOG") { b.Keccak = append(b.Keccak, keccak)
// count, _ := strconv.Atoi(opcode[3:]) }
// ofs := scope.Stack.Back(0).ToBig().Int64() } else if strings.HasPrefix(opcode, "LOG") {
// len := scope.Stack.Back(1).ToBig().Int64() count, _ := strconv.Atoi(opcode[3:])
// topics := []hexutil.Bytes{} ofs := StackBack(scope.StackData(), 0)
// for i := 0; i < count; i++ { len := StackBack(scope.StackData(), 1)
// topics = append(topics, scope.Stack.Back(2+i).Bytes()) memory := scope.MemoryData()
// } topics := []hexutil.Bytes{}
// for i := 0; i < count; i++ {
// b.Logs = append(b.Logs, &logsItem{ topics = append(topics, StackBack(scope.StackData(), 2+i).Bytes())
// Data: scope.Memory.GetCopy(ofs, len), //topics = append(topics, scope.Stack.Back(2+i).Bytes())
// Topic: topics, }
// }) log := make([]byte, len.Uint64())
copy(log, memory[ofs.Uint64():ofs.Uint64()+len.Uint64()])
b.Logs = append(b.Logs, &logsItem{
Data: log,
Topic: topics,
})
} }
} }

View file

@ -115,6 +115,9 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
if err := args.setFeeDefaults(ctx, b); err != nil { if err := args.setFeeDefaults(ctx, b); err != nil {
return err return err
} }
if err := args.set7560Defaults(ctx, b); err != nil {
return err
}
if args.Value == nil { if args.Value == nil {
args.Value = new(hexutil.Big) args.Value = new(hexutil.Big)
@ -194,6 +197,25 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
return nil return nil
} }
func (args *TransactionArgs) set7560Defaults(ctx context.Context, b Backend) error {
// Not 7560 tx
if args.Sender == nil {
return nil
}
if args.Paymaster == nil {
log.Error("set7560Defaults setting default paymaster fields")
args.Paymaster = &common.Address{}
args.PaymasterData = &hexutil.Bytes{}
}
if args.Deployer == nil {
log.Error("set7560Defaults setting default deployer fields")
args.Deployer = &common.Address{}
args.DeployerData = &hexutil.Bytes{}
}
return nil
}
// setFeeDefaults fills in default fee values for unspecified tx fields. // setFeeDefaults fills in default fee values for unspecified tx fields.
func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) error { func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) error {
head := b.CurrentHeader() head := b.CurrentHeader()
@ -500,16 +522,16 @@ func (args *TransactionArgs) ToTransaction() *types.Transaction {
Data: args.data(), Data: args.data(),
AccessList: al, AccessList: al,
// RIP-7560 parameters // RIP-7560 parameters
Sender: args.Sender, Sender: args.Sender,
Signature: *args.Signature, Signature: *args.Signature,
Paymaster: args.Paymaster, Paymaster: args.Paymaster,
PaymasterData: *args.PaymasterData, PaymasterData: *args.PaymasterData,
Deployer: args.Deployer, Deployer: args.Deployer,
DeployerData: *args.DeployerData, DeployerData: *args.DeployerData,
BuilderFee: (*big.Int)(args.BuilderFee), BuilderFee: (*big.Int)(args.BuilderFee),
ValidationGas: uint64(*args.ValidationGas), ValidationGasLimit: uint64(*args.ValidationGas),
PaymasterGas: uint64(*args.PaymasterGas), PaymasterValidationGasLimit: uint64(*args.PaymasterGas),
PostOpGas: uint64(*args.PostOpGas), PostOpGas: uint64(*args.PostOpGas),
} }
data = &aatx data = &aatx
hash := types.NewTx(data).Hash() hash := types.NewTx(data).Hash()

View file

@ -14,9 +14,9 @@ func TestValidationFailure_deployerRevert(t *testing.T) {
withCode(DEFAULT_SENDER, []byte{}, DEFAULT_BALANCE). withCode(DEFAULT_SENDER, []byte{}, DEFAULT_BALANCE).
withCode(DEPLOYER.Hex(), revertWithData([]byte{}), 0), withCode(DEPLOYER.Hex(), revertWithData([]byte{}), 0),
types.Rip7560AccountAbstractionTx{ types.Rip7560AccountAbstractionTx{
Deployer: &DEPLOYER, Deployer: &DEPLOYER,
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "account deployment failed: execution reverted") }, "account deployment failed: execution reverted")
} }
@ -25,9 +25,9 @@ func TestValidationFailure_deployerOOG(t *testing.T) {
withCode(DEFAULT_SENDER, []byte{}, DEFAULT_BALANCE). withCode(DEFAULT_SENDER, []byte{}, DEFAULT_BALANCE).
withCode(DEPLOYER.Hex(), revertWithData([]byte{}), 0), withCode(DEPLOYER.Hex(), revertWithData([]byte{}), 0),
types.Rip7560AccountAbstractionTx{ types.Rip7560AccountAbstractionTx{
Deployer: &DEPLOYER, Deployer: &DEPLOYER,
ValidationGas: 1, ValidationGasLimit: 1,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "account deployment failed: out of gas") }, "account deployment failed: out of gas")
} }
@ -36,9 +36,9 @@ func TestValidationFailure_senderNotDeployed(t *testing.T) {
withCode(DEFAULT_SENDER, []byte{}, DEFAULT_BALANCE). withCode(DEFAULT_SENDER, []byte{}, DEFAULT_BALANCE).
withCode(DEPLOYER.Hex(), returnWithData([]byte{}), 0), withCode(DEPLOYER.Hex(), returnWithData([]byte{}), 0),
types.Rip7560AccountAbstractionTx{ types.Rip7560AccountAbstractionTx{
Deployer: &DEPLOYER, Deployer: &DEPLOYER,
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "account deployment failed: sender not deployed") }, "account deployment failed: sender not deployed")
} }
@ -50,10 +50,10 @@ func TestValidationFailure_senderAlreadyDeployed(t *testing.T) {
withCode(sender.Hex(), accountCode, DEFAULT_BALANCE). withCode(sender.Hex(), accountCode, DEFAULT_BALANCE).
withCode(DEPLOYER.Hex(), deployerCode, 0), withCode(DEPLOYER.Hex(), deployerCode, 0),
types.Rip7560AccountAbstractionTx{ types.Rip7560AccountAbstractionTx{
Sender: &sender, Sender: &sender,
Deployer: &DEPLOYER, Deployer: &DEPLOYER,
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "account deployment failed: sender already deployed") }, "account deployment failed: sender already deployed")
} }
@ -65,10 +65,10 @@ func TestValidationFailure_senderReverts(t *testing.T) {
withCode(sender.Hex(), []byte{}, DEFAULT_BALANCE). withCode(sender.Hex(), []byte{}, DEFAULT_BALANCE).
withCode(DEPLOYER.Hex(), deployerCode, 0), withCode(DEPLOYER.Hex(), deployerCode, 0),
types.Rip7560AccountAbstractionTx{ types.Rip7560AccountAbstractionTx{
Sender: &sender, Sender: &sender,
Deployer: &DEPLOYER, Deployer: &DEPLOYER,
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "execution reverted") }, "execution reverted")
} }
@ -80,9 +80,9 @@ func TestValidation_deployer_ok(t *testing.T) {
withCode(sender.Hex(), []byte{}, DEFAULT_BALANCE). withCode(sender.Hex(), []byte{}, DEFAULT_BALANCE).
withCode(DEPLOYER.Hex(), deployerCode, 0), withCode(DEPLOYER.Hex(), deployerCode, 0),
types.Rip7560AccountAbstractionTx{ types.Rip7560AccountAbstractionTx{
Sender: &sender, Sender: &sender,
Deployer: &DEPLOYER, Deployer: &DEPLOYER,
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "ok") }, "ok")
} }

View file

@ -15,9 +15,9 @@ func TestPaymasterValidationFailure_nobalance(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), createCode(vm.PUSH0, vm.DUP1, vm.REVERT), 1), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), createCode(vm.PUSH0, vm.DUP1, vm.REVERT), 1), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "insufficient funds for gas * price + value: address 0xaaAaaAAAAAbBbbbbBbBBCCCCcCCCcCdddDDDdddd have 1 want 1000000000000000000") }, "insufficient funds for gas * price + value: address 0xaaAaaAAAAAbBbbbbBbBBCCCCcCCCcCdddDDDdddd have 1 want 1000000000000000000")
} }
@ -25,19 +25,19 @@ func TestPaymasterValidationFailure_oog(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), createCode(vm.PUSH0, vm.DUP1, vm.REVERT), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), createCode(vm.PUSH0, vm.DUP1, vm.REVERT), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "out of gas") }, "out of gas")
} }
func TestPaymasterValidationFailure_revert(t *testing.T) { func TestPaymasterValidationFailure_revert(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), createCode(vm.PUSH0, vm.DUP1, vm.REVERT), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), createCode(vm.PUSH0, vm.DUP1, vm.REVERT), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
}, "execution reverted") }, "execution reverted")
} }
@ -45,20 +45,20 @@ func TestPaymasterValidationFailure_unparseable_return_value(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "paymaster return data: too short") }, "paymaster return data: too short")
} }
func TestPaymasterValidationFailure_wrong_magic(t *testing.T) { func TestPaymasterValidationFailure_wrong_magic(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(1, 2, 3, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(1, 2, 3, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "paymaster did not return correct MAGIC_VALUE") }, "paymaster did not return correct MAGIC_VALUE")
} }
@ -77,39 +77,39 @@ func TestPaymasterValidationFailure_contextTooLarge(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), pmCode, DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), pmCode, DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "paymaster return data: context too large") }, "paymaster return data: context too large")
} }
func TestPaymasterValidationFailure_validAfter(t *testing.T) { func TestPaymasterValidationFailure_validAfter(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(core.MAGIC_VALUE_PAYMASTER, 300, 200, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(core.MAGIC_VALUE_PAYMASTER, 300, 200, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "RIP-7560 transaction validity not reached yet") }, "RIP-7560 transaction validity not reached yet")
} }
func TestPaymasterValidationFailure_validUntil(t *testing.T) { func TestPaymasterValidationFailure_validUntil(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(core.MAGIC_VALUE_PAYMASTER, 1, 0, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(core.MAGIC_VALUE_PAYMASTER, 1, 0, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "RIP-7560 transaction validity expired") }, "RIP-7560 transaction validity expired")
} }
func TestPaymasterValidation_ok(t *testing.T) { func TestPaymasterValidation_ok(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0). handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0).
withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(core.MAGIC_VALUE_PAYMASTER, 0, 0, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ withCode(DEFAULT_PAYMASTER.String(), returnWithData(paymasterReturnValue(core.MAGIC_VALUE_PAYMASTER, 0, 0, []byte{})), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: 1000000000, ValidationGasLimit: 1000000000,
PaymasterGas: 1000000000, PaymasterValidationGasLimit: 1000000000,
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Paymaster: &DEFAULT_PAYMASTER, Paymaster: &DEFAULT_PAYMASTER,
}, "ok") }, "ok")
} }

View file

@ -42,10 +42,10 @@ func TestProcess1(t *testing.T) {
withCode(DEFAULT_SENDER, createAccountCode(), 1000000000000000000). withCode(DEFAULT_SENDER, createAccountCode(), 1000000000000000000).
build(), []*types.Rip7560AccountAbstractionTx{ build(), []*types.Rip7560AccountAbstractionTx{
{ {
Sender: &Sender, Sender: &Sender,
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
Data: []byte{1, 2, 3}, Data: []byte{1, 2, 3},
}, },
}) })
assert.NoError(t, err) assert.NoError(t, err)

View file

@ -30,23 +30,23 @@ func TestUnpackValidationData(t *testing.T) {
func TestValidationFailure_OOG(t *testing.T) { func TestValidationFailure_OOG(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1), ValidationGasLimit: uint64(1),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "out of gas") }, "out of gas")
} }
func TestValidationFailure_no_balance(t *testing.T) { func TestValidationFailure_no_balance(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 1), types.Rip7560AccountAbstractionTx{ handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 1), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1), ValidationGasLimit: uint64(1),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "insufficient funds for gas * price + value: address 0x1111111111222222222233333333334444444444 have 1 want 1000000000") }, "insufficient funds for gas * price + value: address 0x1111111111222222222233333333334444444444 have 1 want 1000000000")
} }
func TestValidationFailure_sigerror(t *testing.T) { func TestValidationFailure_sigerror(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, returnWithData(core.PackValidationData(core.MAGIC_VALUE_SIGFAIL, 0, 0)), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, returnWithData(core.PackValidationData(core.MAGIC_VALUE_SIGFAIL, 0, 0)), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "account signature error") }, "account signature error")
} }
@ -54,8 +54,8 @@ func TestValidationFailure_validAfter(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
returnWithData(core.PackValidationData(core.MAGIC_VALUE_SENDER, 300, 200)), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ returnWithData(core.PackValidationData(core.MAGIC_VALUE_SENDER, 300, 200)), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "RIP-7560 transaction validity not reached yet") }, "RIP-7560 transaction validity not reached yet")
} }
@ -63,45 +63,45 @@ func TestValidationFailure_validUntil(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
returnWithData(core.PackValidationData(core.MAGIC_VALUE_SENDER, 1, 0)), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ returnWithData(core.PackValidationData(core.MAGIC_VALUE_SENDER, 1, 0)), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "RIP-7560 transaction validity expired") }, "RIP-7560 transaction validity expired")
} }
func TestValidation_ok(t *testing.T) { func TestValidation_ok(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "ok") }, "ok")
} }
func TestValidation_ok_paid(t *testing.T) { func TestValidation_ok_paid(t *testing.T) {
aatx := types.Rip7560AccountAbstractionTx{ aatx := types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
} }
tb := newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE) tb := newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE)
handleTransaction(tb, aatx, "ok") handleTransaction(tb, aatx, "ok")
maxCost := new(big.Int).SetUint64(aatx.ValidationGas + aatx.PaymasterGas + aatx.Gas) maxCost := new(big.Int).SetUint64(aatx.ValidationGasLimit + aatx.PaymasterValidationGasLimit + aatx.Gas)
maxCost.Mul(maxCost, aatx.GasFeeCap) maxCost.Mul(maxCost, aatx.GasFeeCap)
} }
func TestValidationFailure_account_nonce(t *testing.T) { func TestValidationFailure_account_nonce(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
Nonce: 1234, Nonce: 1234,
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "nonce too high: address 0x1111111111222222222233333333334444444444, tx: 1234 state: 0") }, "nonce too high: address 0x1111111111222222222233333333334444444444, tx: 1234 state: 0")
} }
func TestValidationFailure_account_revert(t *testing.T) { func TestValidationFailure_account_revert(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
createCode(vm.PUSH0, vm.DUP1, vm.REVERT), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ createCode(vm.PUSH0, vm.DUP1, vm.REVERT), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "execution reverted") }, "execution reverted")
} }
@ -110,24 +110,24 @@ func TestValidationFailure_account_revert_with_reason(t *testing.T) {
reason := hexutils.HexToBytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000") reason := hexutils.HexToBytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000")
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
revertWithData(reason), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ revertWithData(reason), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "execution reverted") }, "execution reverted")
} }
func TestValidationFailure_account_wrong_return_length(t *testing.T) { func TestValidationFailure_account_wrong_return_length(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
returnWithData([]byte{1, 2, 3}), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ returnWithData([]byte{1, 2, 3}), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "invalid account return data length") }, "invalid account return data length")
} }
func TestValidationFailure_account_no_return_value(t *testing.T) { func TestValidationFailure_account_no_return_value(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
returnWithData([]byte{}), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ returnWithData([]byte{}), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "invalid account return data length") }, "invalid account return data length")
} }
@ -136,8 +136,8 @@ func TestValidationFailure_account_wrong_return_value(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER,
returnWithData(make([]byte, 32)), returnWithData(make([]byte, 32)),
DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{ DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
ValidationGas: uint64(1000000000), ValidationGasLimit: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000), GasFeeCap: big.NewInt(1000000000),
}, "account did not return correct MAGIC_VALUE") }, "account did not return correct MAGIC_VALUE")
} }