Skip to content

Commit d77b000

Browse files
committed
Added tests for trace_transaction
1 parent 74f64ca commit d77b000

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

src/tests/integration/test_server.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,91 @@ def sign_and_xdr(tb: TransactionBuilder) -> str:
171171
# 4. Invoke foo()
172172
contract_address = server.interpreter.contract_address_from_deployer_address(keypair.public_key, salt)
173173
send(sign_and_xdr(builder().append_invoke_contract_function_op(contract_address, 'foo', [])))
174+
175+
176+
def test_trace_transaction_returns_result_directly(server: StellarRpcServer) -> None:
177+
"""traceTransaction returns status/ledger/trace immediately, not PENDING."""
178+
keypair = Keypair.random()
179+
account = Account(keypair.public_key, sequence=0)
180+
181+
envelope = (
182+
TransactionBuilder(account, Network.TESTNET_NETWORK_PASSPHRASE)
183+
.append_create_account_op(destination=keypair.public_key, starting_balance='1000')
184+
.set_timeout(30)
185+
.build()
186+
)
187+
envelope.sign(keypair)
188+
189+
result = _rpc(server.port(), 'traceTransaction', {'transaction': envelope.to_xdr()})['result']
190+
191+
assert result['status'] == 'SUCCESS'
192+
assert result['hash'] == envelope.hash_hex()
193+
assert 'ledger' in result
194+
assert 'trace' in result
195+
assert 'latestLedger' in result
196+
197+
198+
def test_trace_transaction_stored_for_get_transaction(server: StellarRpcServer) -> None:
199+
"""traceTransaction stores the result so getTransaction can retrieve it."""
200+
keypair = Keypair.random()
201+
account = Account(keypair.public_key, sequence=0)
202+
203+
envelope = (
204+
TransactionBuilder(account, Network.TESTNET_NETWORK_PASSPHRASE)
205+
.append_create_account_op(destination=keypair.public_key, starting_balance='1000')
206+
.set_timeout(30)
207+
.build()
208+
)
209+
envelope.sign(keypair)
210+
211+
trace_result = _rpc(server.port(), 'traceTransaction', {'transaction': envelope.to_xdr()})['result']
212+
get_result = _rpc(server.port(), 'getTransaction', {'hash': trace_result['hash']})['result']
213+
214+
assert get_result['status'] == 'SUCCESS'
215+
assert get_result['envelopeXdr'] == envelope.to_xdr()
216+
217+
218+
def test_trace_transaction_produces_trace_on_contract_invocation(server: StellarRpcServer) -> None:
219+
"""traceTransaction returns non-empty trace JSONL when a contract function is invoked."""
220+
keypair = Keypair.random()
221+
account = Account(keypair.public_key, sequence=0)
222+
223+
def builder() -> TransactionBuilder:
224+
return TransactionBuilder(account, Network.TESTNET_NETWORK_PASSPHRASE)
225+
226+
def sign_and_xdr(tb: TransactionBuilder) -> str:
227+
env = tb.set_timeout(30).build()
228+
env.sign(keypair)
229+
return env.to_xdr()
230+
231+
def send(xdr: str) -> None:
232+
res = _rpc(server.port(), 'sendTransaction', {'transaction': xdr})
233+
assert res['result']['status'] == 'PENDING'
234+
tx_hash = res['result']['hash']
235+
assert _rpc(server.port(), 'getTransaction', {'hash': tx_hash})['result']['status'] == 'SUCCESS'
236+
237+
# Set up: create account, upload wasm, deploy contract
238+
send(sign_and_xdr(builder().append_create_account_op(keypair.public_key, '1000')))
239+
240+
wasm_bytecode = wat_to_wasm(EMPTY_CONTRACT_WAT)
241+
send(sign_and_xdr(builder().append_upload_contract_wasm_op(wasm_bytecode)))
242+
243+
from stellar_sdk.utils import sha256
244+
wasm_hash = sha256(wasm_bytecode)
245+
salt = b'\x00' * 32
246+
send(sign_and_xdr(builder().append_create_contract_op(wasm_hash, keypair.public_key, None, salt)))
247+
248+
# Invoke via traceTransaction and check trace content
249+
contract_address = server.interpreter.contract_address_from_deployer_address(keypair.public_key, salt)
250+
invoke_xdr = sign_and_xdr(builder().append_invoke_contract_function_op(contract_address, 'foo', []))
251+
result = _rpc(server.port(), 'traceTransaction', {'transaction': invoke_xdr})['result']
252+
253+
assert result['status'] == 'SUCCESS'
254+
assert result['trace'] is not None
255+
# Trace is newline-separated JSON records; verify each line parses as JSON
256+
lines = [line for line in result['trace'].splitlines() if line.strip()]
257+
assert len(lines) > 0
258+
import json as _json
259+
for line in lines:
260+
record = _json.loads(line)
261+
assert 'instr' in record

0 commit comments

Comments
 (0)