Skip to content

Commit e9cb163

Browse files
committed
format: add activation identifier to correlate invocations with returns
An invocation and the return (or revert) that ends the same activation can now carry a matching `activation` string. A debugger uses it to pair a call with its return directly — independent of trace order, without relying on strictly nested invoke/return ordering. Distinct activations carry distinct values, unique within a program. - Schema: add an optional `activation` string to the invoke, return, and revert contexts; add a worked example pairing an invoke with its return by a shared value. - TS types: add `activation` to the invoke/return/revert types and validate it in their guards.
1 parent d6699f5 commit e9cb163

4 files changed

Lines changed: 50 additions & 4 deletions

File tree

‎packages/format/src/types/program/context.ts‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,17 @@ export namespace Context {
155155
Invoke.isInvocation(value.invoke);
156156

157157
export namespace Invoke {
158-
export type Invocation = Function.Identity &
159-
(
158+
export type Invocation = Function.Identity & {
159+
activation?: string;
160+
} & (
160161
| Invocation.InternalCall
161162
| Invocation.ExternalCall
162163
| Invocation.ContractCreation
163164
);
164165

165166
export const isInvocation = (value: unknown): value is Invocation =>
166167
Function.isIdentity(value) &&
168+
(!("activation" in value) || typeof value.activation === "string") &&
167169
(Invocation.isInternalCall(value) ||
168170
Invocation.isExternalCall(value) ||
169171
Invocation.isContractCreation(value));
@@ -241,14 +243,16 @@ export namespace Context {
241243
export interface Info extends Function.Identity {
242244
data?: Function.PointerRef;
243245
success?: Function.PointerRef;
246+
activation?: string;
244247
}
245248

246249
export const isInfo = (value: unknown): value is Info =>
247250
Function.isIdentity(value) &&
248251
typeof value === "object" &&
249252
!!value &&
250253
(!("data" in value) || Function.isPointerRef(value.data)) &&
251-
(!("success" in value) || Function.isPointerRef(value.success));
254+
(!("success" in value) || Function.isPointerRef(value.success)) &&
255+
(!("activation" in value) || typeof value.activation === "string");
252256
}
253257

254258
export interface Revert {
@@ -265,13 +269,15 @@ export namespace Context {
265269
export interface Info extends Function.Identity {
266270
reason?: Function.PointerRef;
267271
panic?: number;
272+
activation?: string;
268273
}
269274

270275
export const isInfo = (value: unknown): value is Info =>
271276
Function.isIdentity(value) &&
272277
typeof value === "object" &&
273278
!!value &&
274279
(!("reason" in value) || Function.isPointerRef(value.reason)) &&
275-
(!("panic" in value) || typeof value.panic === "number");
280+
(!("panic" in value) || typeof value.panic === "number") &&
281+
(!("activation" in value) || typeof value.activation === "string");
276282
}
277283
}

‎schemas/program/context/function/invoke.schema.yaml‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ properties:
4343
4444
$ref: "schema:ethdebug/format/program/context/function"
4545

46+
properties:
47+
activation:
48+
type: string
49+
title: Activation identifier
50+
description: |
51+
Correlation identifier pairing this invocation with its
52+
matching return or revert. The invoke that opens an
53+
activation and the return or revert that closes it carry
54+
the same value; distinct activations carry distinct
55+
values, unique within the program. Lets a debugger pair a
56+
call with its return independent of trace order. Optional.
57+
4658
allOf:
4759
- oneOf:
4860
- required: [jump]
@@ -283,6 +295,9 @@ examples:
283295
- name: "amount"
284296
location: stack
285297
slot: 2
298+
# The matching return context carries the same `activation`
299+
# value, pairing this call with its return.
300+
activation: "transfer#0"
286301

287302
# -----------------------------------------------------------
288303
# External CALL: token.balanceOf(account)

‎schemas/program/context/function/return.schema.yaml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ properties:
4949
required:
5050
- pointer
5151

52+
activation:
53+
type: string
54+
title: Activation identifier
55+
description: |
56+
Correlation identifier for the activation this return
57+
ends. Matches the `activation` on the `invoke` that
58+
opened the same activation; distinct activations carry
59+
distinct values, unique within the program. Lets a
60+
debugger pair a return with its invocation independent
61+
of trace order. Optional.
62+
5263
unevaluatedProperties: false
5364

5465
required:
@@ -75,6 +86,9 @@ examples:
7586
pointer:
7687
location: stack
7788
slot: 0
89+
# Same `activation` value as the opening `invoke`, pairing
90+
# this return with its call.
91+
activation: "transfer#0"
7892

7993
# -----------------------------------------------------------
8094
# External call return: processing result of a CALL

‎schemas/program/context/function/revert.schema.yaml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ properties:
3737
(e.g., Solidity uses codes like 0x11 for arithmetic
3838
overflow).
3939
40+
activation:
41+
type: string
42+
title: Activation identifier
43+
description: |
44+
Correlation identifier for the activation this revert
45+
ends. Matches the `activation` on the `invoke` that
46+
opened the same activation; distinct activations carry
47+
distinct values, unique within the program. Lets a
48+
debugger pair an abnormal exit with its invocation
49+
independent of trace order. Optional.
50+
4051
unevaluatedProperties: false
4152

4253
required:

0 commit comments

Comments
 (0)