Skip to content

Commit 6cb5913

Browse files
committed
Merge #393: multi-Cancel revaultd
ae94b9a Adapt the doc single-cancel wording to multi-cancel (Antoine Poinsot) 32a7ec5 db: remove the db_cancel_transaction routine (Antoine Poinsot) 9465c35 commands: adapt the result of 'listpresignedtxs' to multiple Cancel txs (Antoine Poinsot) ae2839d commands: remove the unit test of listpresigned txs (Antoine Poinsot) 5caa118 commands: update [get,set]revocationtxs flow for all Cancel transactions (Antoine Poinsot) 175478b qa: update miradord and cosignerd to the new message serialization (Antoine Poinsot) f5a2162 Share all Cancel transactions' signatures with the watchtowers (Antoine Poinsot) 74c2f1c rpc: over-simplified adaptation of 'revault' command to multi-Cancel (Antoine Poinsot) 8683a03 poller: notice any possible Cancel when an Unvault is spent. (Antoine Poinsot) a0585c5 poller: adapt Cancel rebroadcast to multi-Cancel (Antoine Poinsot) 30d2d20 poller: adapt Cancel confirmation tracking to multi-Cancel (Antoine Poinsot) effb3f7 bitcoind: store all the Cancel transactions on vault confirmation (Antoine Poinsot) b9b1727 db: simplify the unsigned presigned txs storage (Antoine Poinsot) 410a627 Update revault_tx and revault_net (Antoine Poinsot) Pull request description: This implements revault/practical-revault#119. We adapt all components to use multi-Cancel: - Sharing and fetching the signatures for all the Cancel transactions - Monitoring the chain for any of the Cancel transaction - Changing the various interfaces to have all Cancel transactions instead of a single one Feedback on the new RPC API would be welcome: i preferred a list of Cancel instead of a mapping from feerate to Cancel. We still don't chose the Cancel to broadcast depending on the fee estimation in `revault`. ACKs for top commit: edouardparis: ACK ae94b9a Tree-SHA512: cb2e1b5a13f84188be7897a239b045b5a6ac307af8f9843cc56d689f51d50decf5510b1ea52c3832bed5b937f6a788e555c46bf04a2612553c5ba89fcaacfe4f
2 parents 26ebc35 + ae94b9a commit 6cb5913

File tree

20 files changed

+633
-865
lines changed

20 files changed

+633
-865
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/API.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ Retrieve the status of the servers, such as the coordinator, the cosigners, the
121121
| 5 | `active` | Everyone signed and shared the Unvault transaction signature for this vault |
122122
| 6 | `unvaulting` | The vault has its unvault tx broadcasted |
123123
| 7 | `unvaulted` | The vault has its unvault tx confirmed |
124-
| 8 | `cancelling` | The vault has its cancel tx broadcasted, funds are sent to an other vault |
125-
| 9 | `cancelled` | The vault has its cancel tx confirmed, funds are in an other vault |
124+
| 8 | `cancelling` | The vault has one cancel tx broadcasted, funds are sent to an other vault |
125+
| 9 | `cancelled` | The vault has one cancel tx confirmed, funds are in an other vault |
126126
| 4 / 8 | `emergency_vaulting` | The vault has its emergency tx broadcasted, funds are sent to the Deep Emergency Vault |
127127
| 5 / 9 | `emergency_vaulted` | The vault has its emergency tx confirmed, funds are in the Deep Emergency Vault |
128128
| 8 | `spendable` | The vault has its unvault tx timelock expired and can be spent |
@@ -188,13 +188,13 @@ vault's state).
188188

189189
#### Presigned txs
190190

191-
| Field | Type | Description |
192-
| ------------------- | -------- | ---------------------------------------------------------------------------------------------- |
193-
| `vault_outpoint` | string | The vault deposit transaction outpoint. |
194-
| `unvault` | string | The Unvaulting transaction PSBT (base64 encoded) |
195-
| `cancel` | string | The Cancel transaction PSBT (base64 encoded) |
196-
| `emergency` | string | The Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder |
197-
| `unvault_emergency` | string | The Unvault Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder |
191+
| Field | Type | Description |
192+
| ------------------- | -------- | ---------------------------------------------------------------------------------------------- |
193+
| `vault_outpoint` | string | The vault deposit transaction outpoint. |
194+
| `unvault` | string | The Unvaulting transaction PSBT (base64 encoded) |
195+
| `cancel` | string array | List of base64-encoded Cancel transactions PSBT |
196+
| `emergency` | string | The Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder |
197+
| `unvault_emergency` | string | The Unvault Emergency transaction PSBT (base64 encoded), or `null` if we are not a stakeholder |
198198

199199

