@@ -21,93 +21,120 @@ import (
21
21
22
22
"github.com/ethereum/go-ethereum/common"
23
23
"github.com/ethereum/go-ethereum/common/hexutil"
24
+ "github.com/ethereum/go-ethereum/common/math"
24
25
"github.com/ethereum/go-ethereum/core"
25
26
"github.com/ethereum/go-ethereum/core/types"
26
27
"github.com/ethereum/go-ethereum/params"
27
- "github.com/ethereum/go-ethereum/rlp"
28
28
)
29
29
30
30
// TransactionTest checks RLP decoding and sender derivation of transactions.
31
31
type TransactionTest struct {
32
32
Txbytes hexutil.Bytes `json:"txbytes"`
33
- Result ttResult
33
+ Result map [ string ] * ttFork
34
34
}
35
35
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"`
44
41
}
45
42
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
49
66
}
50
67
51
68
func (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 ) {
53
73
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
56
76
}
57
- sender , err : = types .Sender (signer , tx )
77
+ sender , err = types .Sender (signer , tx )
58
78
if err != nil {
59
- return nil , nil , err
79
+ return
60
80
}
61
81
// 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 )
63
83
if err != nil {
64
- return nil , nil , err
84
+ return
65
85
}
66
86
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 )
68
88
}
69
- h : = tx .Hash ()
70
- return & sender , & h , nil
89
+ hash = tx .Hash ()
90
+ return sender , hash , requiredGas , nil
71
91
}
72
-
73
92
for _ , testcase := range []struct {
74
93
name string
75
94
signer types.Signer
76
- fork ttFork
95
+ fork * ttFork
77
96
isHomestead bool
78
97
isIstanbul bool
98
+ isShanghai bool
79
99
}{
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 },
87
113
} {
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 {
94
115
continue
95
116
}
96
- // Should resolve the right address
117
+ sender , hash , gas , err := validateTx ( tt . Txbytes , testcase . signer , testcase . isHomestead , testcase . isIstanbul , testcase . isShanghai )
97
118
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 )
99
126
}
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 ))
102
129
}
103
- if * sender != common .Address (testcase .fork .Sender ) {
130
+ if common .Address (* testcase .fork .Sender ) != sender {
104
131
return fmt .Errorf ("sender mismatch: got %x, want %x" , sender , testcase .fork .Sender )
105
132
}
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 )
108
135
}
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 ) )
111
138
}
112
139
}
113
140
return nil
0 commit comments