|
12 | 12 | from typing import Any |
13 | 13 |
|
14 | 14 | import pytest |
15 | | -from stellar_sdk import Account, Keypair, Network, StrKey, TransactionBuilder, xdr |
| 15 | +from stellar_sdk import Account, Asset, Keypair, Network, StrKey, TransactionBuilder, xdr |
16 | 16 | from stellar_sdk.xdr.sc_val_type import SCValType |
17 | 17 |
|
18 | 18 | from komet_node.server import StellarRpcServer |
@@ -339,6 +339,40 @@ def test_send_transaction_and_get_result(server: StellarRpcServer) -> None: |
339 | 339 | assert set(get_result) <= _GET_TRANSACTION_KEYS |
340 | 340 |
|
341 | 341 |
|
| 342 | +def test_send_transaction_unsupported_operation_returns_error_status(server: StellarRpcServer) -> None: |
| 343 | + """A transaction that decodes but cannot be processed is rejected with status ERROR. |
| 344 | +
|
| 345 | + Mirrors real stellar-rpc's admission-time rejection: the response carries a txMALFORMED |
| 346 | + TransactionResult in errorResultXdr, the transaction never reaches the ledger (no |
| 347 | + receipt, no ledger bump), and getTransaction stays NOT_FOUND. |
| 348 | + """ |
| 349 | + keypair = Keypair.random() |
| 350 | + account = Account(keypair.public_key, sequence=0) |
| 351 | + envelope = ( |
| 352 | + TransactionBuilder(account, Network.TESTNET_NETWORK_PASSPHRASE) |
| 353 | + .append_payment_op(destination=Keypair.random().public_key, asset=Asset.native(), amount='1') |
| 354 | + .set_timeout(30) |
| 355 | + .build() |
| 356 | + ) |
| 357 | + envelope.sign(keypair) |
| 358 | + |
| 359 | + result = _rpc(server.port(), 'sendTransaction', {'transaction': envelope.to_xdr()})['result'] |
| 360 | + assert result['status'] == 'ERROR' |
| 361 | + assert result['hash'] == envelope.hash_hex() |
| 362 | + assert _is_number(result['latestLedger']) |
| 363 | + assert _is_int_string(result['latestLedgerCloseTime']) |
| 364 | + assert set(result) == {'hash', 'status', 'errorResultXdr', 'latestLedger', 'latestLedgerCloseTime'} |
| 365 | + |
| 366 | + tx_result = xdr.TransactionResult.from_xdr(result['errorResultXdr']) |
| 367 | + assert tx_result.result.code == xdr.TransactionResultCode.txMALFORMED |
| 368 | + assert tx_result.fee_charged.int64 == 0 |
| 369 | + |
| 370 | + # The rejected transaction never reached the ledger. |
| 371 | + assert _rpc(server.port(), 'getLatestLedger', {})['result']['sequence'] == 0 |
| 372 | + get_result = _rpc(server.port(), 'getTransaction', {'hash': envelope.hash_hex()})['result'] |
| 373 | + assert get_result['status'] == 'NOT_FOUND' |
| 374 | + |
| 375 | + |
342 | 376 | def test_send_transaction_duplicate_is_not_reexecuted(server: StellarRpcServer) -> None: |
343 | 377 | """Resubmitting an already-executed transaction returns DUPLICATE and leaves the chain alone.""" |
344 | 378 | keypair = Keypair.random() |
|
0 commit comments