Tier 1 (#7) signs with an immortal era. That was deliberate — it makes CheckMortality's implicit the genesis hash, so there is no birth block for the
signer and the node to disagree about, and it kept the first end-to-end proof
about the crypto rather than about mortality. It is not what should ship.
An immortal extrinsic is valid forever. A signed transfer that fails to get into
a block — pool eviction, a node restart, a user closing the popup after
approving — stays replayable at that nonce indefinitely, so anyone holding the
bytes can submit it later, at a moment the signer did not choose. Substrate's
default for user transactions is mortal for exactly this reason.
What it needs
Era encoding. The registry describes it as a 256-variant enum (Immortal, Mortal1…Mortal255) whose SCALE form is two bytes, so @quantus/codec can
already encode one — the caller has to name the right variant and phase, which
is the part nobody should hand-compute. A helper belongs in the codec next to standardExtensions.
The birth block hash as CheckMortality's implicit, which must be the hash
of the block the era is anchored to, not simply the current head. Getting this
wrong produces a valid signature the chain rejects as BadProof — the same
indistinguishable failure described on quantus/api#1.
A decision on period. 64 blocks is the polkadot-js default, but Heisenberg is
proof-of-work with a block time measured in minutes rather than seconds, so 64
blocks is hours and the mortality window wants choosing against the actual rate
rather than inherited.
Acceptance
The tier-1 harness submits with a mortal era and the transfer is included; and a
signed extrinsic whose era has lapsed is rejected by the node, which is the
property being bought.
Tier 1 (#7) signs with an immortal era. That was deliberate — it makes
`CheckMortality`'s implicit the genesis hash, so there is no birth block for the
signer and the node to disagree about, and it kept the first end-to-end proof
about the crypto rather than about mortality. It is not what should ship.
An immortal extrinsic is valid forever. A signed transfer that fails to get into
a block — pool eviction, a node restart, a user closing the popup after
approving — stays replayable at that nonce indefinitely, so anyone holding the
bytes can submit it later, at a moment the signer did not choose. Substrate's
default for user transactions is mortal for exactly this reason.
## What it needs
- `Era` encoding. The registry describes it as a 256-variant enum (`Immortal`,
`Mortal1`…`Mortal255`) whose SCALE form is two bytes, so `@quantus/codec` can
already encode one — the caller has to name the right variant and phase, which
is the part nobody should hand-compute. A helper belongs in the codec next to
`standardExtensions`.
- The **birth block hash** as `CheckMortality`'s implicit, which must be the hash
of the block the era is anchored to, not simply the current head. Getting this
wrong produces a valid signature the chain rejects as `BadProof` — the same
indistinguishable failure described on quantus/api#1.
- A decision on period. 64 blocks is the polkadot-js default, but Heisenberg is
proof-of-work with a block time measured in minutes rather than seconds, so 64
blocks is hours and the mortality window wants choosing against the actual rate
rather than inherited.
## Acceptance
The tier-1 harness submits with a mortal era and the transfer is included; and a
signed extrinsic whose era has lapsed is rejected by the node, which is the
property being bought.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Tier 1 (#7) signs with an immortal era. That was deliberate — it makes
CheckMortality's implicit the genesis hash, so there is no birth block for thesigner and the node to disagree about, and it kept the first end-to-end proof
about the crypto rather than about mortality. It is not what should ship.
An immortal extrinsic is valid forever. A signed transfer that fails to get into
a block — pool eviction, a node restart, a user closing the popup after
approving — stays replayable at that nonce indefinitely, so anyone holding the
bytes can submit it later, at a moment the signer did not choose. Substrate's
default for user transactions is mortal for exactly this reason.
What it needs
Eraencoding. The registry describes it as a 256-variant enum (Immortal,Mortal1…Mortal255) whose SCALE form is two bytes, so@quantus/codeccanalready encode one — the caller has to name the right variant and phase, which
is the part nobody should hand-compute. A helper belongs in the codec next to
standardExtensions.CheckMortality's implicit, which must be the hashof the block the era is anchored to, not simply the current head. Getting this
wrong produces a valid signature the chain rejects as
BadProof— the sameindistinguishable failure described on quantus/api#1.
proof-of-work with a block time measured in minutes rather than seconds, so 64
blocks is hours and the mortality window wants choosing against the actual rate
rather than inherited.
Acceptance
The tier-1 harness submits with a mortal era and the transfer is included; and a
signed extrinsic whose era has lapsed is rejected by the node, which is the
property being bought.