1717package core
1818
1919import (
20+ "bytes"
2021 "errors"
2122 "fmt"
2223 "io/ioutil"
@@ -30,6 +31,7 @@ import (
3031 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
3132 gokzg4844 "github.com/crate-crypto/go-kzg-4844"
3233 "github.com/ethereum/go-ethereum/common/math"
34+ "github.com/ethereum/go-ethereum/core/vm/program"
3335 "github.com/ethereum/go-ethereum/crypto/kzg4844"
3436 "github.com/ethereum/go-ethereum/eth/tracers/logger"
3537 lru "github.com/hashicorp/golang-lru/v2"
@@ -3442,7 +3444,7 @@ func testEIP2718Transition(t *testing.T, scheme string) {
34423444
34433445 // Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list
34443446 expected := params .TxGas + params .TxAccessListAddressGas + params .TxAccessListStorageKeyGas +
3445- vm .GasQuickStep * 2 + params .WarmStorageReadCostEIP2929 + params .ColdSloadCostEIP2929
3447+ vm .GasQuickStep * 2 + params .WarmStorageReadCostEIP2929 + params .ColdSloadCostEIP2929
34463448 if block .GasUsed () != expected {
34473449 t .Fatalf ("incorrect amount of gas spent: expected %d, got %d" , expected , block .GasUsed ())
34483450
@@ -3545,7 +3547,7 @@ func testEIP1559Transition(t *testing.T, scheme string) {
35453547
35463548 // 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
35473549 expectedGas := params .TxGas + params .TxAccessListAddressGas + params .TxAccessListStorageKeyGas +
3548- vm .GasQuickStep * 2 + params .WarmStorageReadCostEIP2929 + params .ColdSloadCostEIP2929
3550+ vm .GasQuickStep * 2 + params .WarmStorageReadCostEIP2929 + params .ColdSloadCostEIP2929
35493551 if block .GasUsed () != expectedGas {
35503552 t .Fatalf ("incorrect amount of gas spent: expected %d, got %d" , expectedGas , block .GasUsed ())
35513553 }
@@ -4739,3 +4741,95 @@ func TestDeleteThenCreate(t *testing.T) {
47394741 }
47404742 }
47414743}
4744+
4745+ // TestEIP7702 deploys two delegation designations and calls them. It writes one
4746+ // value to storage which is verified after.
4747+ func TestEIP7702 (t * testing.T ) {
4748+ var (
4749+ config = params .TestChainConfig
4750+ signer = types .LatestSigner (config )
4751+ engine = ethash .NewFaker ()
4752+ key1 , _ = crypto .HexToECDSA ("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" )
4753+ key2 , _ = crypto .HexToECDSA ("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a" )
4754+ addr1 = crypto .PubkeyToAddress (key1 .PublicKey )
4755+ addr2 = crypto .PubkeyToAddress (key2 .PublicKey )
4756+ aa = common .HexToAddress ("0x000000000000000000000000000000000000aaaa" )
4757+ bb = common .HexToAddress ("0x000000000000000000000000000000000000bbbb" )
4758+ funds = new (big.Int ).Mul (common .Big1 , big .NewInt (params .Ether ))
4759+ )
4760+ gspec := & Genesis {
4761+ Config : config ,
4762+ Alloc : GenesisAlloc {
4763+ addr1 : {Balance : funds },
4764+ addr2 : {Balance : funds },
4765+ aa : { // The address 0xAAAA calls into addr2
4766+ Code : program .New ().Call (nil , addr2 , 1 , 0 , 0 , 0 , 0 ).Bytes (),
4767+ Nonce : 0 ,
4768+ Balance : big .NewInt (0 ),
4769+ },
4770+ bb : { // The address 0xBBBB sstores 42 into slot 42.
4771+ Code : program .New ().Sstore (0x42 , 0x42 ).Bytes (),
4772+ Nonce : 0 ,
4773+ Balance : big .NewInt (0 ),
4774+ },
4775+ },
4776+ }
4777+
4778+ // Sign authorization tuples.
4779+ // The way the auths are combined, it becomes
4780+ // 1. tx -> addr1 which is delegated to 0xaaaa
4781+ // 2. addr1:0xaaaa calls into addr2:0xbbbb
4782+ // 3. addr2:0xbbbb writes to storage
4783+ auth1 , _ := types .SignAuth (types.Authorization {
4784+ ChainID : gspec .Config .ChainID .Uint64 (),
4785+ Address : aa ,
4786+ Nonce : 1 ,
4787+ }, key1 )
4788+ auth2 , _ := types .SignAuth (types.Authorization {
4789+ ChainID : 0 ,
4790+ Address : bb ,
4791+ Nonce : 0 ,
4792+ }, key2 )
4793+
4794+ _ , blocks , _ := GenerateChainWithGenesis (gspec , engine , 1 , func (i int , b * BlockGen ) {
4795+ b .SetCoinbase (aa )
4796+ txdata := & types.SetCodeTx {
4797+ ChainID : gspec .Config .ChainID .Uint64 (),
4798+ Nonce : 0 ,
4799+ To : addr1 ,
4800+ Gas : 500000 ,
4801+ GasFeeCap : uint256 .MustFromBig (newGwei (5 )),
4802+ GasTipCap : uint256 .NewInt (2 ),
4803+ AuthList : []types.Authorization {auth1 , auth2 },
4804+ }
4805+ tx := types .MustSignNewTx (key1 , signer , txdata )
4806+ b .AddTx (tx )
4807+ })
4808+ chain , err := NewBlockChain (rawdb .NewMemoryDatabase (), nil , gspec , nil , engine , vm.Config {}, nil , nil )
4809+ if err != nil {
4810+ t .Fatalf ("failed to create tester chain: %v" , err )
4811+ }
4812+ defer chain .Stop ()
4813+ if n , err := chain .InsertChain (blocks , nil ); err != nil {
4814+ t .Fatalf ("block %d: failed to insert into chain: %v" , n , err )
4815+ }
4816+
4817+ // Verify delegation designations were deployed.
4818+ state , _ := chain .State ()
4819+ code , want := state .GetCode (addr1 ), types .AddressToDelegation (auth1 .Address )
4820+ if ! bytes .Equal (code , want ) {
4821+ t .Fatalf ("addr1 code incorrect: got %s, want %s" , common .Bytes2Hex (code ), common .Bytes2Hex (want ))
4822+ }
4823+ code , want = state .GetCode (addr2 ), types .AddressToDelegation (auth2 .Address )
4824+ if ! bytes .Equal (code , want ) {
4825+ t .Fatalf ("addr2 code incorrect: got %s, want %s" , common .Bytes2Hex (code ), common .Bytes2Hex (want ))
4826+ }
4827+ // Verify delegation executed the correct code.
4828+ var (
4829+ fortyTwo = common .BytesToHash ([]byte {0x42 })
4830+ actual = state .GetState (addr2 , fortyTwo )
4831+ )
4832+ if actual .Cmp (fortyTwo ) != 0 {
4833+ t .Fatalf ("addr2 storage wrong: expected %d, got %d" , fortyTwo , actual )
4834+ }
4835+ }
0 commit comments