github.com/baptiste-b-pegasys/quorum/v22@v22.4.2/core/types/transaction_test.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package types
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/ecdsa"
    22  	"encoding/json"
    23  	"fmt"
    24  	"math/big"
    25  	"reflect"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/ethereum/go-ethereum/common"
    30  	"github.com/ethereum/go-ethereum/crypto"
    31  	"github.com/ethereum/go-ethereum/rlp"
    32  )
    33  
    34  // The values in those tests are from the Transaction Tests
    35  // at github.com/ethereum/tests.
    36  var (
    37  	testAddr = common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b")
    38  
    39  	emptyTx = NewTransaction(
    40  		0,
    41  		common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"),
    42  		big.NewInt(0), 0, big.NewInt(0),
    43  		nil,
    44  	)
    45  
    46  	rightvrsTx, _ = NewTransaction(
    47  		3,
    48  		testAddr,
    49  		big.NewInt(10),
    50  		2000,
    51  		big.NewInt(1),
    52  		common.FromHex("5544"),
    53  	).WithSignature(
    54  		HomesteadSigner{},
    55  		common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
    56  	)
    57  
    58  	rightvrsTx2, _ = NewTransaction(
    59  		3,
    60  		common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"),
    61  		big.NewInt(10),
    62  		2000,
    63  		big.NewInt(0),
    64  		common.FromHex("5544"),
    65  	).WithSignature(
    66  		HomesteadSigner{},
    67  		common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"),
    68  	)
    69  
    70  	emptyEip2718Tx = NewTx(&AccessListTx{
    71  		ChainID:  big.NewInt(1),
    72  		Nonce:    3,
    73  		To:       &testAddr,
    74  		Value:    big.NewInt(10),
    75  		Gas:      25000,
    76  		GasPrice: big.NewInt(1),
    77  		Data:     common.FromHex("5544"),
    78  	})
    79  
    80  	signedEip2718Tx, _ = emptyEip2718Tx.WithSignature(
    81  		NewEIP2930Signer(big.NewInt(1)),
    82  		common.Hex2Bytes("c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b266032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d3752101"),
    83  	)
    84  )
    85  
    86  func TestDecodeEmptyTypedTx(t *testing.T) {
    87  	input := []byte{0x80}
    88  	var tx Transaction
    89  	err := rlp.DecodeBytes(input, &tx)
    90  	if err != errEmptyTypedTx {
    91  		t.Fatal("wrong error:", err)
    92  	}
    93  }
    94  
    95  func TestTransactionSigHash(t *testing.T) {
    96  	var homestead HomesteadSigner
    97  	if homestead.Hash(emptyTx) != common.HexToHash("c775b99e7ad12f50d819fcd602390467e28141316969f4b57f0626f74fe3b386") {
    98  		t.Errorf("empty transaction hash mismatch, got %x", emptyTx.Hash())
    99  	}
   100  	if homestead.Hash(rightvrsTx) != common.HexToHash("fe7a79529ed5f7c3375d06b26b186a8644e0e16c373d7a12be41c62d6042b77a") {
   101  		t.Errorf("RightVRS transaction hash mismatch, got %x", rightvrsTx.Hash())
   102  	}
   103  }
   104  
   105  func TestTransactionEncode(t *testing.T) {
   106  	txb, err := rlp.EncodeToBytes(rightvrsTx)
   107  	if err != nil {
   108  		t.Fatalf("encode error: %v", err)
   109  	}
   110  	should := common.FromHex("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3")
   111  	if !bytes.Equal(txb, should) {
   112  		t.Errorf("encoded RLP mismatch, got %x", txb)
   113  	}
   114  }
   115  
   116  // Test from the original quorum implementation
   117  func TestTransactionEncode2(t *testing.T) {
   118  	txb, err := rlp.EncodeToBytes(rightvrsTx2)
   119  	if err != nil {
   120  		t.Fatalf("encode error: %v", err)
   121  	}
   122  	should := common.FromHex("f86103808207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3")
   123  	if !bytes.Equal(txb, should) {
   124  		t.Errorf("encoded RLP mismatch, got %x", txb)
   125  	}
   126  }
   127  
   128  func TestEIP2718TransactionSigHash(t *testing.T) {
   129  	s := NewEIP2930Signer(big.NewInt(1))
   130  	if s.Hash(emptyEip2718Tx) != common.HexToHash("49b486f0ec0a60dfbbca2d30cb07c9e8ffb2a2ff41f29a1ab6737475f6ff69f3") {
   131  		t.Errorf("empty EIP-2718 transaction hash mismatch, got %x", s.Hash(emptyEip2718Tx))
   132  	}
   133  	if s.Hash(signedEip2718Tx) != common.HexToHash("49b486f0ec0a60dfbbca2d30cb07c9e8ffb2a2ff41f29a1ab6737475f6ff69f3") {
   134  		t.Errorf("signed EIP-2718 transaction hash mismatch, got %x", s.Hash(signedEip2718Tx))
   135  	}
   136  }
   137  
   138  // This test checks signature operations on access list transactions.
   139  func TestEIP2930Signer(t *testing.T) {
   140  
   141  	var (
   142  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   143  		keyAddr = crypto.PubkeyToAddress(key.PublicKey)
   144  		signer1 = NewEIP2930Signer(big.NewInt(1))
   145  		signer2 = NewEIP2930Signer(big.NewInt(2))
   146  		tx0     = NewTx(&AccessListTx{Nonce: 1})
   147  		tx1     = NewTx(&AccessListTx{ChainID: big.NewInt(1), Nonce: 1})
   148  		tx2, _  = SignNewTx(key, signer2, &AccessListTx{ChainID: big.NewInt(2), Nonce: 1})
   149  	)
   150  
   151  	tests := []struct {
   152  		tx             *Transaction
   153  		signer         Signer
   154  		wantSignerHash common.Hash
   155  		wantSenderErr  error
   156  		wantSignErr    error
   157  		wantHash       common.Hash // after signing
   158  	}{
   159  		{
   160  			tx:             tx0,
   161  			signer:         signer1,
   162  			wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"),
   163  			wantSenderErr:  ErrInvalidChainId,
   164  			wantHash:       common.HexToHash("1ccd12d8bbdb96ea391af49a35ab641e219b2dd638dea375f2bc94dd290f2549"),
   165  		},
   166  		{
   167  			tx:             tx1,
   168  			signer:         signer1,
   169  			wantSenderErr:  ErrInvalidSig,
   170  			wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"),
   171  			wantHash:       common.HexToHash("1ccd12d8bbdb96ea391af49a35ab641e219b2dd638dea375f2bc94dd290f2549"),
   172  		},
   173  		{
   174  			// This checks what happens when trying to sign an unsigned tx for the wrong chain.
   175  			tx:             tx1,
   176  			signer:         signer2,
   177  			wantSenderErr:  ErrInvalidChainId,
   178  			wantSignerHash: common.HexToHash("367967247499343401261d718ed5aa4c9486583e4d89251afce47f4a33c33362"),
   179  			wantSignErr:    ErrInvalidChainId,
   180  		},
   181  		{
   182  			// This checks what happens when trying to re-sign a signed tx for the wrong chain.
   183  			tx:             tx2,
   184  			signer:         signer1,
   185  			wantSenderErr:  ErrInvalidChainId,
   186  			wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"),
   187  			wantSignErr:    ErrInvalidChainId,
   188  		},
   189  	}
   190  
   191  	for i, test := range tests {
   192  		sigHash := test.signer.Hash(test.tx)
   193  		if sigHash != test.wantSignerHash {
   194  			t.Errorf("test %d: wrong sig hash: got %x, want %x", i, sigHash, test.wantSignerHash)
   195  		}
   196  		sender, err := Sender(test.signer, test.tx)
   197  		if err != test.wantSenderErr {
   198  			t.Errorf("test %d: wrong Sender error %q", i, err)
   199  		}
   200  		if err == nil && sender != keyAddr {
   201  			t.Errorf("test %d: wrong sender address %x", i, sender)
   202  		}
   203  		signedTx, err := SignTx(test.tx, test.signer, key)
   204  		if err != test.wantSignErr {
   205  			t.Fatalf("test %d: wrong SignTx error %q", i, err)
   206  		}
   207  		if signedTx != nil {
   208  			if signedTx.Hash() != test.wantHash {
   209  				t.Errorf("test %d: wrong tx hash after signing: got %x, want %x", i, signedTx.Hash(), test.wantHash)
   210  			}
   211  		}
   212  	}
   213  }
   214  
   215  func TestEIP2718TransactionEncode(t *testing.T) {
   216  	// RLP representation
   217  	{
   218  		have, err := rlp.EncodeToBytes(signedEip2718Tx)
   219  		if err != nil {
   220  			t.Fatalf("encode error: %v", err)
   221  		}
   222  		want := common.FromHex("b86601f8630103018261a894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544c001a0c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b2660a032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d37521")
   223  		if !bytes.Equal(have, want) {
   224  			t.Errorf("encoded RLP mismatch, got %x", have)
   225  		}
   226  	}
   227  	// Binary representation
   228  	{
   229  		have, err := signedEip2718Tx.MarshalBinary()
   230  		if err != nil {
   231  			t.Fatalf("encode error: %v", err)
   232  		}
   233  		want := common.FromHex("01f8630103018261a894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544c001a0c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b2660a032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d37521")
   234  		if !bytes.Equal(have, want) {
   235  			t.Errorf("encoded RLP mismatch, got %x", have)
   236  		}
   237  	}
   238  }
   239  
   240  func decodeTx(data []byte) (*Transaction, error) {
   241  	var tx Transaction
   242  	t, err := &tx, rlp.Decode(bytes.NewReader(data), &tx)
   243  	return t, err
   244  }
   245  
   246  func defaultTestKey() (*ecdsa.PrivateKey, common.Address) {
   247  	key, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8")
   248  	addr := crypto.PubkeyToAddress(key.PublicKey)
   249  	return key, addr
   250  }
   251  
   252  func TestRecipientEmpty(t *testing.T) {
   253  	_, addr := defaultTestKey()
   254  	tx, err := decodeTx(common.Hex2Bytes("f8498080808080011ca09b16de9d5bdee2cf56c28d16275a4da68cd30273e2525f3959f5d62557489921a0372ebd8fb3345f7db7b5a86d42e24d36e983e259b0664ceb8c227ec9af572f3d"))
   255  	if err != nil {
   256  		t.Fatal(err)
   257  	}
   258  
   259  	from, err := Sender(HomesteadSigner{}, tx)
   260  	if err != nil {
   261  		t.Fatal(err)
   262  	}
   263  	if addr != from {
   264  		t.Fatal("derived address doesn't match")
   265  	}
   266  }
   267  
   268  func TestRecipientNormal(t *testing.T) {
   269  	_, addr := defaultTestKey()
   270  
   271  	tx, err := decodeTx(common.Hex2Bytes("f85d80808094000000000000000000000000000000000000000080011ca0527c0d8f5c63f7b9f41324a7c8a563ee1190bcbf0dac8ab446291bdbf32f5c79a0552c4ef0a09a04395074dab9ed34d3fbfb843c2f2546cc30fe89ec143ca94ca6"))
   272  	if err != nil {
   273  		t.Fatal(err)
   274  	}
   275  
   276  	from, err := Sender(HomesteadSigner{}, tx)
   277  	if err != nil {
   278  		t.Fatal(err)
   279  	}
   280  	if addr != from {
   281  		t.Fatal("derived address doesn't match")
   282  	}
   283  }
   284  
   285  // Tests that transactions can be correctly sorted according to their price in
   286  // decreasing order, but at the same time with increasing nonces when issued by
   287  // the same account.
   288  func TestTransactionPriceNonceSort(t *testing.T) {
   289  	// Generate a batch of accounts to start with
   290  	keys := make([]*ecdsa.PrivateKey, 25)
   291  	for i := 0; i < len(keys); i++ {
   292  		keys[i], _ = crypto.GenerateKey()
   293  	}
   294  	signer := HomesteadSigner{}
   295  
   296  	// Generate a batch of transactions with overlapping values, but shifted nonces
   297  	groups := map[common.Address]Transactions{}
   298  	for start, key := range keys {
   299  		addr := crypto.PubkeyToAddress(key.PublicKey)
   300  		for i := 0; i < 25; i++ {
   301  			tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil), signer, key)
   302  			groups[addr] = append(groups[addr], tx)
   303  		}
   304  	}
   305  	// Sort the transactions and cross check the nonce ordering
   306  	txset := NewTransactionsByPriceAndNonce(signer, groups)
   307  
   308  	txs := Transactions{}
   309  	for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
   310  		txs = append(txs, tx)
   311  		txset.Shift()
   312  	}
   313  	if len(txs) != 25*25 {
   314  		t.Errorf("expected %d transactions, found %d", 25*25, len(txs))
   315  	}
   316  	for i, txi := range txs {
   317  		fromi, _ := Sender(signer, txi)
   318  
   319  		// Make sure the nonce order is valid
   320  		for j, txj := range txs[i+1:] {
   321  			fromj, _ := Sender(signer, txj)
   322  			if fromi == fromj && txi.Nonce() > txj.Nonce() {
   323  				t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce())
   324  			}
   325  		}
   326  		// If the next tx has different from account, the price must be lower than the current one
   327  		if i+1 < len(txs) {
   328  			next := txs[i+1]
   329  			fromNext, _ := Sender(signer, next)
   330  			if fromi != fromNext && txi.GasPrice().Cmp(next.GasPrice()) < 0 {
   331  				t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
   332  			}
   333  		}
   334  	}
   335  }
   336  
   337  // Tests that if multiple transactions have the same price, the ones seen earlier
   338  // are prioritized to avoid network spam attacks aiming for a specific ordering.
   339  func TestTransactionTimeSort(t *testing.T) {
   340  	// Generate a batch of accounts to start with
   341  	keys := make([]*ecdsa.PrivateKey, 5)
   342  	for i := 0; i < len(keys); i++ {
   343  		keys[i], _ = crypto.GenerateKey()
   344  	}
   345  	signer := HomesteadSigner{}
   346  
   347  	// Generate a batch of transactions with overlapping prices, but different creation times
   348  	groups := map[common.Address]Transactions{}
   349  	for start, key := range keys {
   350  		addr := crypto.PubkeyToAddress(key.PublicKey)
   351  
   352  		tx, _ := SignTx(NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key)
   353  		tx.time = time.Unix(0, int64(len(keys)-start))
   354  
   355  		groups[addr] = append(groups[addr], tx)
   356  	}
   357  	// Sort the transactions and cross check the nonce ordering
   358  	txset := NewTransactionsByPriceAndNonce(signer, groups)
   359  
   360  	txs := Transactions{}
   361  	for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
   362  		txs = append(txs, tx)
   363  		txset.Shift()
   364  	}
   365  	if len(txs) != len(keys) {
   366  		t.Errorf("expected %d transactions, found %d", len(keys), len(txs))
   367  	}
   368  	for i, txi := range txs {
   369  		fromi, _ := Sender(signer, txi)
   370  		if i+1 < len(txs) {
   371  			next := txs[i+1]
   372  			fromNext, _ := Sender(signer, next)
   373  
   374  			if txi.GasPrice().Cmp(next.GasPrice()) < 0 {
   375  				t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
   376  			}
   377  			// Make sure time order is ascending if the txs have the same gas price
   378  			if txi.GasPrice().Cmp(next.GasPrice()) == 0 && txi.time.After(next.time) {
   379  				t.Errorf("invalid received time ordering: tx #%d (A=%x T=%v) > tx #%d (A=%x T=%v)", i, fromi[:4], txi.time, i+1, fromNext[:4], next.time)
   380  			}
   381  		}
   382  	}
   383  }
   384  
   385  // TestTransactionCoding tests serializing/de-serializing to/from rlp and JSON.
   386  func TestTransactionCoding(t *testing.T) {
   387  	key, err := crypto.GenerateKey()
   388  	if err != nil {
   389  		t.Fatalf("could not generate key: %v", err)
   390  	}
   391  	var (
   392  		signer    = NewEIP2930Signer(common.Big1)
   393  		addr      = common.HexToAddress("0x0000000000000000000000000000000000000001")
   394  		recipient = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
   395  		accesses  = AccessList{{Address: addr, StorageKeys: []common.Hash{{0}}}}
   396  	)
   397  	for i := uint64(0); i < 500; i++ {
   398  		var txdata TxData
   399  		switch i % 5 {
   400  		case 0:
   401  			// Legacy tx.
   402  			txdata = &LegacyTx{
   403  				Nonce:    i,
   404  				To:       &recipient,
   405  				Gas:      1,
   406  				GasPrice: big.NewInt(2),
   407  				Data:     []byte("abcdef"),
   408  			}
   409  		case 1:
   410  			// Legacy tx contract creation.
   411  			txdata = &LegacyTx{
   412  				Nonce:    i,
   413  				Gas:      1,
   414  				GasPrice: big.NewInt(2),
   415  				Data:     []byte("abcdef"),
   416  			}
   417  		case 2:
   418  			// Tx with non-zero access list.
   419  			txdata = &AccessListTx{
   420  				ChainID:    big.NewInt(1),
   421  				Nonce:      i,
   422  				To:         &recipient,
   423  				Gas:        123457,
   424  				GasPrice:   big.NewInt(10),
   425  				AccessList: accesses,
   426  				Data:       []byte("abcdef"),
   427  			}
   428  		case 3:
   429  			// Tx with empty access list.
   430  			txdata = &AccessListTx{
   431  				ChainID:  big.NewInt(1),
   432  				Nonce:    i,
   433  				To:       &recipient,
   434  				Gas:      123457,
   435  				GasPrice: big.NewInt(10),
   436  				Data:     []byte("abcdef"),
   437  			}
   438  		case 4:
   439  			// Contract creation with access list.
   440  			txdata = &AccessListTx{
   441  				ChainID:    big.NewInt(1),
   442  				Nonce:      i,
   443  				Gas:        123457,
   444  				GasPrice:   big.NewInt(10),
   445  				AccessList: accesses,
   446  			}
   447  		}
   448  		tx, err := SignNewTx(key, signer, txdata)
   449  		if err != nil {
   450  			t.Fatalf("could not sign transaction: %v", err)
   451  		}
   452  		// RLP
   453  		parsedTx, err := encodeDecodeBinary(tx)
   454  		if err != nil {
   455  			t.Fatal(err)
   456  		}
   457  		assertEqual(parsedTx, tx)
   458  
   459  		// JSON
   460  		parsedTx, err = encodeDecodeJSON(tx)
   461  		if err != nil {
   462  			t.Fatal(err)
   463  		}
   464  		assertEqual(parsedTx, tx)
   465  	}
   466  }
   467  
   468  func encodeDecodeJSON(tx *Transaction) (*Transaction, error) {
   469  	data, err := json.Marshal(tx)
   470  	if err != nil {
   471  		return nil, fmt.Errorf("json encoding failed: %v", err)
   472  	}
   473  	var parsedTx = &Transaction{}
   474  	if err := json.Unmarshal(data, &parsedTx); err != nil {
   475  		return nil, fmt.Errorf("json decoding failed: %v", err)
   476  	}
   477  	return parsedTx, nil
   478  }
   479  
   480  func encodeDecodeBinary(tx *Transaction) (*Transaction, error) {
   481  	data, err := tx.MarshalBinary()
   482  	if err != nil {
   483  		return nil, fmt.Errorf("rlp encoding failed: %v", err)
   484  	}
   485  	var parsedTx = &Transaction{}
   486  	if err := parsedTx.UnmarshalBinary(data); err != nil {
   487  		return nil, fmt.Errorf("rlp decoding failed: %v", err)
   488  	}
   489  	return parsedTx, nil
   490  }
   491  
   492  func assertEqual(orig *Transaction, cpy *Transaction) error {
   493  	// compare nonce, price, gaslimit, recipient, amount, payload, V, R, S
   494  	if want, got := orig.Hash(), cpy.Hash(); want != got {
   495  		return fmt.Errorf("parsed tx differs from original tx, want %v, got %v", want, got)
   496  	}
   497  	if want, got := orig.ChainId(), cpy.ChainId(); want.Cmp(got) != 0 {
   498  		return fmt.Errorf("invalid chain id, want %d, got %d", want, got)
   499  	}
   500  	if orig.AccessList() != nil {
   501  		if !reflect.DeepEqual(orig.AccessList(), cpy.AccessList()) {
   502  			return fmt.Errorf("access list wrong!")
   503  		}
   504  	}
   505  	return nil
   506  }