|
3 | 3 | import pytest |
4 | 4 |
|
5 | 5 | from hiero_sdk_python.account.account_create_transaction import AccountCreateTransaction |
| 6 | +from hiero_sdk_python.account.account_id import AccountId |
6 | 7 | from hiero_sdk_python.crypto.private_key import PrivateKey |
7 | 8 | from hiero_sdk_python.exceptions import ReceiptStatusError |
8 | 9 | from hiero_sdk_python.hapi.services import ( |
|
14 | 15 | transaction_response_pb2, |
15 | 16 | ) |
16 | 17 | from hiero_sdk_python.response_code import ResponseCode |
| 18 | +from hiero_sdk_python.tokens.token_id import TokenId |
| 19 | +from hiero_sdk_python.tokens.token_mint_transaction import TokenMintTransaction |
| 20 | +from hiero_sdk_python.transaction.transaction_id import TransactionId |
17 | 21 | from hiero_sdk_python.transaction.transaction_receipt import TransactionReceipt |
18 | 22 | from hiero_sdk_python.transaction.transaction_response import TransactionResponse |
19 | 23 | from tests.unit.mock_server import mock_hedera_servers |
@@ -117,3 +121,42 @@ def test_execute_returns_receipt_without_error_when_validation_disabled(): |
117 | 121 | receipt = tx.execute(client) |
118 | 122 |
|
119 | 123 | assert receipt.status == ResponseCode.INVALID_SIGNATURE |
| 124 | + |
| 125 | + |
| 126 | +def test_duplicate_signature_not_added(): |
| 127 | + tx = TokenMintTransaction() |
| 128 | + tx.set_transaction_id(TransactionId.generate(AccountId(0, 0, 1234))) |
| 129 | + tx.set_node_account_id(AccountId(0, 0, 3)) |
| 130 | + tx.set_token_id(TokenId(0, 0, 1)) |
| 131 | + tx.set_amount(100) |
| 132 | + key = PrivateKey.generate_ed25519() |
| 133 | + tx.freeze() |
| 134 | + tx.sign(key) |
| 135 | + tx.sign(key) |
| 136 | + assert tx._signature_map, "signature_map should not be empty after freeze+sign" # ← ADD HERE |
| 137 | + body_bytes = next(iter(tx._signature_map.keys())) |
| 138 | + sig_pairs = tx._signature_map[body_bytes].sigPair |
| 139 | + assert len(sig_pairs) == 1, "Expected 1 signature for duplicate key" |
| 140 | + |
| 141 | + |
| 142 | +def test_multiple_keys_still_work(): |
| 143 | + tx = TokenMintTransaction() |
| 144 | + tx.set_transaction_id(TransactionId.generate(AccountId(0, 0, 1234))) |
| 145 | + tx.set_node_account_id(AccountId(0, 0, 3)) |
| 146 | + tx.set_token_id(TokenId(0, 0, 1)) |
| 147 | + tx.set_amount(100) |
| 148 | + key1 = PrivateKey.generate_ed25519() |
| 149 | + key2 = PrivateKey.generate_ed25519() |
| 150 | + tx.freeze() |
| 151 | + tx.sign(key1) |
| 152 | + tx.sign(key2) |
| 153 | + assert tx._signature_map, "signature_map should not be empty after freeze+sign" |
| 154 | + body_bytes = next(iter(tx._signature_map.keys())) |
| 155 | + sig_pairs = tx._signature_map[body_bytes].sigPair |
| 156 | + assert len(sig_pairs) == 2, "Expected 2 signatures for different keys" |
| 157 | + pubkey_prefixes = {sp.pubKeyPrefix for sp in sig_pairs} |
| 158 | + expected_prefixes = { |
| 159 | + key1.public_key().to_bytes_raw(), |
| 160 | + key2.public_key().to_bytes_raw(), |
| 161 | + } |
| 162 | + assert pubkey_prefixes == expected_prefixes, "Signatures should match key1 and key2 exactly" |
0 commit comments