Skip to content

Commit ecb5bc4

Browse files
test: update trace expectations for call-boundary frames
Merging main brought in the enriched tracer (get-events / contract-call features), which now wraps the WebAssembly instruction stream with a callContract entry frame and an endWasm exit frame. Assert the deterministic instruction records exactly and the entry/exit frames structurally, leaving the per-run contract and account ids unpinned.
1 parent 4924249 commit ecb5bc4

1 file changed

Lines changed: 48 additions & 11 deletions

File tree

src/tests/integration/test_server.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -614,30 +614,52 @@ def test_trace_transaction_missing_hash_returns_invalid_params(server: StellarRp
614614

615615

616616
def test_trace_transaction_returns_full_instruction_trace_for_foo(server: StellarRpcServer) -> None:
617-
"""traceTransaction returns the complete, ordered instruction trace of an invocation.
617+
"""traceTransaction returns the complete, ordered trace of an invocation: a ``callContract``
618+
entry frame, the executed WebAssembly instructions, and an ``endWasm`` exit frame.
618619
619620
empty.wat's ``foo()`` body is a single ``i64.const 2`` (the Void return); the three leading
620-
records are the contract's global initialisation and the ``block`` is the function frame.
621-
This is the exact trace shown in the README, asserted record-for-record so any drift in the
622-
format, ordering, or the array-vs-string shape of the result is caught.
621+
instruction records are the contract's global initialisation and the ``block`` is the
622+
function frame. The instruction records are asserted record-for-record (the exact trace
623+
shown in the README) so any drift in format, ordering, or the array-vs-string shape of the
624+
result is caught. The entry/exit frames carry per-run contract and account ids, so they are
625+
checked structurally rather than by value.
623626
"""
624627
invoke = _deploy_and_get_invoker(server, EMPTY_CONTRACT_WAT)
625628
tx_hash = invoke('foo')
626629

627630
trace = _rpc(server.port(), 'traceTransaction', {'hash': tx_hash})['result']
628631

629-
assert trace == [
632+
# A callContract entry frame opens the trace: the account calls foo() on the contract with
633+
# no arguments at call depth 1.
634+
entry = trace[0]
635+
assert entry['instr'] == ['callContract']
636+
assert entry['function'] == 'foo'
637+
assert entry['args'] == []
638+
assert entry['depth'] == 1
639+
assert entry['from']['addrType'] == 'account'
640+
assert entry['to']['addrType'] == 'contract'
641+
642+
# The executed WebAssembly instructions, exactly as shown in the README.
643+
assert trace[1:-1] == [
630644
{'pos': 3, 'instr': ['const', 'i32', 1048576], 'stack': [], 'locals': {}},
631645
{'pos': 11, 'instr': ['const', 'i32', 1048576], 'stack': [], 'locals': {}},
632646
{'pos': 19, 'instr': ['const', 'i32', 1048576], 'stack': [], 'locals': {}},
633647
{'pos': None, 'instr': ['block'], 'stack': [], 'locals': {}},
634648
{'pos': 3, 'instr': ['const', 'i64', 2], 'stack': [], 'locals': {}},
635649
]
636650

651+
# An endWasm exit frame closes the trace: the call succeeded and returned Void.
652+
exit_frame = trace[-1]
653+
assert exit_frame['instr'] == ['endWasm']
654+
assert exit_frame['success'] is True
655+
assert exit_frame['result'] == {'type': 'void'}
656+
assert exit_frame['depth'] == 1
657+
637658

638659
def test_trace_records_have_expected_structure_and_reflect_arguments(server: StellarRpcServer) -> None:
639-
"""Each trace record is a ``{pos, instr, stack, locals}`` object, and for a call that takes
640-
arguments the decoded arguments are bound as locals while intermediate values build up on the
660+
"""The trace opens with a ``callContract`` frame that echoes the decoded arguments, and each
661+
WebAssembly instruction record is a ``{pos, instr, stack, locals}`` object. For a call that
662+
takes arguments the arguments are bound as locals while intermediate values build up on the
641663
stack — exercising a richer trace than the argument-less ``foo()`` case.
642664
"""
643665
invoke = _deploy_and_get_invoker(server, ARGS_CONTRACT_WAT)
@@ -655,7 +677,22 @@ def test_trace_records_have_expected_structure_and_reflect_arguments(server: Ste
655677

656678
assert isinstance(trace, list)
657679
assert len(trace) > 0
658-
for record in trace:
680+
681+
# The callContract entry frame echoes the call target and its decoded arguments.
682+
entry = trace[0]
683+
assert entry['instr'] == ['callContract']
684+
assert entry['function'] == 'test_integers'
685+
assert entry['args'] == [
686+
{'type': 'u32', 'value': 42},
687+
{'type': 'i32', 'value': -7},
688+
{'type': 'u64', 'value': 100},
689+
{'type': 'i64', 'value': -200},
690+
]
691+
692+
# The instruction records (everything between the call-boundary frames) share one shape.
693+
instr_records = [record for record in trace if 'locals' in record]
694+
assert instr_records
695+
for record in instr_records:
659696
assert set(record) == {'pos', 'instr', 'stack', 'locals'}
660697
assert record['pos'] is None or isinstance(record['pos'], int)
661698
assert isinstance(record['instr'], list) and record['instr']
@@ -667,12 +704,12 @@ def test_trace_records_have_expected_structure_and_reflect_arguments(server: Ste
667704
assert all(isinstance(e, list) and len(e) == 2 and isinstance(e[0], str) for e in record['locals'].values())
668705

669706
# The four call arguments are bound as locals 0..3 by the time the body runs.
670-
locals_seen = {key for record in trace for key in record['locals']}
707+
locals_seen = {key for record in instr_records for key in record['locals']}
671708
assert {'0', '1', '2', '3'} <= locals_seen
672709
# Intermediate computation puts values on the stack at some point.
673-
assert any(record['stack'] for record in trace)
710+
assert any(record['stack'] for record in instr_records)
674711
# The function body returns Void: the final instruction pushes the i64 constant 2.
675-
assert trace[-1]['instr'] == ['const', 'i64', 2]
712+
assert instr_records[-1]['instr'] == ['const', 'i64', 2]
676713

677714

678715
def test_call_tx_with_args(server: StellarRpcServer) -> None:

0 commit comments

Comments
 (0)