Skip to content

Commit d5e768c

Browse files
committed
fix: take has_genesis_hash and has_genesis_id into account for transactions in an algod Block
1 parent d3dcfc1 commit d5e768c

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

api/oas-generator/src/oas_generator/renderer/templates/models/block.py.j2

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,23 @@ class Block:
291291
decode=lambda raw: decode_model_sequence(lambda: SignedTxnInBlock, raw),
292292
),
293293
)
294-
294+
295+
def __post_init__(self) -> None:
296+
# populates genesis id and hash on transactions if required to ensure
297+
# tx id's are correct
298+
genesis_id = self.header.genesis_id
299+
genesis_hash = self.header.genesis_hash
300+
set_frozen_field = object.__setattr__
301+
for txn_in_block in self.payset or []:
302+
txn = txn_in_block.signed_transaction.signed_transaction.transaction
303+
304+
if txn_in_block.has_genesis_id and txn.genesis_id is None:
305+
set_frozen_field(txn, "genesis_id", genesis_id)
306+
307+
# the following assumes that Consensus.RequireGenesisHash is true
308+
# so assigns genesis hash unless explicitly set to False
309+
if txn_in_block.has_genesis_hash is not False and txn.genesis_hash is None:
310+
set_frozen_field(txn, "genesis_hash", genesis_hash)
295311

296312
@dataclass(slots=True)
297313
class GetBlock:

src/algokit_algod_client/models/_block.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,23 @@ class Block:
293293
),
294294
)
295295

296+
def __post_init__(self) -> None:
297+
# populates genesis id and hash on transactions if required to ensure
298+
# tx id's are correct
299+
genesis_id = self.header.genesis_id
300+
genesis_hash = self.header.genesis_hash
301+
set_frozen_field = object.__setattr__
302+
for txn_in_block in self.payset or []:
303+
txn = txn_in_block.signed_transaction.signed_transaction.transaction
304+
305+
if txn_in_block.has_genesis_id and txn.genesis_id is None:
306+
set_frozen_field(txn, "genesis_id", genesis_id)
307+
308+
# the following assumes that Consensus.RequireGenesisHash is true
309+
# so assigns genesis hash unless explicitly set to False
310+
if txn_in_block.has_genesis_hash is not False and txn.genesis_hash is None:
311+
set_frozen_field(txn, "genesis_hash", genesis_hash)
312+
296313

297314
@dataclass(slots=True)
298315
class GetBlock:
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import base64
2+
import dataclasses
3+
4+
from algokit_transact import Transaction
5+
from algokit_utils import AlgorandClient, AlgoAmount, AssetCreateParams
6+
7+
8+
def test_block_tx_id_matches_submitted_id() -> None:
9+
localnet = AlgorandClient.default_localnet()
10+
algod = localnet.client.algod
11+
12+
sender = localnet.account.random()
13+
localnet.account.ensure_funded(sender, localnet.account.localnet_dispenser(), AlgoAmount(micro_algo=1_000_000))
14+
15+
txns = (
16+
localnet.new_group()
17+
.add_asset_create(
18+
AssetCreateParams(sender=sender.addr, static_fee=AlgoAmount(micro_algo=2000), total=100_000_000)
19+
)
20+
.send()
21+
)
22+
txn = txns.transactions[0]
23+
group_id = base64.b64decode(txns.group_id)
24+
tx_id = txns.tx_ids[0]
25+
confirmation = algod.pending_transaction_information(tx_id)
26+
confirmed_round = confirmation.confirmed_round
27+
assert confirmed_round is not None, "expected a confirmed round"
28+
assert confirmation.txn.transaction.tx_id() == tx_id, "expected confirmation tx_id to match submitted tx_id"
29+
assert confirmation.txn.transaction.group == group_id, "expected group_id to match"
30+
31+
block = algod.get_block(confirmed_round)
32+
assert block.block.payset is not None, "expected non null payset"
33+
(block_txn,) = block.block.payset
34+
txn_fields = {f.name: getattr(txn, f.name) for f in dataclasses.fields(Transaction)}
35+
block_txn_fields = {
36+
f.name: getattr(block_txn.signed_transaction.signed_transaction.transaction, f.name)
37+
for f in dataclasses.fields(Transaction)
38+
}
39+
assert txn_fields == block_txn_fields
40+
41+
assert block_txn.signed_transaction.signed_transaction.transaction.group == group_id, "expected group_id to match"
42+
assert block_txn.signed_transaction.signed_transaction.transaction.tx_id() == tx_id, "expected block tx_id to match"

tests/modules/transact/test_app_call.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,9 @@ def test_should_throw_error_when_too_many_account_references_are_provided(base_c
425425
accounts = tuple("A" * 58 for _ in range(9)) # Max is 8
426426
tx = clone_transaction(
427427
base_call_transaction,
428-
application_call=build_app_call(app_id=123, on_complete=OnApplicationComplete.NoOp, account_references=accounts),
428+
application_call=build_app_call(
429+
app_id=123, on_complete=OnApplicationComplete.NoOp, account_references=accounts
430+
),
429431
)
430432

431433
assert_validation_error(tx, "App call validation failed: Account references cannot exceed 8 refs")

0 commit comments

Comments
 (0)