Skip to main content

propose_transfer

Function propose_transfer 

Source
pub fn propose_transfer<DbT, ParamsT, InputsT, ChangeT, CommitmentTreeErrT>(
    wallet_db: &mut DbT,
    params: &ParamsT,
    spend_from_account: <DbT as InputSource>::AccountId,
    input_selector: &InputsT,
    change_strategy: &ChangeT,
    request: TransactionRequest,
    confirmations_policy: ConfirmationsPolicy,
    spend_policy: &SpendPolicy,
    lock_inputs: Option<LockRequest>,
    proposed_version: Option<TxVersion>,
) -> Result<Proposal<ChangeT::FeeRule, <DbT as InputSource>::NoteRef>, ProposeTransferErrT<DbT, CommitmentTreeErrT, InputsT, ChangeT>>
where DbT: WalletWrite + InputSource<Error = <DbT as WalletRead>::Error>, <DbT as InputSource>::NoteRef: Copy + Eq + Ord, ParamsT: Parameters + Clone, InputsT: InputSelector<InputSource = DbT>, ChangeT: ChangeStrategy<MetaSource = DbT>,
Expand description

Select transaction inputs, compute fees, and construct a proposal for a transaction or series of transactions that can then be authorized and made ready for submission to the network with create_proposed_transactions.

When lock_inputs is Some(request), every input selected by the returned proposal is locked via OutputLockStore::lock_outputs on behalf of the request’s LockOwner, with an expiry height of target_height + request.for_blocks(), so that the inputs are excluded from selection by subsequent proposals until that height is reached (or until they are explicitly released; see below). When it is None, no locking is performed.

This is the owner- and height-based generalization of the lock_notes: bool parameter originally proposed in zcash/librustzcash#2161.

§Concurrency

Locking is how overlapping proposals for the same account are kept from selecting the same inputs. If a concurrent caller (a different LockOwner) has already locked one of the inputs this proposal selected (a check-then-lock race resolved at the storage layer), locking fails and the error surfaces as ProposalError::InputsLocked identifying the conflicting output; the losing caller should treat this as “the account is busy” and retry. Re-locking under the SAME owner succeeds (an idempotent acquire/extend), so a flow that crashed after locking may safely retry with its original owner token. A caller that abandons a proposal whose inputs it locked should release them with unlock_proposal_inputs under the same owner; locks are otherwise cleared automatically when the inputs are recorded as spent by WalletWrite::store_transactions_to_be_sent, when their expiry height is reached, or via OutputLockStore::clear_locked_outputs.

Note that expiry re-opens the race the lock exists to prevent: if building and proving the transaction takes longer than the requested lock window, the lock expires and a concurrent proposal may select and spend the same inputs. Choose the window conservatively with respect to the worst-case time between proposal creation and transaction storage.