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.