Skip to content

fix(signing): decouple multisign's tx_list borrow from Transaction's lifetime - #359

Open
soloking1412 wants to merge 1 commit into
XRPLF:mainfrom
soloking1412:fix/multisign-lifetime-decoupling
Open

fix(signing): decouple multisign's tx_list borrow from Transaction's lifetime#359
soloking1412 wants to merge 1 commit into
XRPLF:mainfrom
soloking1412:fix/multisign-lifetime-decoupling

Conversation

@soloking1412

Copy link
Copy Markdown

High Level Overview of Change

multisign's signature conflated two independent lifetimes under one parameter 'a: the borrow lifetime of tx_list and T's own Transaction<'a, F> data lifetime. Whenever a caller's T got inferred as 'static (routine when a transaction is built from string literals inside an async block), the borrow of tx_list was forced to 'static too, leaving Box::leak as the only way to call the function. Implements Option A from #306: give the borrow its own lifetime and take a slice instead of &Vec<T>.

// before
pub fn multisign<'a, T, F>(transaction: &mut T, tx_list: &'a Vec<T>) -> XRPLHelperResult<()>

// after
pub fn multisign<'a, 'b, T, F>(transaction: &mut T, tx_list: &'b [T]) -> XRPLHelperResult<()>

'b is the short borrow lifetime; 'a remains T's own data lifetime, now free to be inferred independently. The function body only iterates tx_list once and clones out each tx's first signer — it never stores the reference past the call, so a short, independent borrow is sufficient. &Vec<T>&[T] is also more idiomatic and existing &vec call sites keep working via the standard slice coercion.

Context of Change

Filed as #306 after Box::leak showed up as the only way to satisfy the borrow checker in the multisign integration test added by #298.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Before / After

tests/transactions/multisign_payment.rs previously had to leak the signer-signed-copies Vec to get a &'static Vec<_>:

let signer_signed_copies: &'static Vec<_> =
    Box::leak(Box::new(vec![payment_signed_by_a, payment_signed_by_b]));
xrpl::transaction::multisign(&mut payment, signer_signed_copies)

Now it's a plain local borrow:

let signer_signed_copies = vec![payment_signed_by_a, payment_signed_by_b];
xrpl::transaction::multisign(&mut payment, &signer_signed_copies)

Test Plan

  • cargo test --release: 1314 passed, including the existing unit test in src/transaction/multisign.rs::test.
  • cargo check --tests --features std,json-rpc,helpers,cli,websocket,integration: compiles clean, confirming tests/transactions/multisign_payment.rs no longer needs Box::leak and matches CI's feature set (this test requires a live xrpld node to actually execute, so it wasn't run end-to-end here — only compiled).
  • cargo clippy --all-targets --features std,json-rpc,helpers,cli,websocket,integration and cargo fmt --check: clean on both changed files.

Closes #306

…lifetime

tx_list's borrow lifetime and T's Transaction<'a, F> data lifetime shared
one type parameter, so a T inferred as 'static (routine for transactions
built from string literals in an async block) forced the tx_list borrow to
'static as well. Give the borrow its own lifetime and take a slice instead
of &Vec<T>, per Option A in the issue.

Closes XRPLF#306
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

multisign: decouple tx_list borrow lifetime from T's Transaction<'a> lifetime

1 participant