@@ -21,93 +21,120 @@ import (
2121
2222 "github.com/ethereum/go-ethereum/common"
2323 "github.com/ethereum/go-ethereum/common/hexutil"
24+ "github.com/ethereum/go-ethereum/common/math"
2425 "github.com/ethereum/go-ethereum/core"
2526 "github.com/ethereum/go-ethereum/core/types"
2627 "github.com/ethereum/go-ethereum/params"
27- "github.com/ethereum/go-ethereum/rlp"
2828)
2929
3030// TransactionTest checks RLP decoding and sender derivation of transactions.
3131type TransactionTest struct {
3232 Txbytes hexutil.Bytes `json:"txbytes"`
33- Result ttResult
33+ Result map [ string ] * ttFork
3434}
3535
36- type ttResult struct {
37- Byzantium ttFork
38- Constantinople ttFork
39- Istanbul ttFork
40- EIP150 ttFork
41- EIP158 ttFork
42- Frontier ttFork
43- Homestead ttFork
36+ type ttFork struct {
37+ Sender * common.UnprefixedAddress `json:"sender"`
38+ Hash * common.UnprefixedHash `json:"hash"`
39+ Exception * string `json:"exception"`
40+ IntrinsicGas math.HexOrDecimal64 `json:"intrinsicGas"`
4441}
4542
46- type ttFork struct {
47- Sender common.UnprefixedAddress `json:"sender"`
48- Hash common.UnprefixedHash `json:"hash"`
43+ func (tt * TransactionTest ) validate () error {
44+ if tt .Txbytes == nil {
45+ return fmt .Errorf ("missing txbytes" )
46+ }
47+ for name , fork := range tt .Result {
48+ if err := tt .validateFork (fork ); err != nil {
49+ return fmt .Errorf ("invalid %s: %v" , name , err )
50+ }
51+ }
52+ return nil
53+ }
54+
55+ func (tt * TransactionTest ) validateFork (fork * ttFork ) error {
56+ if fork == nil {
57+ return nil
58+ }
59+ if fork .Hash == nil && fork .Exception == nil {
60+ return fmt .Errorf ("missing hash and exception" )
61+ }
62+ if fork .Hash != nil && fork .Sender == nil {
63+ return fmt .Errorf ("missing sender" )
64+ }
65+ return nil
4966}
5067
5168func (tt * TransactionTest ) Run (config * params.ChainConfig ) error {
52- validateTx := func (rlpData hexutil.Bytes , signer types.Signer , isHomestead bool , isIstanbul bool ) (* common.Address , * common.Hash , error ) {
69+ if err := tt .validate (); err != nil {
70+ return err
71+ }
72+ validateTx := func (rlpData hexutil.Bytes , signer types.Signer , isHomestead , isIstanbul , isShanghai bool ) (sender common.Address , hash common.Hash , requiredGas uint64 , err error ) {
5373 tx := new (types.Transaction )
54- if err := rlp . DecodeBytes (rlpData , tx ); err != nil {
55- return nil , nil , err
74+ if err = tx . UnmarshalBinary (rlpData ); err != nil {
75+ return
5676 }
57- sender , err : = types .Sender (signer , tx )
77+ sender , err = types .Sender (signer , tx )
5878 if err != nil {
59- return nil , nil , err
79+ return
6080 }
6181 // Intrinsic gas
62- requiredGas , err : = core .IntrinsicGas (tx .Data (), tx .AccessList (), tx .SetCodeAuthorizations (), tx .To () == nil , isHomestead , isIstanbul , false )
82+ requiredGas , err = core .IntrinsicGas (tx .Data (), tx .AccessList (), tx .SetCodeAuthorizations (), tx .To () == nil , isHomestead , isIstanbul , isShanghai )
6383 if err != nil {
64- return nil , nil , err
84+ return
6585 }
6686 if requiredGas > tx .Gas () {
67- return nil , nil , fmt .Errorf ("insufficient gas ( %d < %d )" , tx .Gas (), requiredGas )
87+ return sender , hash , 0 , fmt .Errorf ("insufficient gas ( %d < %d )" , tx .Gas (), requiredGas )
6888 }
69- h : = tx .Hash ()
70- return & sender , & h , nil
89+ hash = tx .Hash ()
90+ return sender , hash , requiredGas , nil
7191 }
72-
7392 for _ , testcase := range []struct {
7493 name string
7594 signer types.Signer
76- fork ttFork
95+ fork * ttFork
7796 isHomestead bool
7897 isIstanbul bool
98+ isShanghai bool
7999 }{
80- {"Frontier" , types.FrontierSigner {}, tt .Result .Frontier , false , false },
81- {"Homestead" , types.HomesteadSigner {}, tt .Result .Homestead , true , false },
82- {"EIP150" , types.HomesteadSigner {}, tt .Result .EIP150 , true , false },
83- {"EIP158" , types .NewEIP155Signer (config .ChainID ), tt .Result .EIP158 , true , false },
84- {"Byzantium" , types .NewEIP155Signer (config .ChainID ), tt .Result .Byzantium , true , false },
85- {"Constantinople" , types .NewEIP155Signer (config .ChainID ), tt .Result .Constantinople , true , false },
86- {"Istanbul" , types .NewEIP155Signer (config .ChainID ), tt .Result .Istanbul , true , true },
100+ {"Frontier" , types.FrontierSigner {}, tt .Result ["Frontier" ], false , false , false },
101+ {"Homestead" , types.HomesteadSigner {}, tt .Result ["Homestead" ], true , false , false },
102+ {"EIP150" , types.HomesteadSigner {}, tt .Result ["EIP150" ], true , false , false },
103+ {"EIP158" , types .NewEIP155Signer (config .ChainID ), tt .Result ["EIP158" ], true , false , false },
104+ {"Byzantium" , types .NewEIP155Signer (config .ChainID ), tt .Result ["Byzantium" ], true , false , false },
105+ {"Constantinople" , types .NewEIP155Signer (config .ChainID ), tt .Result ["Constantinople" ], true , false , false },
106+ {"Istanbul" , types .NewEIP155Signer (config .ChainID ), tt .Result ["Istanbul" ], true , true , false },
107+ {"Berlin" , types .NewEIP2930Signer (config .ChainID ), tt .Result ["Berlin" ], true , true , false },
108+ {"London" , types .NewLondonSigner (config .ChainID ), tt .Result ["London" ], true , true , false },
109+ {"Paris" , types .NewLondonSigner (config .ChainID ), tt .Result ["Paris" ], true , true , false },
110+ {"Shanghai" , types .NewLondonSigner (config .ChainID ), tt .Result ["Shanghai" ], true , true , true },
111+ {"Cancun" , types .NewCancunSigner (config .ChainID ), tt .Result ["Cancun" ], true , true , true },
112+ {"Prague" , types .NewPragueSigner (config .ChainID ), tt .Result ["Prague" ], true , true , true },
87113 } {
88- sender , txhash , err := validateTx (tt .Txbytes , testcase .signer , testcase .isHomestead , testcase .isIstanbul )
89-
90- if testcase .fork .Sender == (common.UnprefixedAddress {}) {
91- if err == nil {
92- return fmt .Errorf ("expected error, got none (address %v)[%v]" , sender .String (), testcase .name )
93- }
114+ if testcase .fork == nil {
94115 continue
95116 }
96- // Should resolve the right address
117+ sender , hash , gas , err := validateTx ( tt . Txbytes , testcase . signer , testcase . isHomestead , testcase . isIstanbul , testcase . isShanghai )
97118 if err != nil {
98- return fmt .Errorf ("got error, expected none: %v" , err )
119+ if testcase .fork .Hash != nil {
120+ return fmt .Errorf ("unexpected error: %v" , err )
121+ }
122+ continue
123+ }
124+ if testcase .fork .Exception != nil {
125+ return fmt .Errorf ("expected error %v, got none (%v)" , * testcase .fork .Exception , err )
99126 }
100- if sender == nil {
101- return fmt .Errorf ("sender was nil, should be %x" , common .Address ( testcase .fork .Sender ))
127+ if common . Hash ( * testcase . fork . Hash ) != hash {
128+ return fmt .Errorf ("hash mismatch: got %x, want %x" , hash , common .Hash ( * testcase .fork .Hash ))
102129 }
103- if * sender != common .Address (testcase .fork .Sender ) {
130+ if common .Address (* testcase .fork .Sender ) != sender {
104131 return fmt .Errorf ("sender mismatch: got %x, want %x" , sender , testcase .fork .Sender )
105132 }
106- if txhash == nil {
107- return fmt .Errorf ("txhash was nil, should be %x" , common . Hash ( testcase .fork .Hash ) )
133+ if hash != common . Hash ( * testcase . fork . Hash ) {
134+ return fmt .Errorf ("hash mismatch: got %x, want %x" , hash , testcase .fork .Hash )
108135 }
109- if * txhash != common . Hash (testcase .fork .Hash ) {
110- return fmt .Errorf ("hash mismatch: got %x , want %x " , * txhash , testcase .fork .Hash )
136+ if uint64 (testcase .fork .IntrinsicGas ) != gas {
137+ return fmt .Errorf ("intrinsic gas mismatch: got %d , want %d " , gas , uint64 ( testcase .fork .IntrinsicGas ) )
111138 }
112139 }
113140 return nil
0 commit comments