trie/trie.go
339 lines
1// Package trie implements the binary Merkle trie of the specification.2//3// Keys are 32 bytes and navigated bit by bit, MSB first (bit 0 is the most4// significant bit of byte 0); left child 0, right child 1. Branches exist5// only where keys diverge (a crit-bit trie), so the shape of the trie — and6// therefore its root hash — is a pure function of the key/value set,7// independent of insertion order.8//9// Leaf hash: SHA256(key ‖ value)10// Branch hash: SHA256(bit_position ‖ aggregate ‖ left_hash ‖ right_hash)11// Empty: [32]byte{0}12//13// bit_position is a uint8, the key bit at which the branch diverges. Storage14// tries (reg, rng, election) carry the number of entries below each branch as15// a big-endian uint64 aggregate, which gives every entry an index — its rank16// in key order, leftmost 0 — via Rank and Select. Plain tries (tx, coin,17// token) omit the aggregate from the hash.18//19// The trie is persistent: every mutation returns a new *Trie sharing20// unmodified subtrees with the old one, which is left untouched. Values are21// treated as immutable byte strings; Insert and Update copy them.22package trie2324import (25"crypto/sha256"26"encoding/binary"27"errors"28)2930// Key is a 32-byte trie key: a public key, or a UTXO or transaction ID.31type Key [32]byte3233// Hash is a 32-byte SHA-256 digest.34type Hash [32]byte3536var (37ErrExists = errors.New("trie: key already present")38ErrNotFound = errors.New("trie: key not found")39)4041// Trie is a persistent binary Merkle trie.42type Trie struct {43root node44counted bool45}4647// NewStorage returns an empty storage trie (branches carry entry counts).48func NewStorage() *Trie { return &Trie{counted: true} }4950// NewPlain returns an empty plain trie (no aggregate in the branch hash).51func NewPlain() *Trie { return &Trie{counted: false} }5253// Counted reports whether this trie hashes entry counts into its branches.54func (t *Trie) Counted() bool { return t.counted }5556type node interface {57hash() Hash58count() uint6459}6061type leaf struct {62key Key63value []byte64h Hash65}6667type branch struct {68pos uint8 // bit at which the children diverge69n uint6470left node71right node72h Hash73}7475func (l *leaf) hash() Hash { return l.h }76func (l *leaf) count() uint64 { return 1 }77func (b *branch) hash() Hash { return b.h }78func (b *branch) count() uint64 { return b.n }7980// LeafHash is SHA256(key ‖ value).81func LeafHash(key Key, value []byte) Hash {82h := sha256.New()83h.Write(key[:])84h.Write(value)85var out Hash86copy(out[:], h.Sum(nil))87return out88}8990// BranchHash is SHA256(bit_position ‖ aggregate ‖ left ‖ right); the91// aggregate (big-endian uint64 count) is present only when counted is true.92func BranchHash(counted bool, pos uint8, count uint64, left, right Hash) Hash {93h := sha256.New()94h.Write([]byte{pos})95if counted {96var c [8]byte97binary.BigEndian.PutUint64(c[:], count)98h.Write(c[:])99}100h.Write(left[:])101h.Write(right[:])102var out Hash103copy(out[:], h.Sum(nil))104return out105}106107func newLeaf(key Key, value []byte) *leaf {108v := make([]byte, len(value))109copy(v, value)110return &leaf{key: key, value: v, h: LeafHash(key, v)}111}112113func (t *Trie) newBranch(pos uint8, left, right node) *branch {114n := left.count() + right.count()115return &branch{116pos: pos,117n: n,118left: left,119right: right,120h: BranchHash(t.counted, pos, n, left.hash(), right.hash()),121}122}123124// bit returns bit pos of key, MSB first.125func bit(k *Key, pos uint8) uint8 {126return (k[pos>>3] >> (7 - pos&7)) & 1127}128129// firstDiff returns the first bit position at which a and b differ.130func firstDiff(a, b *Key) (uint8, bool) {131for i := 0; i < 32; i++ {132if x := a[i] ^ b[i]; x != 0 {133p := i * 8134for x&0x80 == 0 {135x <<= 1136p++137}138return uint8(p), true139}140}141return 0, false142}143144func (t *Trie) with(root node) *Trie { return &Trie{root: root, counted: t.counted} }145146// Root returns the root hash; the zero hash for an empty trie.147func (t *Trie) Root() Hash {148if t.root == nil {149return Hash{}150}151return t.root.hash()152}153154// Count returns the number of entries.155func (t *Trie) Count() uint64 {156if t.root == nil {157return 0158}159return t.root.count()160}161162// findLeaf follows key's bits at each branch and returns the leaf reached,163// which may or may not hold key.164func (t *Trie) findLeaf(key *Key) *leaf {165n := t.root166for {167switch x := n.(type) {168case *leaf:169return x170case *branch:171if bit(key, x.pos) == 0 {172n = x.left173} else {174n = x.right175}176default:177return nil178}179}180}181182// Get returns the value stored at key.183func (t *Trie) Get(key Key) ([]byte, bool) {184l := t.findLeaf(&key)185if l == nil || l.key != key {186return nil, false187}188return l.value, true189}190191// Has reports whether key is present.192func (t *Trie) Has(key Key) bool {193_, ok := t.Get(key)194return ok195}196197// Insert adds a new entry. It fails with ErrExists if key is present.198func (t *Trie) Insert(key Key, value []byte) (*Trie, error) {199if t.root == nil {200return t.with(newLeaf(key, value)), nil201}202l := t.findLeaf(&key)203d, ok := firstDiff(&key, &l.key)204if !ok {205return nil, ErrExists206}207return t.with(t.insertAt(t.root, key, value, d)), nil208}209210// insertAt splices a new leaf into the subtree n at the first node whose211// branch position exceeds d, the bit at which key diverges from every key in212// that subtree.213func (t *Trie) insertAt(n node, key Key, value []byte, d uint8) node {214if b, ok := n.(*branch); ok && b.pos < d {215if bit(&key, b.pos) == 0 {216return t.newBranch(b.pos, t.insertAt(b.left, key, value, d), b.right)217}218return t.newBranch(b.pos, b.left, t.insertAt(b.right, key, value, d))219}220nl := newLeaf(key, value)221if bit(&key, d) == 0 {222return t.newBranch(d, nl, n)223}224return t.newBranch(d, n, nl)225}226227// modify rebuilds the path to key, replacing its leaf with f(leaf); a nil228// result deletes the leaf, collapsing the parent into the sibling.229func (t *Trie) modify(n node, key *Key, f func(*leaf) node) (node, error) {230switch x := n.(type) {231case *leaf:232if x.key != *key {233return nil, ErrNotFound234}235return f(x), nil236case *branch:237if bit(key, x.pos) == 0 {238l, err := t.modify(x.left, key, f)239if err != nil {240return nil, err241}242if l == nil {243return x.right, nil244}245return t.newBranch(x.pos, l, x.right), nil246}247r, err := t.modify(x.right, key, f)248if err != nil {249return nil, err250}251if r == nil {252return x.left, nil253}254return t.newBranch(x.pos, x.left, r), nil255default:256return nil, ErrNotFound257}258}259260// Update replaces the value of an existing entry.261func (t *Trie) Update(key Key, value []byte) (*Trie, error) {262root, err := t.modify(t.root, &key, func(*leaf) node { return newLeaf(key, value) })263if err != nil {264return nil, err265}266return t.with(root), nil267}268269// Delete removes an existing entry.270func (t *Trie) Delete(key Key) (*Trie, error) {271root, err := t.modify(t.root, &key, func(*leaf) node { return nil })272if err != nil {273return nil, err274}275return t.with(root), nil276}277278// Rank returns the index of key in key order (leftmost leaf 0).279func (t *Trie) Rank(key Key) (uint64, bool) {280var idx uint64281n := t.root282for {283switch x := n.(type) {284case *leaf:285if x.key == key {286return idx, true287}288return 0, false289case *branch:290if bit(&key, x.pos) == 0 {291n = x.left292} else {293idx += x.left.count()294n = x.right295}296default:297return 0, false298}299}300}301302// Select returns the entry at index i in key order.303func (t *Trie) Select(i uint64) (Key, []byte, bool) {304if t.root == nil || i >= t.root.count() {305return Key{}, nil, false306}307n := t.root308for {309switch x := n.(type) {310case *leaf:311return x.key, x.value, true312case *branch:313if lc := x.left.count(); i < lc {314n = x.left315} else {316i -= lc317n = x.right318}319}320}321}322323// Walk visits every entry in key order until fn returns false.324func (t *Trie) Walk(fn func(Key, []byte) bool) {325var walk func(node) bool326walk = func(n node) bool {327switch x := n.(type) {328case *leaf:329return fn(x.key, x.value)330case *branch:331return walk(x.left) && walk(x.right)332}333return true334}335if t.root != nil {336walk(t.root)337}338}