Strand
Merkle and Bitfield
Merkle tree and bitfield internals for Strand — sparse replication, proof generation, and gap repair across partial replicas.
Purpose
Append-only log with Merkle proofs, bitfields, storage backends, policies, and replication streams.
This page follows the real source shape for Strand and explains the workflow a developer is likely to use first.
Developer workflow
Start from the smallest constructor or builder, perform one meaningful operation, inspect the returned state, then add the relevant policy, storage, or network integration. The examples below should be expanded whenever the crate API changes.
Primary types to know
AllowAllPolicy— models/strand/src/policy.rsBitfield— models/strand/src/bitfield.rsBitfieldIterator— models/strand/src/bitfield.rsFileStorage— models/strand/src/storage.rsHeader— models/strand/src/lib.rsInfo— models/strand/src/storage.rsMemoryStorage— models/strand/src/storage.rsMerkleTree— models/strand/src/merkle_tree.rsNode— models/strand/src/merkle_tree.rsProof— models/strand/src/merkle_tree.rsRangeHandle— models/strand/src/replication_api.rsRangeSpec— models/strand/src/replication_api.rs
Example shape
use strand::{Bitfield, MerkleTree, Node, Strand, StrandConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build a local strand and request a Merkle proof for an interior block.
let dir = tempfile::tempdir()?;
let mut strand = Strand::new(StrandConfig::new().with_storage(dir.path())).await?;
for payload in [b"alpha".as_slice(), b"beta", b"gamma", b"delta"] {
strand.append(payload).await?;
}
let target_seq: u64 = 2;
let proof = strand.proof(target_seq).await?;
let ok = strand.verify_proof(&proof, b"gamma").await?;
assert!(ok, "proof must verify for the original payload");
// Reconstruct a MerkleTree directly from leaf nodes to confirm the public surface.
let mut tree = MerkleTree::new();
for (i, leaf_hash) in [[1u8; 32], [2u8; 32], [3u8; 32], [4u8; 32]].into_iter().enumerate() {
tree.add(Node { index: i as u64, size: 1, hash: leaf_hash });
}
let root = tree.root_hash();
// Bitfield tracks which sequence numbers a peer has. Mark the first three present
// and ask for the next missing slot — replication uses this to schedule fetches.
let mut have = Bitfield::with_capacity(8);
have.set_range(0, 3, true);
let next_missing = have.first_unset();
println!(
"verified seq={} proof_nodes={} tree_root={} peer_have_count={} next_missing={:?}",
target_seq,
proof.nodes.len(),
hex::encode(root),
have.count(),
next_missing,
);
Ok(())
}