Component
Batching
Leaves in one aligned subtree can share a proof: a cohort rewrite publishes the subtree before and after, and in one transaction its members can leave, join, rotate keys and pay each other. A detach moves the cohort into an output of its own so that later exits prove a shorter path, but no batch removes the cost of publishing, authorising and paying each leaf that changes.
What a batch costs
Every transition proves some leaves against the committed root and folds their replacements up to a new one. Its cost has three parts, and they behave differently as more leaves share a transaction.
| Part | What it is | vB |
|---|---|---|
| Fixed | the transaction skeleton, the state checks at both ends, the script's reveal | about 470 |
| Per shared level | one level of the fold and one sibling | 32 |
| Per leaf | the 116-byte leaf, its signature, its payout and the script that hashes it | about 100 to 120 |
The fixed part is paid once per transaction. A shared level is paid once per path, so only leaves under a common subtree share it; two random slots share only the few levels near the root. That is why chaining two exits saves so little, and why the operator grafts members into aligned cohorts: the cohort's position is what makes batching possible later.
The cohort rewrite
REWRITE_h replaces the contents of one aligned subtree of
height h. The witness carries the path above the subtree and, for each of its
2h slots, an old element and a new element, each a leaf or an empty
marker. The script rebuilds the old subtree and checks it against the committed
root, rebuilds the new subtree, and folds it up the same path. Within one
transaction a slot can go from a leaf to empty (an exit, paid in full), from
empty to a leaf (a join, funded by another input), or from one leaf to another
(a resize, renewal, key rotation or payment).
Authorisation is per leaf. Every owner whose leaf changes signs, except an owner whose leaf changes only by gaining amount: that exception lets a payment need only the payer's signature, and it cannot be used to change a key or a lease. The operator signs once. A leaf nobody signs for passes through unchanged, so a cohort settles with only its changing members online. An Ark round, by contrast, settles new balances in one transaction only if every member is online to sign, and its tree expires. Because the new slots are published, a join through a rewrite is checked by the script itself, where a graft relies on each joiner's own check.
| Shape | vB per leaf |
|---|---|
| Two separate exits chained in one transaction | 842 |
| Rewrite of 4 slots, every leaf leaves | 366 |
| Rewrite of 16 slots, every leaf leaves | 202 |
| Rewrite of 64 slots, every leaf leaves | 165 |
| Rewrite of 64 slots, every key rotated | 151 |
One UPDATE per leaf instead | 1,030 |
| Operator's sweep of 51 expired leaves, for comparison | 158 |
Sixty-four owners who leave together pay about what the operator pays to
sweep them. A slot that does not change costs about 95 vB: its leaf is published
once, with a one-byte marker in place of the second copy, so a rewrite with
only a few changes beats separate UPDATEs from about two or
three leaves up.
Detaching a cohort
Nothing in a script can refer to an earlier transaction's witness, so the
only way to reuse a proof across transactions is to give the cohort an output of
its own. DETACH_h, authorised by the operator, proves the cohort's
node against the root, empties its slot in the parent, and creates a second tree
output whose root is the cohort's node. The new tree uses the same script set
compiled for depth h, fixed when the parent was created. At depth 16 with a
cohort of 256 slots, the detach costs about 780 vB, and each later exit from
the cohort costs 765 vB instead of 1,020, so the detach pays for itself at the
fourth exit.
The larger effect is on throughput. Every transition of a tree spends the same output, so they queue one behind another, and relay policy caps the queue at 25 unconfirmed transactions before Bitcoin Core 31.0 and at most 64 since. A detached cohort has its own output and its own queue. Detaching is a way to split a deployment when a cohort's members may need to leave quickly, for example channel leaves with HTLCs near their deadlines. Leaf bytes do not change, so channel leaves are unaffected, and vouchers stay valid too: a voucher binds the tree's identifier, which the cohort inherits from its parent.
The floor no batch removes
A leaf that leaves must be published, must authorise its exit, and must be paid: about 100 vB in every shape. A leaf that stays in a rewritten subtree costs about 92. Batching moves the fixed and shared costs out of the way; it leaves this one. The remaining lever is the leaf itself: a leaf format in which an exit reveals only the exit key and amount plus a hash of the other fields would publish about 72 bytes instead of 116, saving about 11 vB per leaf in every shape. That would be a change to the tree format.
REWRITE_h and DETACH_h are built in the FULL, MID and
CCV tiers (CCV in both of its numerics); the sizes on this page are FULL's.
Deeper
- Spec 7.9:
REWRITE_hand its seven rules; 7.10:DETACH_h. - Spec 7.6: composition and shape-specialised multiproofs.
- Spec 10.5: why every transition queues behind the last.
- Spec 11: the measured rewrite and detach sizes.
design/batching.md: the three parts of a transition's cost, and the shapes measured against each other.formal/README.md:rewrite_sound,detach_soundanddetach_member_payable.