11"""Helper functions."""
22
33from dataclasses import dataclass
4- from typing import Dict , List
4+ from typing import Any , Dict , List
55
66import pytest
77
88from ethereum_clis import Result
99from ethereum_test_exceptions import ExceptionBase , ExceptionMapper , UndefinedException
10- from ethereum_test_types import Transaction
10+ from ethereum_test_types import Transaction , TransactionReceipt
1111
1212
1313class TransactionExpectedToFailSucceedError (Exception ):
@@ -70,12 +70,32 @@ def __init__(
7070 super ().__init__ (message )
7171
7272
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+
7393@dataclass
7494class TransactionExceptionInfo :
7595 """Info to print transaction exception error messages."""
7696
7797 t8n_error_message : str | None
78- transaction_ind : int
98+ transaction_index : int
7999 tx : Transaction
80100
81101
@@ -90,11 +110,11 @@ def verify_transaction_exception(
90110 # info.tx.error is expected error code defined in .py test
91111 if expected_error and not info .t8n_error_message :
92112 raise TransactionExpectedToFailSucceedError (
93- index = info .transaction_ind , nonce = info .tx .nonce
113+ index = info .transaction_index , nonce = info .tx .nonce
94114 )
95115 elif not expected_error and info .t8n_error_message :
96116 raise TransactionUnexpectedFailError (
97- index = info .transaction_ind ,
117+ index = info .transaction_index ,
98118 nonce = info .tx .nonce ,
99119 message = info .t8n_error_message ,
100120 exception = exception_mapper .message_to_exception (info .t8n_error_message ),
@@ -122,7 +142,7 @@ def verify_transaction_exception(
122142
123143 if expected_error_msg is None or expected_error_msg not in info .t8n_error_message :
124144 raise TransactionExceptionMismatchError (
125- index = info .transaction_ind ,
145+ index = info .transaction_index ,
126146 nonce = info .tx .nonce ,
127147 expected_exception = expected_exception ,
128148 expected_message = expected_error_msg ,
@@ -132,21 +152,60 @@ def verify_transaction_exception(
132152 )
133153
134154
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+
135183def verify_transactions (
136- exception_mapper : ExceptionMapper , txs : List [Transaction ], result : Result
184+ * ,
185+ txs : List [Transaction ],
186+ exception_mapper : ExceptionMapper ,
187+ result : Result ,
137188) -> List [int ]:
138189 """
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.
141193 """
142194 rejected_txs : Dict [int , str ] = {
143195 rejected_tx .index : rejected_tx .error for rejected_tx in result .rejected_transactions
144196 }
145197
198+ receipt_index = 0
146199 for i , tx in enumerate (txs ):
147200 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 )
150209
151210 return list (rejected_txs .keys ())
152211
0 commit comments