entropy_cr_dice
Behaviour
Section titled “Behaviour”- Returns a random integer in the range
[0, sides)derived from the consensus entropy visible to this Hook execution. - The hook must specify a minimum entropy tier (
min_tier). If the visible entropy is missing, stale, or below it, the call fails withTOO_LITTLE_ENTROPY. - The hook must specify which later strong Hooks may run after the draw (
flags). Withflags = 0, a strong Hook can only draw if no other strong Hook can run after it in the transaction; otherwise the call fails withLATER_STRONG_HOOKbefore any randomness is derived. See Later strong Hooks.
Definition
Section titled “Definition”int64_t entropy_cr_dice ( uint32_t sides, uint32_t min_tier, uint32_t flags);Hooks compiled against the earlier two-argument entropy_cr_dice(sides, min_tier) must be recompiled and reinstalled. The runtime supplies no default for the missing flags argument; the strict policy is an explicit final 0.
Example
Section titled “Example”A d6 with validator-quorum entropy that no later strong Hook can veto:
int64_t roll = entropy_cr_dice(6, 3, 0);if (roll == LATER_STRONG_HOOK) rollback(SBUF("A later Hook could veto this roll"), 1);if (roll < 0) rollback(SBUF("No entropy available"), 1);Alternatively, a cosmetic d100 that any later strong Hook may veto:
int64_t percent = entropy_cr_dice(100, 1, ENTROPY_ALLOW_ANY_STRONG_VETO);if (percent < 0) rollback(SBUF("No entropy available"), 1);These are alternative policies, not a fallback sequence. Choose the policy the application needs for each draw.
Parameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
sides | uint32_t | Number of sides. Result is in [0, sides). |
min_tier | uint32_t | Minimum entropy tier required: 1 = consensus fallback, 2 = participant aligned, 3 = validator quorum, 4 = validator full (reveals from every active validator). |
flags | uint32_t | Which strong Hooks may run after this draw: 0 = none; ENTROPY_ALLOW_SAME_ACCOUNT_STRONG_VETO (2) = Hooks installed on this Hook’s own account; ENTROPY_ALLOW_ANY_STRONG_VETO (1) = any. Setting both bits means any. Other bits are invalid. |
Later strong Hooks
Section titled “Later strong Hooks”A strong Hook that runs later in the same transaction can observe the effects of a draw and roll back the transaction when it dislikes the outcome, so that the transaction only ever succeeds with outcomes it accepts. flags states which later strong Hooks the draw tolerates:
flags | A strong Hook may draw when |
|---|---|
0 | It is the last strong Hook that can run in the transaction. |
ENTROPY_ALLOW_SAME_ACCOUNT_STRONG_VETO | Every strong Hook that can run after it is installed on the same account. |
ENTROPY_ALLOW_ANY_STRONG_VETO | Always: no restriction on later strong Hooks. The other checks still apply. |
- The check runs before the draw. A refused call returns
LATER_STRONG_HOOK, derives no randomness, and does not advance the draw counter. The Hook can handle the error and continue without randomness, or reject. - Which Hooks can run is fixed before strong execution starts: every Hook whose
HookOnandHookNamematch the transaction, in the sender’s chain (not run for transactions emitted by a Hook) and in the chains of all strong transactional stakeholders.hook_skiprequests made during execution do not change it. - Weak, callback, and again-as-weak executions have no later strong phase, so these checks always pass there.
- Later Hooks that a draw allows keep their normal veto and skip behaviour.
- The policy applies per call. One Hook’s flags never change what another Hook’s draw requires, and a later call with broader flags does not relax an earlier successful stricter draw.
Open-ledger previews
Section titled “Open-ledger previews”Open-ledger hook execution, including simulate, is provisional and uses the previous ledger’s entropy. Final execution uses only the current ledger’s entropy, which every normally built RNG-enabled ledger has: validator-derived, or a fallback derived for that ledger. A present current-ledger fallback may still fail the caller’s min_tier. If the current input is exceptionally missing, for example because its pseudo-transaction failed to apply, an otherwise admissible draw also fails with TOO_LITTLE_ENTROPY rather than reusing an older input. entropy_cr_dice() output can therefore differ between preview and final execution. See Speculative Execution.
Return Code
Section titled “Return Code”| Type | Description |
|---|---|
| int64_t | A random integer in [0, sides) on success. If negative, one of the errors below, checked in the order listed. |
| Error | Meaning |
|---|---|
INVALID_ARGUMENT | sides is 0, min_tier is outside 1..4, or flags has an undefined bit set. |
LATER_STRONG_HOOK | A strong Hook that flags does not allow can run later in this transaction. |
TOO_LITTLE_ENTROPY | Entropy is unavailable, stale, or below min_tier. |
INTERNAL_ERROR | The entropy API returned an unexpected byte count. |
Determinism
Section titled “Determinism”Each successful call to entropy_cr_dice() uses fresh derivation input from the same ledger entropy, even within the same hook execution. The reduced result can still repeat, especially for small sides values. The randomness is derived from:
- Ledger sequence, transaction ID, hook hash, account, chain position
- Originating account, strong/weak execution flag, and callback/direct dispatch flag
- The consensus entropy digest
- An internal call counter that advances on each successful draw
This ensures deterministic replay (same inputs → same outputs) while using different derivation input per draw.