pub trait TopicManager {
// Required methods
fn identify_admissible_outputs<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
tx: &'life1 Transaction,
previous_coins: &'life2 [u8],
off_chain_values: Option<&'life3 [u8]>,
mode: SubmitMode,
context: &'life4 TopicAdmittanceContext,
) -> Pin<Box<dyn Future<Output = Result<AdmittanceInstructions, TopicManagerError>> + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait;
fn get_documentation<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = String> + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn get_metadata<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ServiceMetadata> + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn identify_needed_inputs<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_beef: &'life1 [u8],
_off_chain_values: Option<&'life2 [u8]>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Outpoint>, TopicManagerError>> + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn reads_off_chain_values(&self) -> bool { ... }
fn sync_expiry(&self, _script: &LockingScript) -> Option<u64> { ... }
}Expand description
Validates transactions and decides which outputs to admit into a topic.
Implementations are topic-specific — e.g., SHIPTopicManager validates SHIP advertisement PushDrop scripts, while a custom topic manager might validate token transfers.
Required Methods§
Sourcefn identify_admissible_outputs<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
tx: &'life1 Transaction,
previous_coins: &'life2 [u8],
off_chain_values: Option<&'life3 [u8]>,
mode: SubmitMode,
context: &'life4 TopicAdmittanceContext,
) -> Pin<Box<dyn Future<Output = Result<AdmittanceInstructions, TopicManagerError>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn identify_admissible_outputs<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
tx: &'life1 Transaction,
previous_coins: &'life2 [u8],
off_chain_values: Option<&'life3 [u8]>,
mode: SubmitMode,
context: &'life4 TopicAdmittanceContext,
) -> Pin<Box<dyn Future<Output = Result<AdmittanceInstructions, TopicManagerError>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Examine a transaction and return instructions indicating which outputs should be admitted into this topic.
§Arguments
tx— The submitted transaction, parsed ONCE by the engine from the BEEF (Transaction::from_beef(beef, None)) and shared across every topic manager on the submit. Before bsv-low #289 each manager re-parsed the same bytes independently (T+1 parses per/submit). Admission stays byte-format-only: managers still validate the OUTPUT SCRIPTS themselves; only the redundant container parse moved.previous_coins— BEEF data for previously-admitted outputs that this transaction spends (inputs from the same topic). May be empty if no inputs come from this topic.off_chain_values— Optional off-chain context data associated with the transaction (not on-chain).mode— Submission mode: CurrentTx (broadcast + SPV), HistoricalTx (no broadcast), HistoricalTxNoSpv (GASP sync).context: the reference’s fifth argument (context?: TopicAdmittanceContext,dryRun).context.dry_runistruewhen the engine only asks what WOULD be admitted and admits nothing on this call: the GASP walk asks it of every proven node a peer sends, and the anchor check replays a peer’s whole graph that way before it is finalized. A dry run must leave NO durable trace: no storage write, no head advance, no counter an operator reads as an admission. The answer must still be the one a real call would give. A manager that writes on admission MUST read this flag; a manager that holds no state may ignore it.modeis not a substitute: the Cloudflare queue replays real submissions underHistoricalTx, the same mode both dry runs use, so only this flag tells them apart. Every submit passesdry_run: false.
§Returns
AdmittanceInstructions with:
outputs_to_admit: indices of outputs to keep in this topiccoins_to_retain: indices of previous coins to keep (not garbage-collect)
Sourcefn get_documentation<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = String> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_documentation<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = String> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return Markdown documentation for this topic manager.
Sourcefn get_metadata<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ServiceMetadata> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_metadata<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ServiceMetadata> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return metadata identifying this topic manager.
Provided Methods§
Sourcefn identify_needed_inputs<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_beef: &'life1 [u8],
_off_chain_values: Option<&'life2 [u8]>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Outpoint>, TopicManagerError>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn identify_needed_inputs<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_beef: &'life1 [u8],
_off_chain_values: Option<&'life2 [u8]>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Outpoint>, TopicManagerError>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Identify which inputs are needed to validate this transaction for GASP sync.
Called by the GASP storage layer to determine which ancestor transactions need to be fetched from the remote peer.
Default: returns empty (no additional inputs needed beyond what BEEF provides).
Sourcefn reads_off_chain_values(&self) -> bool
fn reads_off_chain_values(&self) -> bool
Whether this manager’s admission READS the transaction’s off-chain
values (lane E1D’s delta fold, L1). The door lands a carried
predecessor first with NO off-chain values (the submit carries only
the successor’s), and the predecessor’s own submit is a dupe after
that, so values its manager would have read are lost for good: the
engine lands nothing first into a topic whose manager answers true
(the successor waits for the predecessor’s own submit). Default
true, so a manager that does not say is never judged without its
values; one that never reads them answers false.
Sourcefn sync_expiry(&self, _script: &LockingScript) -> Option<u64>
fn sync_expiry(&self, _script: &LockingScript) -> Option<u64>
Optional advert expiry for a sync root, in Unix seconds. This does not change submission admission or the treatment of ancestry.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".