test nonce

This commit is contained in:
Dror Tirosh 2024-07-01 12:56:48 +03:00
parent 71e6d5ad1d
commit 702d157aef
3 changed files with 41 additions and 7 deletions

View file

@ -88,11 +88,16 @@ func handleRip7560Transactions(transactions []*types.Transaction, index int, sta
aatx := tx.Rip7560TransactionData() aatx := tx.Rip7560TransactionData()
statedb.SetTxContext(tx.Hash(), index+i) statedb.SetTxContext(tx.Hash(), index+i)
err := BuyGasRip7560Transaction(aatx, statedb) err := CheckNonceRip7560(aatx, statedb)
var vpr *ValidationPhaseResult
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
err = BuyGasRip7560Transaction(aatx, statedb)
if err != nil {
return nil, nil, nil, err
}
var vpr *ValidationPhaseResult
vpr, err = ApplyRip7560ValidationPhases(chainConfig, bc, coinbase, gp, statedb, header, tx, cfg) vpr, err = ApplyRip7560ValidationPhases(chainConfig, bc, coinbase, gp, statedb, header, tx, cfg)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
@ -142,6 +147,24 @@ func BuyGasRip7560Transaction(st *types.Rip7560AccountAbstractionTx, state vm.St
return nil return nil
} }
// precheck nonce of transaction.
// (standard preCheck function check both nonce and no-code of account)
func CheckNonceRip7560(tx *types.Rip7560AccountAbstractionTx, st *state.StateDB) error {
// Make sure this transaction's nonce is correct.
stNonce := st.GetNonce(*tx.Sender)
if msgNonce := tx.Nonce; stNonce < msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
tx.Sender.Hex(), msgNonce, stNonce)
} else if stNonce > msgNonce {
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
tx.Sender.Hex(), msgNonce, stNonce)
} else if stNonce+1 < stNonce {
return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
tx.Sender.Hex(), stNonce)
}
return nil
}
func ApplyRip7560ValidationPhases(chainConfig *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, cfg vm.Config) (*ValidationPhaseResult, error) { func ApplyRip7560ValidationPhases(chainConfig *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, cfg vm.Config) (*ValidationPhaseResult, error) {
blockContext := NewEVMBlockContext(header, bc, author) blockContext := NewEVMBlockContext(header, bc, author)
txContext := vm.TxContext{ txContext := vm.TxContext{
@ -333,6 +356,7 @@ func prepareAccountValidationMessage(baseTx *types.Transaction, chainConfig *par
return &Message{ return &Message{
From: chainConfig.EntryPointAddress, From: chainConfig.EntryPointAddress,
To: tx.Sender, To: tx.Sender,
Nonce: tx.Nonce,
Value: big.NewInt(0), Value: big.NewInt(0),
GasLimit: tx.ValidationGas - deploymentUsedGas, GasLimit: tx.ValidationGas - deploymentUsedGas,
GasPrice: tx.GasFeeCap, GasPrice: tx.GasFeeCap,

View file

@ -55,9 +55,10 @@ type Rip7560AccountAbstractionTx struct {
// copy creates a deep copy of the transaction data and initializes all fields. // copy creates a deep copy of the transaction data and initializes all fields.
func (tx *Rip7560AccountAbstractionTx) copy() TxData { func (tx *Rip7560AccountAbstractionTx) copy() TxData {
cpy := &Rip7560AccountAbstractionTx{ cpy := &Rip7560AccountAbstractionTx{
To: copyAddressPtr(tx.To), To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data), Data: common.CopyBytes(tx.Data),
Gas: tx.Gas, Nonce: tx.Nonce,
Gas: tx.Gas,
// These are copied below. // These are copied below.
AccessList: make(AccessList, len(tx.AccessList)), AccessList: make(AccessList, len(tx.AccessList)),
Value: new(big.Int), Value: new(big.Int),

View file

@ -16,8 +16,9 @@ import (
func TestPackValidationData(t *testing.T) { func TestPackValidationData(t *testing.T) {
//assert.Equal(t, make([]byte, 32), packValidationData(0, 0, 0)) //assert.Equal(t, make([]byte, 32), packValidationData(0, 0, 0))
//assert.Equal(t, new(big.Int).SetInt64(0x1234).Text(16), new(big.Int).SetBytes(packValidationData(0x1234, 0, 0)).Text(16)) //assert.Equal(t, new(big.Int).SetInt64(0x1234).Text(16), new(big.Int).SetBytes(packValidationData(0x1234, 0, 0)).Text(16))
// ------------------------------------ bbbbbbbbbbbb-aaaaaaaaaaa-mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm // --------------- after 6bytes before 6 bytes magic 20 bytes
packed, _ := new(big.Int).SetString("0000000000020000000000010000000000000000000000000000000000001234", 16) validationData := "000000000002" + "000000000001" + "0000000000000000000000000000000000001234"
packed, _ := new(big.Int).SetString(validationData, 16)
assert.Equal(t, packed.Text(16), new(big.Int).SetBytes(core.PackValidationData(0x1234, 1, 2)).Text(16)) assert.Equal(t, packed.Text(16), new(big.Int).SetBytes(core.PackValidationData(0x1234, 1, 2)).Text(16))
} }
@ -71,6 +72,14 @@ func TestValidation_ok_paid(t *testing.T) {
maxCost.Mul(maxCost, aatx.GasFeeCap) maxCost.Mul(maxCost, aatx.GasFeeCap)
} }
func TestValidationFailure_account_nonce(t *testing.T) {
handleTransaction(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), DEFAULT_BALANCE), types.Rip7560AccountAbstractionTx{
Nonce: 1234,
ValidationGas: uint64(1000000000),
GasFeeCap: big.NewInt(1000000000),
}, "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{