You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: references/delayed-message-pattern.md
+15-12Lines changed: 15 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,21 +6,24 @@ Use this pattern for future-block work such as reminders, auctions, inactivity c
6
6
7
7
## Canonical Self-Message Payload
8
8
9
-
For a standard Sails self-call by route name, encode service, method, and arguments in order, then concatenate:
9
+
For a Sails 1.0 self-call, build the same Sails Header v1 plus SCALE-encoded params that generated clients use. In generated Rust client code this is the `io::<Call>::encode_call(route_idx, args...)` helper:
- This is the route-prefixed byte shape to use when a delayed internal message cannot go through a generated client call directly.
21
-
- Keep the service and method names aligned with the exported Sails routes.
22
-
23
-
Note: In Sails 1.0, messages use the binary header protocol instead of SCALE-string routing for the route prefix. See `../../references/sails-header-wire-format.md` for the encoding.
23
+
- This is the header-routed byte shape to use when a delayed internal message cannot go through a generated client send directly.
24
+
- Keep the route constant and generated `io` type aligned with the exported Sails route.
25
+
- If generated client code is unavailable, manually encode the Sails Header v1 followed by SCALE-encoded params. See `../../references/sails-header-wire-format.md` for the header layout.
26
+
- The legacy SCALE-string route form (`service`, `method`, then args) is not a valid Sails 1.0 delayed self-message payload.
- Use `run_to_block` for delay-sensitive assertions.
73
76
- Assert both the scheduler-side effect and the eventual handler-side effect.
74
-
- If debugging the raw byte route, test the payload shape directly before blaming gas or timing.
77
+
- If debugging the raw byte route, assert the payload starts with the Sails Header v1 bytes (`GM`, version `0x01`, header length `0x10`) before blaming gas or timing.
Copy file name to clipboardExpand all lines: references/gear-builtin-actors.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -152,7 +152,7 @@ When debugging a builtin reply:
152
152
1. Confirm the sender targeted a builtin `ActorId`, not a program. If it was a program, this skill does not apply — go to `gear-message-execution`.
153
153
2. Identify the matching helper crate by source `ActorId` ↔ builtin id.
154
154
3. Classify: empty success, typed `Response`, or error reply.
155
-
4. Decode as `gbuiltin_*::Response` using `parity_scale_codec::Decode` — not a Sails generated client, not `ProgramMetadata`. There is no Sails route prefix on a builtin reply.
155
+
4. Decode as `gbuiltin_*::Response` using `parity_scale_codec::Decode` — not a Sails generated client, not `ProgramMetadata`. There is no Sails Header framing on a builtin reply.
156
156
5. On error replies, inspect the payload as `BuiltinActorError` (defined in the `builtins-common` crate at `vara/sdk/builtins/common/src/lib.rs`; import as `use builtins_common::BuiltinActorError;`). Common variants: `InsufficientGas` when the caller-supplied `gas_limit` is below the call's weight; `GasAllowanceExceeded` when the block-level allowance is exhausted; `InsufficientValue`; `DecodingError`; and `Custom(LimitedStr<'static>)` for actor-specific errors.
157
157
158
158
## Gas and ED
@@ -164,7 +164,7 @@ When debugging a builtin reply:
164
164
## Guardrails
165
165
166
166
-**Do not hardcode an `ActorId` without citing a runtime file.** Re-derive with `hash((b"built/in", id).encode())` or copy from `vara/runtime/vara/src/lib.rs`, and note the source.
167
-
-**Do not decode builtin replies with a Sails client.** There is no route prefix; use the helper crate's `Response` type.
167
+
-**Do not decode builtin replies with a Sails client.** There is no Sails Header framing; use the helper crate's `Response` type.
168
168
-**Do not call a builtin from a sync handler.** The call is `_for_reply`; the handler must be async.
169
169
-**Do not assume a reply shape across runtime versions.** Helper crates evolve — pin to a workspace version that matches the target runtime.
170
170
-**Do not wrap a builtin behind a service handler that loses idempotency.** Broker services should carry their own retry and reconciliation state; the builtin has no memory.
Copy file name to clipboardExpand all lines: references/gear-gstd-api-and-syscalls.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ Use `msg` when the design question is about payload handling, outbound messages,
32
32
| Await a reply in async code |`_for_reply` helpers such as `msg::send_bytes_for_reply`| same send wrappers plus async runtime locks | send syscalls plus reply deposit or reply-hook handling |
33
33
| Spend reserved gas on later messaging | reservation-backed send or reply variants | reservation send or reply wrappers |`gr_reservation_send`, `gr_reservation_send_commit`, `gr_reservation_reply`, `gr_reservation_reply_commit`|
34
34
35
-
Design note: prefer typed APIs for stable app contracts. Use bytes variants when the route is intentionally raw or when isolating codec or route-prefix bugs in Sails.
35
+
Design note: prefer typed APIs for stable app contracts. Use bytes variants when the route is intentionally raw or when isolating codec or Sails Header routing bugs.
Copy file name to clipboardExpand all lines: references/gear-messaging-and-replies.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@
7
7
- Use delayed variants when execution must happen in a future block.
8
8
- Use reservation-backed variants when later execution needs preserved gas.
9
9
- Use staged payload flows only when the payload must be built incrementally.
10
-
- When a Sails program calls a Sails constructor or service, prefer generated clients or equivalent route-prefixed encoding rather than an ad hoc raw struct payload.
10
+
- When a Sails program calls a Sails constructor or service, prefer generated clients or equivalent Sails Header-aware encoding rather than an ad hoc raw struct payload.
11
11
12
12
## Message Lifecycle Checklist
13
13
@@ -37,9 +37,9 @@
37
37
38
38
## Sails Routing Notes
39
39
40
-
- Generated Sails clients encode the correct service and method route prefixes for you.
41
-
- The Sails wire format is route-prefixed encoded data, so a bare raw struct is not a normal constructor or service payload.
42
-
- If a payload uses the wrong route prefix, decode fails even when the payload body type is otherwise correct.
40
+
- Generated Sails clients encode the Sails Header and SCALE body for you.
41
+
- The Sails 1.0 wire format is Sails Header v1 plus encoded data, so a bare raw struct is not a normal constructor or service payload.
42
+
- If a payload uses the wrong interface ID, entry ID, or route index, decode fails even when the payload body type is otherwise correct.
43
43
- Treat generated clients as the default path and use low-level byte encoding only to isolate transport or codec bugs.
Copy file name to clipboardExpand all lines: references/sails-cheatsheet.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -58,7 +58,7 @@ These errors appear in order of frequency from builder feedback.
58
58
## IDL And Clients
59
59
- Sails generates IDL from Rust types at build time.
60
60
- Generated clients are the default typed integration surface for Rust and TypeScript.
61
-
- Generated clients encode the correct payloads for constructor and service calls using route-prefixed SCALE encoding.
61
+
- Generated clients encode the correct payloads for constructor and service calls using the Sails Header plus SCALE body.
62
62
- The IDL uses V2 syntax (see `../../references/sails-idl-v2-syntax.md`) and messages use a binary header protocol (see `../../references/sails-header-wire-format.md`).
63
63
- Architecture decisions must keep exported DTO names distinct from service names.
64
64
- Events are part of the public interface and should map to meaningful state transitions.
@@ -67,7 +67,7 @@ These errors appear in order of frequency from builder feedback.
67
67
- Specs should talk in terms of program constructors, service routes, commands, queries, and events.
68
68
- Specs should name the chosen state ownership pattern instead of leaving storage implicit.
69
69
- Architecture plans should keep `#[program]` thin and push logic into services.
70
-
- Implementation guidance should prefer generated clients or other Sails route-prefixed encoding over raw payload handling.
70
+
- Implementation guidance should prefer generated clients or other Sails Header-aware encoding over raw payload handling.
Copy file name to clipboardExpand all lines: references/sails-header-wire-format.md
+8-6Lines changed: 8 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,22 +4,24 @@ Source of truth: [docs/sails-header-v1-spec.md](https://github.com/gear-tech/sai
4
4
5
5
## Overview
6
6
7
-
Every Sails message begins with a 16-byte base header (extensions optional) prepended to the SCALE-encoded payload. The header lives entirely within the Gear message payload — no runtime or consensus changes required.
7
+
Every Sails 1.0 message begins with a 16-byte header prepended to the SCALE-encoded payload. The header lives entirely within the Gear message payload — no runtime or consensus changes required.
8
8
9
9
## Base Header Layout
10
10
11
11
```
12
12
Byte offset Field Size (bytes) Description
13
13
0–1 Magic 2 ASCII "GM" (0x47 0x4D)
14
14
2 Version 1 0x01
15
-
3 Header length 1 Total header size; base = 0x10
15
+
3 Header length 1 Must be 0x10 in v1
16
16
4–11 Interface ID 8 64-bit ID from interface hash
17
17
12–13 Entry ID 2 Little-endian 16-bit entry identifier
18
18
14 Route Index 1 0x00 = infer route if unambiguous
19
19
15 Reserved 1 Must be 0x00 in v1
20
-
>15 ExtensionsvariablePresent only if header length > 0x10
20
+
>15 Payloadvariable SCALE-encoded params or body
21
21
```
22
22
23
+
Extension-sized headers are reserved for future versions. A v1 decoder must reject header lengths other than `0x10`.
24
+
23
25
## Identifier Derivation
24
26
25
27
### Interface ID
@@ -42,15 +44,15 @@ Generated clients encode/decode the header automatically. When debugging wire pa
42
44
## Interface ID Stability
43
45
44
46
- Adding or removing methods/types **changes** the interface ID
45
-
- Renaming methods does NOT change the interface ID (hash is structural)
46
-
-`@entry_id` overrides allow pinning specific entry points across versions
47
+
- Renaming public methods **changes**the interface ID because the exported function route name is hashed
48
+
-`@entry_id` overrides allow pinning specific entry points across versions, but they do not preserve the interface ID after a method rename
47
49
- Programs hosting V1 and V2 services simultaneously can use `route_idx` to disambiguate
48
50
49
51
## Validation Checklist
50
52
51
53
1. Magic: first two bytes are `0x47 0x4D`
52
54
2. Version: `0x01`
53
-
3. Header length: `= 0x10` for v1; `> 0x10` only when extensions are present and must be `<= payload_length`
55
+
3. Header length: must equal `0x10` for v1; reject smaller, larger, or extension-sized v1 headers
54
56
4. Reserved byte: must be `0x00` in v1
55
57
5. Route inference (`0x00`): resolve only if exactly one matching instance exists
0 commit comments