Fields
All numeric fields are little-endian.chain_ididentifies which the Grid network the activation is for. The same payload signed for a different network produces a different signature, so cross-network replays are rejected.valid_until_blockis the highest block index at which this activation may execute. See The validity window below.tagis a 32-bit application-defined value the signer can vary to disambiguate otherwise-identical activations. Two payloads with identical content but different tags produce two differentActivationIds.tois the target entity. If left unset, it resolves to the signer’s own entity ID.signeris the Ed25519 public key that authorized the activation.operations_payloadis a Borsh-encodedVec<SerializedOperation>. Each entry carries avm_id(e.g.Gci,Gvm) and the per-VM operation bytes. The protocol treats this as opaque; only the execution layer parses it.
What is signed
The Ed25519 signature is computed over a fixed-size 82-byte buffer derived from the activation. The payload itself is not signed directly: it is hashed first, and only the 32-byte hash goes into the buffer.tois always the resolved target. Iftowas unset on the activation, this slot holds the signer’s entity ID. The signed pre-image is unambiguous either way.payloadH = SHA256(operations_payload).
Activation ID
The same buffer determines the activation’s identity:gen_getActivation (or gen client get-activation) to look up status and receipts.
The validity window
The Grid does not use a sequential per-account nonce. There is noaccount.nonce + 1 to look up before signing, no nonce gap that strands later activations when an earlier one is dropped, and no requirement that activations from the same signer arrive in any particular order.
Instead, every activation declares an explicit expiry: valid_until_block. At admission the protocol enforces:
valid_until_block > last_finalized_block: the activation has not already expired.valid_until_block - last_finalized_block < MAX_VALIDITY_WINDOW: the expiry is bounded so the dedup window stays finite.
MAX_VALIDITY_WINDOW is 1,000,000 blocks today. At a 10ms block time that is roughly 2.7 hours of wall-clock validity. A signer can pick any value within that bound. (The exact constant and whether it remains overridable per-deployment may be tightened before mainnet.)
This works because the Grid has deterministic BFT finality with no forks. There is no recent-block-hash to bind against. Once a block is final, it stays final, so a future block index alone is enough to bound the activation’s lifetime.
Replay protection
Replay protection has two parts:- Cryptographic binding.
chain_id,valid_until_block,to,tag, and the payload hash are all in the signed buffer. The same payload signed for a different chain, target, expiry, or tag is a different signed message and a differentActivationId. - Mempool dedup. Each shard mempool retains every admitted
ActivationIduntil itsvalid_until_blockis finalized and pruned. A duplicate submission within that window is rejected at admission.
tag or a payload field) so the new activation has a fresh ActivationId.
Picking a valid_until_block
The typical flow is:
- Read the current finalized block via
gen_getCurrentBlockIndex(RPC) orgen client get-current-block-index(CLI). - Add a buffer for the latency you expect between signing and admission.
current + 600gives ~6 seconds at 10ms blocks;current + 6000gives ~60 seconds. Stay underMAX_VALIDITY_WINDOW. - Sign and submit.
What the protocol validates at admission
The mempool admission gate enforces:- Structural: required fields are present and framing is valid.
- Signature: Ed25519 verification against the 82-byte buffer and the activation’s
signer. - Expiry:
valid_until_block > last_finalized_blockand withinMAX_VALIDITY_WINDOW. - Deduplication:
ActivationIdnot already in the dedup window.
Related
- Activations: what activations are and the developer lifecycle.
- Finality: when an activation is final and how to wait correctly.
- Sign with an external KMS: a worked signing flow.
- JSON-RPC overview:
gen_getCurrentBlockIndex,gen_sendExternalActivation,gen_getActivation.

