Skip to main content

nectar_mantaray/
lib.rs

1//! Mantaray manifest trie for Ethereum Swarm.
2//!
3//! Dedicated to the memory of ldeffenb, whose guidance on manifest generation
4//! made this implementation possible.
5//!
6//! Mantaray is a trie-based manifest structure that maps human-readable paths
7//! (e.g. `index.html`, `img/logo.png`) to content-addressed chunk references.
8//! It supports XOR obfuscation, versioned binary serialisation (v0.1 and v0.2),
9//! and metadata per path.
10//!
11//! # Efficient Partial Updates
12//!
13//! The trie uses lazy loading and dirty-reference tracking so that updating a
14//! single path in a million-entry manifest only re-serialises O(depth) nodes:
15//!
16//! 1. [`Manifest::add`] lazily loads only the affected path branch.
17//! 2. Modified nodes have their reference cleared (dirty flag).
18//! 3. [`Manifest::save`] skips nodes with non-empty references (unmodified).
19//! 4. After save, child forks are dropped from memory.
20//! 5. The next operation lazily reloads from the new state.
21//!
22//! # Unified Store
23//!
24//! Manifest operations use the typed chunk store traits from `nectar_primitives`:
25//! [`SyncChunkGet`](nectar_primitives::store::SyncChunkGet) for loading and
26//! [`SyncChunkPut`](nectar_primitives::store::SyncChunkPut) for saving. This means a single
27//! [`MemoryStore`] can hold both file chunks and manifest trie nodes.
28//!
29//! ```no_run
30//! # use nectar_mantaray::{PlainManifest, Entry, DefaultMemoryStore};
31//! let store = DefaultMemoryStore::new();
32//! let mut manifest: PlainManifest<_> = PlainManifest::new(store);
33//! ```
34//!
35//! # Website Manifests
36//!
37//! Configure index and error documents for Swarm-hosted websites:
38//!
39//! ```no_run
40//! # use nectar_mantaray::{PlainManifest, Entry, metadata, DefaultMemoryStore};
41//! # let store = DefaultMemoryStore::new();
42//! # let mut manifest = PlainManifest::new(store);
43//! manifest.set_index_document("index.html").unwrap();
44//! manifest.set_error_document("404.html").unwrap();
45//! ```
46//!
47//! # Metadata Constants
48//!
49//! Well-known metadata keys are available in the [`metadata`] module:
50//!
51//! ```
52//! use nectar_mantaray::metadata;
53//! assert_eq!(metadata::CONTENT_TYPE, "Content-Type");
54//! ```
55//!
56//! # Upstream-bug workarounds
57//!
58//! Code that exists solely to tolerate a defect in an upstream reference
59//! implementation is tagged with a grep-able `BEE-WORKAROUND(bee#NNNN)`
60//! comment. When the upstream fix lands and downstream consumers have
61//! upgraded past the buggy releases, every site tagged with that issue
62//! number should be removed. Run `git grep -n BEE-WORKAROUND` to enumerate
63//! them.
64
65use nectar_primitives::bmt::DEFAULT_BODY_SIZE;
66use nectar_primitives::chunk::ChunkAddress;
67
68pub mod codec;
69mod constants;
70pub mod entry;
71pub mod error;
72pub mod manifest;
73pub mod manifest_ref;
74pub mod mode;
75pub mod node;
76pub mod obfuscation;
77
78// Re-export constants.
79pub use constants::metadata;
80pub(crate) use constants::*;
81
82// Re-export public types.
83pub use entry::Entry;
84pub use error::{MantarayError, Result};
85pub use manifest::{Manifest, ManifestIter};
86pub use manifest_ref::ManifestRef;
87pub use mode::NodeEntry;
88pub use node::{Fork, Node, NodeType, Prefix};
89pub use obfuscation::ObfuscationKey;
90
91// Re-export typed storage traits from primitives.
92pub use nectar_primitives::DefaultMemoryStore;
93pub use nectar_primitives::store::{MemoryStore, SyncChunkHas};
94
95/// Default manifest type using [`DEFAULT_BODY_SIZE`] and plain mode.
96pub type DefaultManifest<S> = PlainManifest<S, DEFAULT_BODY_SIZE>;
97
98/// Plain manifest: 32-byte refs, no obfuscation.
99pub type PlainManifest<S, const BS: usize = DEFAULT_BODY_SIZE> = Manifest<S, ChunkAddress, BS>;
100
101/// Encrypted manifest: 64-byte refs, random obfuscation key.
102#[cfg(feature = "encryption")]
103pub type EncryptedManifest<S, const BS: usize = DEFAULT_BODY_SIZE> =
104    Manifest<S, nectar_primitives::EncryptedChunkRef, BS>;