200200
### `listonchaintransactions`
@@ -250,11 +250,11 @@ known and confirmed ([`funded`](#vault-statuses)) vault.
250250

251251
#### Response
252252

253-
| Field | Type | Description |
254-
| ---------------------- | ------ | ----------------------------------------------------------- |
255-
| `cancel_tx` | string | Base64-encoded Cancel transaction PSBT |
256-
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
257-
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |
253+
| Field | Type | Description |
254+
| ---------------------- | ------------ | ----------------------------------------------------------- |
255+
| `cancel_txs` | string array | List of the base64-encoded Cancel transactions PSBTs |
256+
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
257+
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |
258258

259259

260260
### `revocationtxs`
@@ -265,12 +265,12 @@ See the [flows](#stakeholder-flows) for more information.
265265

266266
#### Request
267267

268-
| Field | Type | Description |
269-
| ---------------------- | ------ | ----------------------------------------------------------- |
270-
| `outpoint` | string | Deposit outpoint of the vault |
271-
| `cancel_tx` | string | Base64-encoded Cancel transaction PSBT |
272-
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
273-
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |
268+
| Field | Type | Description |
269+
| ---------------------- | ------------ | ----------------------------------------------------------- |
270+
| `outpoint` | string | Deposit outpoint of the vault |
271+
| `cancel_txs` | string array | List of base64-encoded Cancel transactions PSBTs |
272+
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
273+
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |
274274

275275

276276
#### Response

src/bitcoind/poller.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
bitcoind::{
44
interface::{BitcoinD, DepositsState, SyncInfo, UnvaultsState, UtxoInfo},
55
utils::{
6-
cancel_txid, emer_txid, populate_deposit_cache, populate_unvaults_cache,
6+
cancel_txids, emer_txid, populate_deposit_cache, populate_unvaults_cache,
77
presigned_transactions, unemer_txid, unvault_txid, unvault_txin_from_deposit,
88
vault_deposit_utxo,
99
},
@@ -21,10 +21,10 @@ use crate::{
2121
db_update_first_stage_blockheight_from_unvault_txid, db_update_tip,
2222
},
2323
interface::{
24-
db_broadcastable_spend_transactions, db_canceling_vaults, db_cpfpable_spends,
25-
db_cpfpable_unvaults, db_emering_vaults, db_exec, db_spending_vaults, db_tip,
26-
db_txids_unvaulted_no_bh, db_unemering_vaults, db_unvault_dbtx, db_unvault_transaction,
27-
db_vault_by_deposit, db_vault_by_unvault_txid, db_vaults_dbtx, db_wallet,
24+
db_broadcastable_spend_transactions, db_cpfpable_spends, db_cpfpable_unvaults,
25+
db_emering_vaults, db_exec, db_spending_vaults, db_tip, db_txids_unvaulted_no_bh,
26+
db_unemering_vaults, db_unvault_dbtx, db_unvault_transaction, db_vault_by_deposit,
27+
db_vault_by_unvault_txid, db_vaults_by_status, db_vaults_dbtx, db_wallet,
2828
},
2929
schema::DbVault,
3030
},
@@ -264,9 +264,11 @@ fn mark_confirmed_cancels(
264264
) -> Result<(), BitcoindError> {
265265
let db_path = revaultd.read().unwrap().db_file();
266266

267-
for (db_vault, cancel_tx) in db_canceling_vaults(&db_path)? {
268-
let cancel_txid = cancel_tx.txid();
269-
match maybe_confirm_cancel(&db_path, bitcoind, &db_vault, &cancel_txid) {
267+
for db_vault in db_vaults_by_status(&db_path, VaultStatus::Canceling)? {
268+
let cancel_txid = &db_vault
269+
.final_txid
270+
.expect("Must be there in Canceling state");
271+
match maybe_confirm_cancel(&db_path, bitcoind, &db_vault, cancel_txid) {
270272
Ok(false) => {}
271273
Ok(true) => continue,
272274
Err(e) => {
@@ -278,7 +280,7 @@ fn mark_confirmed_cancels(
278280
}
279281
};
280282

281-
if !bitcoind.is_in_mempool(&cancel_tx.txid())? {
283+
if !bitcoind.is_in_mempool(cancel_txid)? {
282284
// At least, is this transaction still in mempool?
283285
// If it was evicted, downgrade it to `unvaulted`, the polling loop will
284286
// take care of checking its new state immediately.
@@ -438,11 +440,10 @@ impl ToBeCpfped {
438440
}
439441

440442
pub fn fees(&self) -> Amount {
441-
// TODO(revault_tx): fees() should return an Amount!
442-
Amount::from_sat(match self {
443+
match self {
443444
Self::Spend(s) => s.fees(),
444445
Self::Unvault(u) => u.fees(),
445-
})
446+
}
446447
}
447448
}
448449

@@ -832,9 +833,10 @@ fn rebroadcast_transactions(
832833
db_vault.status,
833834
VaultStatus::Canceling | VaultStatus::Canceled
834835
) {
835-
let cancel_txid =
836-
cancel_txid(revaultd, &db_vault).expect("Must be able to derive cancel txid");
837-
if let Err(e) = bitcoind.rebroadcast_wallet_tx(&cancel_txid) {
836+
let cancel_txid = &db_vault
837+
.final_txid
838+
.expect("Must be there for canceling/canceled");
839+
if let Err(e) = bitcoind.rebroadcast_wallet_tx(cancel_txid) {
838840
log::debug!(
839841
"Error re-broadcasting Cancel tx for vault {}: '{}'",
840842
&db_vault.deposit_outpoint,
@@ -1111,7 +1113,7 @@ fn update_tip(
11111113
// Which kind of transaction may spend the Unvault transaction.
11121114
#[derive(Debug)]
11131115
enum UnvaultSpender {
1114-
// The Cancel, spending via the stakeholders path to a new deposit
1116+
// A Cancel, spending via the stakeholders path to a new deposit
11151117
Cancel(Txid),
11161118
// The Spend, any transaction spending via the managers path
11171119
Spend(Txid),
@@ -1135,13 +1137,17 @@ fn unvault_spender(
11351137
))
11361138
})?;
11371139

1138-
// First, check if it was spent by a Cancel, it's cheaper.
1139-
let cancel_txid = cancel_txid(revaultd, &vault)?;
1140-
if bitcoind.is_current(&cancel_txid)? {
1141-
return Ok(Some(UnvaultSpender::Cancel(cancel_txid)));
1140+
// First, check if it was spent by a Cancel, it's cheaper than the Spend and more likely than
1141+
// the UnvaultEmergency.
1142+
let cancel_txids = cancel_txids(revaultd, &vault)?;
1143+
for txid in cancel_txids.iter() {
1144+
if bitcoind.is_current(&txid)? {
1145+
return Ok(Some(UnvaultSpender::Cancel(*txid)));
1146+
}
11421147
}
11431148

1144-
// Second, check if it was spent by an UnvaultEmergency if we are able to, it's as cheap.
1149+
// Second, check if it was spent by an UnvaultEmergency if we are able to, it's cheaper than
1150+
// the Spend.
11451151
let unemer_txid = unemer_txid(revaultd, &vault)?;
11461152
if let Some(unemer_txid) = unemer_txid {
11471153
if bitcoind.is_current(&unemer_txid)? {
@@ -1154,12 +1160,12 @@ fn unvault_spender(
11541160
// FIXME: be smarter, all the information are in the previous call, no need for a
11551161
// second one.
11561162

1157-
// Let's double-check that we didn't fetch the cancel, nor the unemer
1158-
// In theory (read edge cases), the Cancel and UnEmer could have not been
1163+
// Let's double-check that we didn't fetch a cancel, nor the unemer
1164+
// In theory (read edge cases), a Cancel and UnEmer could have not been
11591165
// current at the last bitcoind poll but could be now.
11601166
// Be sure to not wrongly mark a Cancel or UnEmer as a Spend!
1161-
if spender_txid == cancel_txid || Some(spender_txid) == unemer_txid {
1162-
// Alright, the spender is the cancel or the unemer,
1167+
if cancel_txids.contains(&spender_txid) || Some(spender_txid) == unemer_txid {
1168+
// Alright, the spender is a cancel or the unemer,
11631169
// but we just checked and they weren't current. We'll return None
11641170
// so the checker will call this function again.
11651171
return Ok(None);
@@ -1285,7 +1291,8 @@ fn handle_new_deposit(
12851291
outpoint: OutPoint,
12861292
utxo: UtxoInfo,
12871293
) -> Result<(), BitcoindError> {
1288-
if utxo.txo.value <= revault_tx::transactions::DUST_LIMIT {
1294+
// TODO: don't ignore those with the deposit split
1295+
if utxo.txo.value <= revault_tx::transactions::DEPOSIT_MIN_SATS {
12891296
log::info!(
12901297
"Received a deposit that we considered being dust. Ignoring it. \
12911298
Outpoint: '{}', amount: '{}'",
@@ -1383,7 +1390,7 @@ fn handle_confirmed_deposit(
13831390

13841391
let txo_value = utxo.txo.value;
13851392
// emer_tx and unemer_tx are None for managers
1386-
let (unvault_tx, cancel_tx, emer_tx, unemer_tx) =
1393+
let (unvault_tx, cancel_batch, emer_tx, unemer_tx) =
13871394
match presigned_transactions(&revaultd.read().unwrap(), outpoint, utxo) {
13881395
Ok(txs) => txs,
13891396
Err(e) => {
@@ -1403,7 +1410,7 @@ fn handle_confirmed_deposit(
14031410
blockheight,
14041411
blocktime,
14051412
&unvault_tx,
1406-
&cancel_tx,
1413+
&cancel_batch,
14071414
emer_tx.as_ref(),
14081415
unemer_tx.as_ref(),
14091416
)?;

0 commit comments

Comments
 (0)