diff --git a/doc/API.md b/doc/API.md index 6de9ee6a..11420eff 100644 --- a/doc/API.md +++ b/doc/API.md @@ -188,13 +188,13 @@ vault's state). #### Presigned txs -| Field | Type | Description | -| ------------------- | -------- | ---------------------------------------------------------------------------------------------- | -| `vault_outpoint` | string | The vault deposit transaction outpoint. | -| `unvault` | string | The Unvaulting transaction PSBT (base64 encoded) | -| `cancel` | string | The Cancel transaction PSBT (base64 encoded) | -| `emergency` | string | The Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder | -| `unvault_emergency` | string | The Unvault Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder | +| Field | Type | Description | +| ------------------- | -------- | ---------------------------------------------------------------------------------------------- | +| `vault_outpoint` | string | The vault deposit transaction outpoint. | +| `unvault` | string | The Unvaulting transaction PSBT (base64 encoded) | +| `cancel` | string array | List of base64-encoded Cancel transactions PSBT | +| `emergency` | string | The Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder | +| `unvault_emergency` | string | The Unvault Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder | ### `listonchaintransactions` diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 83ef8fc8..4e134933 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1505,7 +1505,7 @@ pub struct RevocationTransactions { pub struct ListPresignedTxEntry { pub vault_outpoint: OutPoint, pub unvault: UnvaultTransaction, - pub cancel: CancelTransaction, + pub cancel: [CancelTransaction; 5], /// Always None if not stakeholder pub emergency: Option, /// Always None if not stakeholder diff --git a/src/commands/utils.rs b/src/commands/utils.rs index 8a90487a..f81db880 100644 --- a/src/commands/utils.rs +++ b/src/commands/utils.rs @@ -8,9 +8,9 @@ use crate::{ }, database::{ interface::{ - db_cancel_transaction, db_emer_transaction, db_signed_emer_txs, db_signed_unemer_txs, - db_unvault_emer_transaction, db_unvault_transaction, db_vault_by_deposit, db_vaults, - db_vaults_with_txids_in_period, + db_cancel_transaction_by_txid, db_emer_transaction, db_signed_emer_txs, + db_signed_unemer_txs, db_unvault_emer_transaction, db_unvault_transaction, + db_vault_by_deposit, db_vaults, db_vaults_with_txids_in_period, }, schema::DbVault, DatabaseError, @@ -25,7 +25,7 @@ use revault_tx::{ Transaction as BitcoinTransaction, Txid, }, miniscript::DescriptorTrait, - transactions::RevaultTransaction, + transactions::{transaction_chain_manager, RevaultTransaction}, }; use std::{ @@ -161,10 +161,23 @@ pub fn presigned_txs( .expect("Database must be available")? .psbt .assert_unvault(); - let cancel = db_cancel_transaction(db_path, db_vault.id) - .expect("Database must be available")? - .psbt - .assert_cancel(); + let (_, cancel_batch) = transaction_chain_manager( + db_vault.deposit_outpoint, + db_vault.amount, + &revaultd.deposit_descriptor, + &revaultd.unvault_descriptor, + &revaultd.cpfp_descriptor, + db_vault.derivation_index, + &revaultd.secp_ctx, + ) + .expect("We wouldn't have put a vault with an invalid chain in DB"); + let mut cancel = cancel_batch.all_feerates(); + for cancel_tx in cancel.iter_mut() { + *cancel_tx = db_cancel_transaction_by_txid(db_path, &cancel_tx.txid()) + .expect("Database must always be available")? + .psbt + .assert_cancel(); + } let mut emergency = None; let mut unvault_emergency = None; diff --git a/tests/test_framework/revault_network.py b/tests/test_framework/revault_network.py index ceb52c2d..28b39c49 100644 --- a/tests/test_framework/revault_network.py +++ b/tests/test_framework/revault_network.py @@ -454,11 +454,12 @@ def signed_unvault_psbt(self, deposit, derivation_index): def signed_cancel_psbt(self, deposit, derivation_index): """Get the fully-signed Cancel transaction for this deposit. + This picks the lowest feerate version. This will raise if we don't have all the signatures. """ psbt_str = self.stks()[0].rpc.listpresignedtransactions([deposit])[ "presigned_transactions" - ][0]["cancel"] + ][0]["cancel"][0] psbt = serializations.PSBT() psbt.deserialize(psbt_str) diff --git a/tests/test_rpc.py b/tests/test_rpc.py index ee5279c1..403c1740 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -1080,13 +1080,13 @@ def test_revault_command(revault_network, bitcoind, executor): == len(stks[0].rpc.listvaults(["funded"])["vaults"]) ) - # And the deposit txid is the Cancel txid + # And the deposit txid is the lowest-feerate Cancel's txid for v in stks[0].rpc.listvaults(["canceled"])["vaults"]: deposit = f"{v['txid']}:{v['vout']}" cancel_psbt = serializations.PSBT() cancel_b64 = stks[0].rpc.listpresignedtransactions([deposit])[ "presigned_transactions" - ][0]["cancel"] + ][0]["cancel"][0] cancel_psbt.deserialize(cancel_b64) cancel_psbt.tx.calc_sha256()