1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! The read-only tree sync interface.
mod errors;
mod host;
mod merge;
mod noop;
mod proof;
mod stats;

pub use errors::SyncerError;
pub use host::HostReadSyncer;
pub use merge::merge_verified_subtree;
pub use noop::NoopReadSyncer;
pub use proof::{Proof, ProofBuilder, ProofVerifier, RawProofEntry};
pub use stats::StatsCollector;

use std::any::Any;

use anyhow::Result;

use crate::{
    common::crypto::hash::Hash,
    storage::mkvs::{tree::Root, Prefix},
};

/// Identifies a specific tree and a position within that tree.
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct TreeID {
    /// The Merkle tree root.
    pub root: Root,
    /// The caller's position in the tree structure to allow
    /// returning partial proofs if possible.
    pub position: Hash,
}

/// Request for the SyncGet operation.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
pub struct GetRequest {
    pub tree: TreeID,
    pub key: Vec<u8>,
    #[cbor(optional)]
    pub include_siblings: bool,
}

/// Request for the SyncGetPrefixes operation.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
pub struct GetPrefixesRequest {
    pub tree: TreeID,
    pub prefixes: Vec<Prefix>,
    pub limit: u16,
}

/// Request for the SyncIterate operation.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
pub struct IterateRequest {
    pub tree: TreeID,
    pub key: Vec<u8>,
    pub prefetch: u16,
}

/// Response for requests that produce proofs.
#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
pub struct ProofResponse {
    pub proof: Proof,
}

/// ReadSync is the interface for synchronizing the in-memory cache
/// with another (potentially untrusted) MKVS.
pub trait ReadSync {
    /// Return `self` as an `Any` object, useful for downcasting.
    fn as_any(&self) -> &dyn Any;

    /// Fetch a single key and returns the corresponding proof.
    fn sync_get(&mut self, request: GetRequest) -> Result<ProofResponse>;

    /// Fetch all keys under the given prefixes and returns the corresponding proofs.
    fn sync_get_prefixes(&mut self, request: GetPrefixesRequest) -> Result<ProofResponse>;

    /// Seek to a given key and then fetch the specified number of following items
    /// based on key iteration order.
    fn sync_iterate(&mut self, request: IterateRequest) -> Result<ProofResponse>;
}

#[cfg(test)]
mod test;