Skip to content

Choosing a period and layer count

Three numbers shape a mint: its rotation period, its number of layers and the size of each layer. The layers and their size are fixed for the mint’s life; the period is set when you create it.

With n layers and a period P:

  • How often a note moves. A note in the last layer is frozen until the next rotation, and each hop lands one layer on. So once a note has reached the last layer it moves at most once per period. Notes in lower layers can make a burst of up to n − 1 − k hops from position k.
  • How long a note lives untouched. A note at position k dies in the (k + 1)-th rotation from now. A note that just arrived sits in the last layer, so it dies in the n-th rotation, within n × P.
  • How often holders must act. A holder who wants to keep a note pays it to a fresh key of its own before its layer is dropped. worgl refresh and the SDKs’ refresh do that for the notes that die at the next rotation, so a holder runs it once per period.
Period Layers A received note, left alone, dies within A note moves at most
1 hour 4 4 hours once an hour
1 day 4 4 days once a day
1 day 8 8 days once a day
1 week 4 4 weeks once a week

The period sets both how fast tokens can circulate and how long they can sit still. A short period suits quotas and credits meant to be used soon; a long one suits tokens people hold for a while.

mint_layer in the policy picks the position new notes are minted into. By default it is the second to last layer: one hop right away, and the longest life that allows a hop. A lower layer gives more hops now and a shorter life; the last layer gives the longest life and no hop until the next rotation.

A layer hands out each of its bits once per generation, so layer_size caps how many notes can enter one generation, minted into it or moved into it, over its whole life. A generation opens as the last layer and takes notes until it reaches the first, about n − 1 periods, or through the first too if mint_layer is 0. Once its bits run out it refuses with layer_full for the rest of that life. Mints are refused for as long as it is the mint layer, so one that fills before it gets there, as the last layer for instance, refuses every mint for the whole period it later spends as the mint layer. Notes in the layer just before a full one cannot be paid or refreshed on their own, since the hop would land in the full one, and so expire with their layer.

Spending or burning a note gives no bit back: a cleared bit means spent, so handing it out again would bring the note back. A burn lowers the outstanding value, but the bits its value took on the way stay used. Every hop moves value to a strictly newer generation, so a unit of value lands in any generation at most once. While the outstanding value plus the value burned from layers not yet dropped, counted in the smallest amount, stays at or below layer_size, layer_full cannot happen. The property tests check both the bound and this guarantee.

To see how close a mint is, compare each layer’s issued with its capacity in GET /v1/mints/{mint}/info.

The ledger stores one bit per note: n × layer_size bits in all. Four layers of 220 bits take 512 KiB and hold over four million notes in flight (measured in the README).

A rotation costs one word write per 64 bits the dropped layer used.

Allowed
Layers 2 to 65,536
layer_size a positive multiple of 64
Layers × layer_size at most 236 bits
mint_layer below the number of layers

worgl-server create-mint takes --layers (default 4), --layer-size (default 1,048,576) and --rotate-every in seconds. Without --rotate-every the mint rotates only when its admin asks. Over HTTP, the same three are ledger.layers, ledger.layer_size and rotate_every in POST /v1/admin/mints; see Running a server.

v0.1Not yet independently security reviewed. Don't use it to hold anything you can't afford to lose.MIT or Apache-2.0