1 // Copyright (c) 2026 The Limenka developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 5 #ifndef LIMENKA_CONSENSUS_DELAY_H
6 #define LIMENKA_CONSENSUS_DELAY_H
7 8 #include <primitives/transaction.h>
9 #include <uint256.h>
10 11 #include <cstdint>
12 #include <optional>
13 14 /**
15 * Sequential per-block delay - division-free schoolbook long division.
16 *
17 * The delay is a consensus requirement on every fork block: the block
18 * must commit the result of dividing a deterministic 2^33-word stream
19 * (xorshift64* seeded from the previous block hash) by a 64-bit odd
20 * divisor derived from the same hash. The computation is a strict
21 * dependency chain (each remainder depends on the previous), so it
22 * cannot be parallelized or precomputed; it binds to the block via the
23 * hash-derived stream and divisor.
24 *
25 * Construction properties (measured, test/delay/delaybench.cpp):
26 * - per-step cost is a handful of 64-bit multiplies/adds/subtracts
27 * (Barrett reciprocal estimate, no hardware DIV): ~27 cycles on
28 * Zen 2, and the op mix is uniform across x86/ARM - the wall-time
29 * variance across hardware is essentially the clock-speed ratio
30 * - non-shortcuttable: dividing a PRG stream has no closed form
31 * (unlike 2^B mod d, which is exponentiation-by-squaring)
32 * - verified by recomputation - the verifier redoes the same work
33 * (~60s per block at 2^33 steps; ~10% of one core at 600s blocks)
34 * - latency-bound: GPUs/FPGAs/ASIC throughput cannot shorten a
35 * dependent chain; their per-op latency is not better than a CPU's
36 */
37 38 /** Divisor and stream seed from the previous block hash. */
39 uint64_t DelayDivisor(const uint256& prev_hash);
40 41 /** Compute the delay remainder: `steps` chained long-division words.
42 * Deterministic; ~27 cycles per step on reference hardware. */
43 uint64_t ComputeDelay(const uint256& prev_hash, uint64_t steps);
44 45 /** One schoolbook long-division step (exposed for tests). */
46 uint64_t DelayStep(uint64_t r, uint64_t w, uint64_t d, unsigned __int128 v);
47 48 // Coinbase commitment: OP_RETURN <"LD"> <8-byte LE delay output>.
49 static constexpr uint8_t DELAY_MAGIC_BYTE0 = 0x4c; // 'L'
50 static constexpr uint8_t DELAY_MAGIC_BYTE1 = 0x44; // 'D'
51 static constexpr int NO_DELAY_OUTPUT = -1;
52 53 /** Index of the delay commitment output in the coinbase, or
54 * NO_DELAY_OUTPUT. Last match wins (same convention as the witness
55 * commitment). */
56 int GetDelayOutputIndex(const CTransaction& coinbase);
57 58 /** Extract the committed delay value, or nullopt if malformed. */
59 std::optional<uint64_t> GetDelayOutputValue(const CTxOut& out);
60 61 #endif // LIMENKA_CONSENSUS_DELAY_H
62