1
1
"""Helper functions."""
2
2
3
3
from dataclasses import dataclass
4
- from typing import Dict , List
4
+ from typing import Any , Dict , List
5
5
6
6
import pytest
7
7
8
8
from ethereum_clis import Result
9
9
from ethereum_test_exceptions import ExceptionBase , ExceptionMapper , UndefinedException
10
- from ethereum_test_types import Transaction
10
+ from ethereum_test_types import Transaction , TransactionReceipt
11
11
12
12
13
13
class TransactionExpectedToFailSucceedError (Exception ):
@@ -70,12 +70,32 @@ def __init__(
70
70
super ().__init__ (message )
71
71
72
72
73
+ class TransactionReceiptMismatchError (Exception ):
74
+ """Exception used when the actual transaction receipt differs from the expected one."""
75
+
76
+ def __init__ (
77
+ self ,
78
+ index : int ,
79
+ field_name : str ,
80
+ expected_value : Any ,
81
+ actual_value : Any ,
82
+ ):
83
+ """Initialize the exception."""
84
+ message = (
85
+ f"\n TransactionReceiptMismatch (pos={ index } ):"
86
+ f"\n What: { field_name } mismatch!"
87
+ f"\n Want: { expected_value } "
88
+ f"\n Got: { actual_value } "
89
+ )
90
+ super ().__init__ (message )
91
+
92
+
73
93
@dataclass
74
94
class TransactionExceptionInfo :
75
95
"""Info to print transaction exception error messages."""
76
96
77
97
t8n_error_message : str | None
78
- transaction_ind : int
98
+ transaction_index : int
79
99
tx : Transaction
80
100
81
101
@@ -90,11 +110,11 @@ def verify_transaction_exception(
90
110
# info.tx.error is expected error code defined in .py test
91
111
if expected_error and not info .t8n_error_message :
92
112
raise TransactionExpectedToFailSucceedError (
93
- index = info .transaction_ind , nonce = info .tx .nonce
113
+ index = info .transaction_index , nonce = info .tx .nonce
94
114
)
95
115
elif not expected_error and info .t8n_error_message :
96
116
raise TransactionUnexpectedFailError (
97
- index = info .transaction_ind ,
117
+ index = info .transaction_index ,
98
118
nonce = info .tx .nonce ,
99
119
message = info .t8n_error_message ,
100
120
exception = exception_mapper .message_to_exception (info .t8n_error_message ),
@@ -122,7 +142,7 @@ def verify_transaction_exception(
122
142
123
143
if expected_error_msg is None or expected_error_msg not in info .t8n_error_message :
124
144
raise TransactionExceptionMismatchError (
125
- index = info .transaction_ind ,
145
+ index = info .transaction_index ,
126
146
nonce = info .tx .nonce ,
127
147
expected_exception = expected_exception ,
128
148
expected_message = expected_error_msg ,
@@ -132,21 +152,60 @@ def verify_transaction_exception(
132
152
)
133
153
134
154
155
+ def verify_transaction_receipt (
156
+ transaction_index : int ,
157
+ expected_receipt : TransactionReceipt | None ,
158
+ actual_receipt : TransactionReceipt | None ,
159
+ ):
160
+ """
161
+ Verify the actual receipt against the expected one.
162
+
163
+ If the expected receipt is None, validation is skipped.
164
+
165
+ Only verifies non-None values in the expected receipt if any.
166
+ """
167
+ if expected_receipt is None :
168
+ return
169
+ assert actual_receipt is not None
170
+ if (
171
+ expected_receipt .gas_used is not None
172
+ and actual_receipt .gas_used != expected_receipt .gas_used
173
+ ):
174
+ raise TransactionReceiptMismatchError (
175
+ index = transaction_index ,
176
+ field_name = "gas_used" ,
177
+ expected_value = expected_receipt .gas_used ,
178
+ actual_value = actual_receipt .gas_used ,
179
+ )
180
+ # TODO: Add more fields as needed
181
+
182
+
135
183
def verify_transactions (
136
- exception_mapper : ExceptionMapper , txs : List [Transaction ], result : Result
184
+ * ,
185
+ txs : List [Transaction ],
186
+ exception_mapper : ExceptionMapper ,
187
+ result : Result ,
137
188
) -> List [int ]:
138
189
"""
139
- Verify rejected transactions (if any) against the expected outcome.
140
- Raises exception on unexpected rejections or unexpected successful txs.
190
+ Verify accepted and rejected (if any) transactions against the expected outcome.
191
+ Raises exception on unexpected rejections, unexpected successful txs, or successful txs with
192
+ unexpected receipt values.
141
193
"""
142
194
rejected_txs : Dict [int , str ] = {
143
195
rejected_tx .index : rejected_tx .error for rejected_tx in result .rejected_transactions
144
196
}
145
197
198
+ receipt_index = 0
146
199
for i , tx in enumerate (txs ):
147
200
error_message = rejected_txs [i ] if i in rejected_txs else None
148
- info = TransactionExceptionInfo (t8n_error_message = error_message , transaction_ind = i , tx = tx )
149
- verify_transaction_exception (exception_mapper = exception_mapper , info = info )
201
+ if error_message is None :
202
+ verify_transaction_receipt (i , tx .expected_receipt , result .receipts [receipt_index ])
203
+ receipt_index += 1
204
+ else :
205
+ info = TransactionExceptionInfo (
206
+ t8n_error_message = error_message , transaction_index = i , tx = tx
207
+ )
208
+ verify_transaction_exception (exception_mapper = exception_mapper , info = info )
150
209
151
210
return list (rejected_txs .keys ())
152
211
0 commit comments