From 45ec501b4b4e98e5a5b1b442af4cca9953568ac2 Mon Sep 17 00:00:00 2001 From: Dror Tirosh Date: Tue, 4 Jun 2024 19:40:06 +0300 Subject: [PATCH] initial Process test (#7) initial test for the full "Process" call, to handle mixed legacy and AA transactions --- tests/rip7560/process_test.go | 112 ++++++++++++++++++++++++++++++ tests/rip7560/rip7560TestUtils.go | 8 +++ tests/rip7560/validation_test.go | 4 +- 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 tests/rip7560/process_test.go diff --git a/tests/rip7560/process_test.go b/tests/rip7560/process_test.go new file mode 100644 index 0000000000..4d97c59dd7 --- /dev/null +++ b/tests/rip7560/process_test.go @@ -0,0 +1,112 @@ +// attempt to test Process, and how 7560 transaction affect normal TXs +package rip7560 + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/tests" + "github.com/ethereum/go-ethereum/trie" + "github.com/stretchr/testify/assert" + "math/big" + "testing" +) + +/** +Test that "Process" of 7560 transactions doesn't alter legacy transaction processing. +the idea: +1. Run "Process" with a set of transactions L1 [AA1..AAn] L2 +2. Run "Process" just with the lagacy transactions L1,L2 +3. if AA transactions revert validation - make sure the legacy processing is intact. +4. if AA transactions are executed, make sure the needed state changes of the legacy transactions is intact +*/ + +const addr1 = "f39Fd6e51aad88F6F4ce6aB8827279cffFb92266" +const privKey1 = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + +const addr2 = "70997970C51812dc3A010C7d01b50e0d17dc79C8" +const privKey2 = "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" + +// initial minimal test that a valid AATX can be processed in a block +func TestProcess1(t *testing.T) { + + Sender := common.HexToAddress(DEFAULT_SENDER) + runProcess(newTestContextBuilder(t). + withAccount(addr1, 100000000000000). + withCode(DEFAULT_SENDER, createAccountCode(), 1000000000000000000). + build(), []*types.Rip7560AccountAbstractionTx{ + { + Sender: &Sender, + ValidationGas: uint64(1000000000), + GasFeeCap: big.NewInt(1000000000), + Data: []byte{1, 2, 3}, + }, + }) +} + +// run a set of AA transactions, with a legacy TXs before and after. +func runProcess(t *testContext, aatxs []*types.Rip7560AccountAbstractionTx) error { + var db ethdb.Database = rawdb.NewMemoryDatabase() + var state = tests.MakePreState(db, t.genesisAlloc, false, rawdb.HashScheme) + defer state.Close() + + cacheConfig := &core.CacheConfig{} + chainOverrides := core.ChainOverrides{} + engine := beacon.New(ethash.NewFaker()) + lookupLimit := uint64(0) + blockchain, err := core.NewBlockChain(db, cacheConfig, t.genesis, &chainOverrides, engine, + vm.Config{}, shouldPreserve, &lookupLimit) + if err != nil { + t.t.Fatalf("NewBlockChain failed: %v", err) + } + + signer := types.MakeSigner(blockchain.Config(), new(big.Int), 0) + key1, _ := crypto.HexToECDSA(privKey1) + if crypto.PubkeyToAddress(key1.PublicKey) != common.HexToAddress(addr1) { + t.t.Fatalf("sanity: addr1 doesn't match privKey1: should be %s", crypto.PubkeyToAddress(key1.PublicKey)) + } + //addr1 := crypto.PubkeyToAddress(key1.PublicKey) + + key2, _ := crypto.HexToECDSA(privKey2) + addr2 := crypto.PubkeyToAddress(key2.PublicKey) + + tx1, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{ + Nonce: 0, + GasFeeCap: big.NewInt(1000000000), + Value: big.NewInt(1), + Gas: 30000, + To: &addr2, + }), signer, key1) + + tx3, _ := types.SignTx(types.NewTx(&types.DynamicFeeTx{ + Nonce: 1, + GasFeeCap: big.NewInt(1000000000), + Value: big.NewInt(2), + Gas: 30000, + To: &addr2, + }), signer, key1) + + txs := []*types.Transaction{tx1} + for _, aatx := range aatxs { + txs = append(txs, types.NewTx(aatx)) + } + txs = append(txs, tx3) + + b := types.NewBlock(blockchain.CurrentBlock(), txs, nil, nil, trie.NewStackTrie(nil)) + _, _, _, err = blockchain.Processor().Process(b, state.StateDB, vm.Config{}) + if err != nil { + return err + } + assert.Equal(t.t, "0x3", state.StateDB.GetBalance(addr2).Hex(), "failed to process pre/post legacy transactions") + return nil +} + +func shouldPreserve(*types.Header) bool { + return false +} diff --git a/tests/rip7560/rip7560TestUtils.go b/tests/rip7560/rip7560TestUtils.go index 9a330cbfc3..d891d4b223 100644 --- a/tests/rip7560/rip7560TestUtils.go +++ b/tests/rip7560/rip7560TestUtils.go @@ -109,6 +109,14 @@ func returnData(data []byte) []byte { return ret } +// create bytecode for account +func createAccountCode() []byte { + magic := big.NewInt(0xbf45c166) + magic.Lsh(magic, 256-32) + + return returnData(magic.Bytes()) +} + // create EVM code from OpCode, byte and []bytes func createCode(items ...interface{}) []byte { var buffer bytes.Buffer diff --git a/tests/rip7560/validation_test.go b/tests/rip7560/validation_test.go index 2ab9ca6490..357fc3a8e8 100644 --- a/tests/rip7560/validation_test.go +++ b/tests/rip7560/validation_test.go @@ -24,10 +24,8 @@ func TestValidation_OOG(t *testing.T) { } func TestValidation_ok(t *testing.T) { - magic := big.NewInt(0xbf45c166) - magic.Lsh(magic, 256-32) - validatePhase(newTestContextBuilder(t).withCode(DEFAULT_SENDER, returnData(magic.Bytes()), 0), types.Rip7560AccountAbstractionTx{ + validatePhase(newTestContextBuilder(t).withCode(DEFAULT_SENDER, createAccountCode(), 0), types.Rip7560AccountAbstractionTx{ ValidationGas: uint64(1000000000), GasFeeCap: big.NewInt(1000000000), }, "")