Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ members = [
]

[workspace.dependencies]
dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "4db5c36701b8f38c4aea704badb81e3103ed701d" }
dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }
dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "393b612269c158925451235a5d9c0ffa5e2eeed2" }

tokio-metrics = "0.5"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ use std::str::FromStr;
pub struct FFITransactionBuilder {
inner: *mut c_void,
network: FFINetwork,
/// Set by `core_wallet_tx_builder_use_only_added_inputs`. key-wallet takes
/// this per funding call, which the finalizers make internally, so the
/// intent has to be carried here and read when they run.
reservation_only: bool,
}

/// Owned signed-transaction bytes handed across the C ABI as the `out_tx`
Expand Down Expand Up @@ -142,11 +146,13 @@ pub unsafe extern "C" fn core_wallet_tx_builder_finalize(

let signer =
MnemonicResolverCoreSigner::new(core_signer_handle, wallet.wallet_id(), wallet.network());
let finalized = runtime().block_on(wallet.core().finalize_transaction(
let reservation_only = ffi.reservation_only;
let finalized = runtime().block_on(wallet.core().finalize_transaction_with_options(
inner,
account_type.funding_sources(),
account_index,
&signer,
reservation_only,
));
let finalized = unwrap_result_or_return!(finalized);

Expand Down Expand Up @@ -277,11 +283,19 @@ pub unsafe extern "C" fn core_wallet_signed_payment_finalize(
MnemonicResolverCoreSigner::new(core_signer_handle, wallet.wallet_id(), wallet.network());

// Atomic select + reserve + sign in one wallet-manager critical section.
let finalized = runtime().block_on(wallet.core().finalize_transaction(
// `reservation_only` is read off the reclaimed box (never through `builder`,
// whose provenance ends at `Box::from_raw`) and threaded through here for the
// same reason as in the immediate sibling: a host that called
// `core_wallet_tx_builder_use_only_added_inputs` and then finalized a
// DEFERRED payment would otherwise have the restriction silently discarded,
// and the account's UTXOs would be offered to selection after all.
let reservation_only = ffi.reservation_only;
let finalized = runtime().block_on(wallet.core().finalize_transaction_with_options(
inner,
account_type.funding_sources(),
account_index,
&signer,
reservation_only,
));
let finalized = unwrap_result_or_return!(finalized);

Expand Down Expand Up @@ -451,7 +465,11 @@ pub unsafe extern "C" fn core_wallet_tx_builder_new(
network: FFINetwork,
) -> *mut FFITransactionBuilder {
let inner = Box::into_raw(Box::new(TransactionBuilder::new())) as *mut c_void;
Box::into_raw(Box::new(FFITransactionBuilder { inner, network }))
Box::into_raw(Box::new(FFITransactionBuilder {
inner,
network,
reservation_only: false,
}))
}

/// # Safety
Expand Down Expand Up @@ -616,6 +634,32 @@ pub unsafe extern "C" fn core_wallet_tx_builder_set_fee_rate(
PlatformWalletFFIResult::ok()
}

/// Fund the build from the inputs `core_wallet_tx_builder_add_inputs_from_outpoints`
/// supplied, and nothing else.
///
/// Without this, the wallet-aware finalizers offer every unreserved UTXO of the
/// funding account alongside the seeded ones, so seeding a subset does not
/// restrict what gets selected. A caller draining an account in batches that
/// each stay under the standard-transaction input limit needs this, or every
/// batch sees the whole account and fails with a too-many-inputs error.
///
/// Honoured by BOTH finalizers — `core_wallet_tx_builder_finalize` and the
/// deferred `core_wallet_signed_payment_finalize` — so the restriction cannot
/// be lost by picking one submission path over the other. It only removes
/// candidates: the account still takes on the build's reservation bookkeeping
/// and still supplies its change address.
///
/// # Safety
/// `builder` must be a valid, non-destroyed pointer.
#[no_mangle]
pub unsafe extern "C" fn core_wallet_tx_builder_use_only_added_inputs(
builder: *mut FFITransactionBuilder,
) -> PlatformWalletFFIResult {
check_ptr!(builder);
(*builder).reservation_only = true;
PlatformWalletFFIResult::ok()
}

/// # Safety
/// `builder` must be a valid, non-destroyed pointer.
#[no_mangle]
Expand Down
Loading
Loading