pub trait StateStore: Send + Sync {
// Required methods
fn load<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<DownloadState>, DownloadError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn save<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 DownloadState,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn clear<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
// Provided methods
fn record_bad_descriptor<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target_key: &'life1 str,
peer_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn bad_descriptor_peers<'life0, 'life1, 'async_trait>(
&'life0 self,
target_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, DownloadError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Persists DownloadState so a download resumes across pause + process restart.
The orchestrator checkpoints after each range completes and on pause. A resume loads the state and
re-plans; only the ranges NOT in done_ranges are fetched. The trait abstracts the medium so
tests use an InMemoryStateStore and a node uses FileStateStore (or a store-backed one).
Required Methods§
Sourcefn load<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<DownloadState>, DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn load<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<DownloadState>, DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Load the persisted state for key, or None if there is no checkpoint yet.
Sourcefn save<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 DownloadState,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn save<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 DownloadState,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Persist state (overwriting any prior checkpoint for its key).
Sourcefn clear<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn clear<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete the checkpoint for key (called after a successful, finalized download).
Provided Methods§
Sourcefn record_bad_descriptor<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target_key: &'life1 str,
peer_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn record_bad_descriptor<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target_key: &'life1 str,
peer_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Remember that peer_id supplied a descriptor for target_key that failed a final integrity
gate, so a later call — or a later PROCESS — does not pay for the same lie again.
Demotion within one pull is not enough: the holder order is deterministic, so a fresh call, a
retry, or a restart re-asks the same liars from scratch, each paying up to
MAX_DESCRIPTOR_ATTEMPTS full pull attempts in bandwidth and staging disk (#1611).
A verdict is advisory and decays (BAD_DESCRIPTOR_TTL); it must never become a denial
primitive, so a caller consults it to ORDER/FILTER descriptor sources and falls back to the
full holder set rather than giving up. Demoted holders stay fully usable for CHUNK fetches —
chunk bytes are independently hash-attributed, so excluding them would cost availability for no
integrity gain.
The default is a no-op, so an existing StateStore keeps compiling and simply forgets
reputation between calls (the pre-#1611 behaviour — an efficiency loss, never a correctness one).
Sourcefn bad_descriptor_peers<'life0, 'life1, 'async_trait>(
&'life0 self,
target_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn bad_descriptor_peers<'life0, 'life1, 'async_trait>(
&'life0 self,
target_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, DownloadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
The peers with a still-live record_bad_descriptor verdict for
target_key. The default returns none (this store keeps no reputation).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".