pub struct ArtifactExchange { /* private fields */ }Expand description
Node-local state of the artifact piece protocol.
Implementations§
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub fn new(
node_id: impl Into<String>,
store: Arc<ArtifactStore>,
config: ExchangeConfig,
) -> Result<Self, ExchangeError>
pub fn new( node_id: impl Into<String>, store: Arc<ArtifactStore>, config: ExchangeConfig, ) -> Result<Self, ExchangeError>
Exchange for node_id over store.
Sourcepub fn set_chain_manager(&mut self, cm: Arc<ChainManager>)
pub fn set_chain_manager(&mut self, cm: Arc<ChainManager>)
Chain transfer outcomes to cm.
Sourcepub fn store(&self) -> &Arc<ArtifactStore> ⓘ
pub fn store(&self) -> &Arc<ArtifactStore> ⓘ
Backing store.
Sourcepub fn config(&self) -> &ExchangeConfig
pub fn config(&self) -> &ExchangeConfig
Configuration.
Sourcepub fn seed_reader(
&self,
reader: &mut dyn Read,
expect: Option<([u8; 32], u64)>,
) -> Result<ArtifactDescriptor, ExchangeError>
pub fn seed_reader( &self, reader: &mut dyn Read, expect: Option<([u8; 32], u64)>, ) -> Result<ArtifactDescriptor, ExchangeError>
Split reader into pieces, store each, and register the artifact.
Streams: at most one piece is in memory. When expect is given
(content hash, size), a mismatch is an error and nothing is
registered.
Sourcepub fn seed_bytes(
&self,
content: &[u8],
) -> Result<ArtifactDescriptor, ExchangeError>
pub fn seed_bytes( &self, content: &[u8], ) -> Result<ArtifactDescriptor, ExchangeError>
Self::seed_reader over an in-memory buffer.
Sourcepub fn descriptor(&self, id: &ArtifactId) -> Option<ArtifactDescriptor>
pub fn descriptor(&self, id: &ArtifactId) -> Option<ArtifactDescriptor>
Verified descriptor by id.
Sourcepub fn is_verified(&self, id: &ArtifactId) -> bool
pub fn is_verified(&self, id: &ArtifactId) -> bool
True when id is verified on this node.
Sourcepub fn resolve(&self, key: &ArtifactKey) -> Option<ArtifactDescriptor>
pub fn resolve(&self, key: &ArtifactKey) -> Option<ArtifactDescriptor>
Verified descriptor by key.
Sourcepub fn have(&self, id: &ArtifactId) -> Option<Bitfield>
pub fn have(&self, id: &ArtifactId) -> Option<Bitfield>
Pieces held locally for a verified or pending artifact, derived from the store.
Sourcepub fn read_to(
&self,
id: &ArtifactId,
sink: &mut dyn FnMut(&[u8]) -> Result<(), ExchangeError>,
) -> Result<u64, ExchangeError>
pub fn read_to( &self, id: &ArtifactId, sink: &mut dyn FnMut(&[u8]) -> Result<(), ExchangeError>, ) -> Result<u64, ExchangeError>
Stream the whole artifact through sink in piece order, checking
every piece and the whole-content hash. Returns the byte count.
Sourcepub fn read_all(&self, id: &ArtifactId) -> Result<Vec<u8>, ExchangeError>
pub fn read_all(&self, id: &ArtifactId) -> Result<Vec<u8>, ExchangeError>
Whole artifact in memory (bounded by materialize_limit).
Sourcepub fn is_servable(&self, d: &ArtifactDescriptor) -> bool
pub fn is_servable(&self, d: &ArtifactDescriptor) -> bool
Governance: may d be listed in broadcast facts and seeded? It must
be verified on this node (its pieces assemble to its content_hash),
a signed manifest that verified here must list it, the redistribution
policy must allow it for Audience::Advertise, and neither the
package, its signers nor the content hash may be revoked. Serving a
particular peer is Self::is_servable_to.
Sourcepub fn is_servable_to(
&self,
d: &ArtifactDescriptor,
audience: &Audience<'_>,
) -> bool
pub fn is_servable_to( &self, d: &ArtifactDescriptor, audience: &Audience<'_>, ) -> bool
Self::is_servable for a specific audience.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub fn seed_package(
&self,
manifest: &[u8],
anchors: &TrustAnchors,
open: &mut dyn FnMut(&FileRef) -> Result<Box<dyn Read>>,
) -> Result<ExchangedPackage, PackageExchangeError>
pub fn seed_package( &self, manifest: &[u8], anchors: &TrustAnchors, open: &mut dyn FnMut(&FileRef) -> Result<Box<dyn Read>>, ) -> Result<ExchangedPackage, PackageExchangeError>
Seed a signed package. open yields each listed file’s bytes; files
are streamed, so large payloads never sit in memory whole.
Sourcepub fn seed_package_in(
&self,
manifest: &[u8],
anchors: &TrustAnchors,
kinds: &KindRegistry,
open: &mut dyn FnMut(&FileRef) -> Result<Box<dyn Read>>,
) -> Result<ExchangedPackage, PackageExchangeError>
pub fn seed_package_in( &self, manifest: &[u8], anchors: &TrustAnchors, kinds: &KindRegistry, open: &mut dyn FnMut(&FileRef) -> Result<Box<dyn Read>>, ) -> Result<ExchangedPackage, PackageExchangeError>
Self::seed_package against a caller-supplied kind registry.
Sourcepub fn seed_package_dir(
&self,
dir: &Path,
anchors: &TrustAnchors,
) -> Result<ExchangedPackage, PackageExchangeError>
pub fn seed_package_dir( &self, dir: &Path, anchors: &TrustAnchors, ) -> Result<ExchangedPackage, PackageExchangeError>
Self::seed_package from an unpacked package directory.
Sourcepub fn seed_package_dir_in(
&self,
dir: &Path,
anchors: &TrustAnchors,
kinds: &KindRegistry,
) -> Result<ExchangedPackage, PackageExchangeError>
pub fn seed_package_dir_in( &self, dir: &Path, anchors: &TrustAnchors, kinds: &KindRegistry, ) -> Result<ExchangedPackage, PackageExchangeError>
Self::seed_package_dir against a caller-supplied kind registry.
Sourcepub fn seed_package_dir_manifest(
&self,
dir: &Path,
manifest: &[u8],
anchors: &TrustAnchors,
kinds: &KindRegistry,
) -> Result<ExchangedPackage, PackageExchangeError>
pub fn seed_package_dir_manifest( &self, dir: &Path, manifest: &[u8], anchors: &TrustAnchors, kinds: &KindRegistry, ) -> Result<ExchangedPackage, PackageExchangeError>
Self::seed_package_dir_in for a caller that already read the
manifest bytes from dir (so the manifest is read once). manifest
must be the content of dir’s cogpkg.json; it is verified here.
Sourcepub async fn fetch_package(
&self,
peers: &mut PeerSet,
manifest_hash: &str,
anchors: &TrustAnchors,
) -> Result<ExchangedPackage, PackageExchangeError>
pub async fn fetch_package( &self, peers: &mut PeerSet, manifest_hash: &str, anchors: &TrustAnchors, ) -> Result<ExchangedPackage, PackageExchangeError>
Fetch a signed package by its manifest hash. Signatures are checked before any file is requested; each file must match its pinned size and hash. Once the manifest verifies, this node may serve the listed files it holds verified.
Sourcepub async fn fetch_package_in(
&self,
peers: &mut PeerSet,
manifest_hash: &str,
anchors: &TrustAnchors,
kinds: &KindRegistry,
) -> Result<ExchangedPackage, PackageExchangeError>
pub async fn fetch_package_in( &self, peers: &mut PeerSet, manifest_hash: &str, anchors: &TrustAnchors, kinds: &KindRegistry, ) -> Result<ExchangedPackage, PackageExchangeError>
Self::fetch_package against a caller-supplied kind registry. A
node that places a registered non-cog kind from a peer must use this:
with the builtin registry the kind is refused, failing closed.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub async fn serve(
&self,
stream: &mut dyn MeshStream,
peer: &str,
) -> Result<ServeStats, ExchangeError>
pub async fn serve( &self, stream: &mut dyn MeshStream, peer: &str, ) -> Result<ServeStats, ExchangeError>
Serve one peer until it closes the stream. Only pieces of servable
artifacts (Self::is_servable) are sent. An oversize or
malformed frame ends the session with an error, and so does a peer
that sends nothing for serve_idle_timeout.
peer is only a claimed id (the peer is ServePeer::unverified):
with a policy that serves verified peers only, nothing is served. Use
Self::serve_as when admission authenticated the peer.
Sourcepub async fn serve_as(
&self,
stream: &mut dyn MeshStream,
who: &ServePeer,
) -> Result<ServeStats, ExchangeError>
pub async fn serve_as( &self, stream: &mut dyn MeshStream, who: &ServePeer, ) -> Result<ServeStats, ExchangeError>
Self::serve for a peer whose identity the caller has (or has not)
verified: the redistribution policy sees peer for every request.
Sourcepub async fn serve_frame(
&self,
stream: &mut dyn MeshStream,
peer: &str,
raw: &[u8],
stats: &mut ServeStats,
) -> Result<(), ExchangeError>
pub async fn serve_frame( &self, stream: &mut dyn MeshStream, peer: &str, raw: &[u8], stats: &mut ServeStats, ) -> Result<(), ExchangeError>
Serve one frame already read from stream, for sessions that carry
the piece protocol beside other traffic on one stream (the
workload.ctl fetch-before-load, mesh-placement-12). Same rules as
Self::serve: only servable artifacts are sent.
Sourcepub async fn serve_frame_as(
&self,
stream: &mut dyn MeshStream,
who: &ServePeer,
raw: &[u8],
stats: &mut ServeStats,
) -> Result<(), ExchangeError>
pub async fn serve_frame_as( &self, stream: &mut dyn MeshStream, who: &ServePeer, raw: &[u8], stats: &mut ServeStats, ) -> Result<(), ExchangeError>
Self::serve_frame with the peer’s verified-ness stated.
Sourcepub async fn fetch(
&self,
peers: &mut PeerSet,
key: ArtifactKey,
) -> Result<FetchOutcome, FetchError>
pub async fn fetch( &self, peers: &mut PeerSet, key: ArtifactKey, ) -> Result<FetchOutcome, FetchError>
Fetch key from peers with the v1 SequentialScheduler.
Sourcepub async fn fetch_with(
&self,
peers: &mut PeerSet,
key: ArtifactKey,
scheduler: &mut dyn PieceScheduler,
) -> Result<FetchOutcome, FetchError>
pub async fn fetch_with( &self, peers: &mut PeerSet, key: ArtifactKey, scheduler: &mut dyn PieceScheduler, ) -> Result<FetchOutcome, FetchError>
Fetch key, trying each live peer in turn until every piece is
held and the whole content verifies. Pieces already held are never
requested, so a repeated call resumes an interrupted transfer. A
peer whose pieces do not assemble to its declared content is dropped
and its descriptor discarded. The outcome (verified or failed) is
chained as artifact.fetch.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub async fn swarm_fetch(
self: &Arc<Self>,
dialer: Arc<dyn PeerDialer>,
candidates: Vec<PeerCandidate>,
key: ArtifactKey,
opts: &SwarmFetchOptions,
) -> Result<FetchOutcome, FetchError>
pub async fn swarm_fetch( self: &Arc<Self>, dialer: Arc<dyn PeerDialer>, candidates: Vec<PeerCandidate>, key: ArtifactKey, opts: &SwarmFetchOptions, ) -> Result<FetchOutcome, FetchError>
Fetch key from several holders at once (see the module docs).
Pieces already held are not requested again, so a repeated call
resumes. candidates are the peers that may hold it (from
crate::mesh_swarm_lookup); banned peers are skipped.
A fetch by content hash trusts nobody’s descriptor: when the pieces a peer’s descriptor describes do not assemble to the content hash, that peer and the sources that vouched for the same descriptor are banned and the fetch carries on with the remaining candidates (up to three attempts), so one liar cannot block it or get honest peers blamed.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub fn set_revocations(&self, list: Arc<RevocationList>) -> bool
pub fn set_revocations(&self, list: Arc<RevocationList>) -> bool
Use list as this node’s revocation list (first call wins).
Sourcepub fn is_revoked(&self, content_hash: &[u8; 32]) -> bool
pub fn is_revoked(&self, content_hash: &[u8; 32]) -> bool
True when the content hash is revoked, or every package that allowed it (or those packages’ signers) is. A package revoked while another, unrevoked one still lists the same content leaves the content allowed.
Sourcepub fn apply_revocations(&self) -> Vec<RevokedArtifact>
pub fn apply_revocations(&self) -> Vec<RevokedArtifact>
Apply the revocation list to everything held: drop each revoked
grant; when no grant is left for a content hash, evict its bytes (and
any partial copy), and chain artifact.revoke and artifact.evict.
Safe to call repeatedly.
Revocation evicts even pinned cache entries (the bytes are removed
and serving is blocked). This sweep does not touch a workload that is
already running from them; stopping those is the host’s job
(WorkloadHostService::enforce_revocations), which the daemon runs
after every applied revocation.
Revocation is monotonic mesh-wide: entries are only ever added, by an
operator command or a signed notice, and a notice is re-flooded to
every peer. Removing one locally (unrevoke_subject) is undone by the
next notice a peer re-sends; to lift a revocation, clear the list on
every node or issue the package under a new key.
Sourcepub fn ban_peer(&self, peer: &str, reason: &str) -> bool
pub fn ban_peer(&self, peer: &str, reason: &str) -> bool
Ban peer: no more fetching from it or serving it. Returns true if
newly banned (chained as artifact.peer_ban).
Sourcepub fn unban_peer(&self, peer: &str) -> bool
pub fn unban_peer(&self, peer: &str) -> bool
Lift a ban. Returns true if the peer was banned.
Sourcepub fn banned_peers(&self) -> Vec<(String, String)>
pub fn banned_peers(&self) -> Vec<(String, String)>
Banned peers and why.
Sourcepub fn link_stats(&self) -> &LinkStats
pub fn link_stats(&self) -> &LinkStats
Measured link speeds to peers.
Sourcepub fn pending_bytes(&self) -> u64
pub fn pending_bytes(&self) -> u64
Bytes of downloads in progress (what their descriptors claim).
Sourcepub fn servable_artifacts(&self) -> Vec<ArtifactDescriptor>
pub fn servable_artifacts(&self) -> Vec<ArtifactDescriptor>
Verified artifacts this node may serve (verified, allowed, not revoked).
Sourcepub fn forget(&self, id: &ArtifactId, reason: &str) -> Option<Forgotten>
pub fn forget(&self, id: &ArtifactId, reason: &str) -> Option<Forgotten>
Remove id (verified or pending) and the blobs no other artifact
lists. The grant is kept, so a later fetch can seed it again;
revocation drops the grant itself. Chains artifact.evict.
Only blobs this exchange created and nobody else has stored since
(store reference count 1) are removed: the store is shared with
package verification and installed workloads, which may hold the same
bytes. A pinned cache entry is not forgotten, except for revoked.
Sourcepub fn held_capabilities(
&self,
model_shards: &HashSet<[u8; 32]>,
) -> Vec<Capability>
pub fn held_capabilities( &self, model_shards: &HashSet<[u8; 32]>, ) -> Vec<Capability>
Capabilities for what this node can serve, to merge into its facts:
store.artifact.<16 hex of content hash> per artifact (attrs
content, size) and, for content hashes in model_shards,
model.present with the shard list. Held artifacts are probed: this
node verified them itself.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub async fn who_has(
self: &Arc<Self>,
dialer: Arc<dyn PeerDialer>,
peers: &[PeerCandidate],
key: ArtifactKey,
) -> Vec<Holder>
pub async fn who_has( self: &Arc<Self>, dialer: Arc<dyn PeerDialer>, peers: &[PeerCandidate], key: ArtifactKey, ) -> Vec<Holder>
Ask peers whether they hold key. Peers that refuse, fail or are
banned are left out. Sorted by peer id.
Sourcepub async fn find_holders(
self: &Arc<Self>,
dialer: Arc<dyn PeerDialer>,
facts: &NodeFactsCache,
neighbors: &[PeerCandidate],
key: ArtifactKey,
now: u64,
) -> Vec<PeerCandidate>
pub async fn find_holders( self: &Arc<Self>, dialer: Arc<dyn PeerDialer>, facts: &NodeFactsCache, neighbors: &[PeerCandidate], key: ArtifactKey, now: u64, ) -> Vec<PeerCandidate>
Candidates for key: peers advertising it in their facts plus
neighbors that answer a who_has query now.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub async fn swarm_fetch_package(
self: &Arc<Self>,
dialer: Arc<dyn PeerDialer>,
candidates: &[PeerCandidate],
manifest_hash: &str,
anchors: &TrustAnchors,
opts: &SwarmFetchOptions,
) -> Result<ExchangedPackage, PackageExchangeError>
pub async fn swarm_fetch_package( self: &Arc<Self>, dialer: Arc<dyn PeerDialer>, candidates: &[PeerCandidate], manifest_hash: &str, anchors: &TrustAnchors, opts: &SwarmFetchOptions, ) -> Result<ExchangedPackage, PackageExchangeError>
Fetch a signed package by its manifest hash from candidates.
Sourcepub async fn swarm_fetch_package_in(
self: &Arc<Self>,
dialer: Arc<dyn PeerDialer>,
candidates: &[PeerCandidate],
manifest_hash: &str,
anchors: &TrustAnchors,
opts: &SwarmFetchOptions,
kinds: &KindRegistry,
) -> Result<ExchangedPackage, PackageExchangeError>
pub async fn swarm_fetch_package_in( self: &Arc<Self>, dialer: Arc<dyn PeerDialer>, candidates: &[PeerCandidate], manifest_hash: &str, anchors: &TrustAnchors, opts: &SwarmFetchOptions, kinds: &KindRegistry, ) -> Result<ExchangedPackage, PackageExchangeError>
Self::swarm_fetch_package against a caller-supplied kind registry.
Source§impl ArtifactExchange
impl ArtifactExchange
Sourcepub fn grant_checkout(&self, v: &VerifiedCheckoutGrant)
pub fn grant_checkout(&self, v: &VerifiedCheckoutGrant)
Make the bytes of a verified checkout grant shareable inside the
mesh: one grant per listed BLAKE3, signed by the bound grant key, with
GrantOrigin::Cognitum. A revoked key or hash is skipped by
grant_with, and revocation applies through the usual sweep. This
does not make the bytes runnable (see super::may_run).
Auto Trait Implementations§
impl !Freeze for ArtifactExchange
impl !RefUnwindSafe for ArtifactExchange
impl !UnwindSafe for ArtifactExchange
impl Send for ArtifactExchange
impl Sync for ArtifactExchange
impl Unpin for ArtifactExchange
impl UnsafeUnpin for ArtifactExchange
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more