Expiry and timestamps
You are looking at an old version of this page: revision #25 by zoobc.how, 2026-10-26 20:39 UTC. See the current version
Every ZooBC transaction carries the moment it was made, in Unix seconds, inside its signed bytes. That timestamp opens a validity window: a block may include the transaction only within the window, and after it the transaction is dead and must be signed again. The window protects the signer. A payment that could not get into a block at a busy moment does not linger for days and then surprise them; it simply expires, and they can decide again.
The default window: one hour
By default a block may include a transaction until 3,600 seconds after its timestamp: one hour, or 240 blocks at one block every 15 seconds. After that, nodes refuse it with a message that ends "...sign it again".
The window also has a front edge. A transaction dated more than 3,600 seconds in the future is refused too, with a hint to check the signer's clock. This catches a device whose clock is wrong.
Choosing the window: version 3
A version-3 transaction carries a 4-byte expiry field, right after the fee and the survival field, and states its own window in seconds:
- 0 means the default hour;
- a smaller value shortens the window, for a payment that must happen soon or not at all;
- the largest allowed value is 86,400 seconds, one day; a larger value is refused.
A version 1 or 2 transaction has no expiry field, and one that states an expiry anyway is refused. Whatever the version, the limit of one hour into the future still applies.
A longer window helps when a signature takes time to collect: on a hardware wallet, or among the participants of a multisignature account.
How pools and chains keep up
Two companion rules make the day-long window safe:
- a node's transaction pool keeps each transaction for its own stated window;
- every chain keeps transaction ids for at least 25 hours: the longest window plus the one-hour tolerance into the future.
Since a node refuses an id it has already confirmed (see signing a transaction), a transaction can never be replayed while it is still valid.
Time in blocks
Blocks are checked against the same windows, so every node reaches the same verdict:
- a block whose timestamp is past a transaction's timestamp plus its window is invalid;
- so is a block that carries a transaction dated more than 3,600 seconds after the block.
Some settlements happen by themselves, block by block: Escrow deadlines, the completion of liquid payments (streams), scheduled transfers falling due, the expiry of market orders and the phases of the fee vote. These read the previous block's timestamp, not the block's own. A producer therefore cannot stamp its block a little ahead of time to pull a payout into it.
How blocks are spaced in time is explained in blocks and time.