Skip to content
Merged
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
8 changes: 4 additions & 4 deletions Cargo.lock

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

40 changes: 20 additions & 20 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ Retrieve the status of the servers, such as the coordinator, the cosigners, the
| 5 | `active` | Everyone signed and shared the Unvault transaction signature for this vault |
| 6 | `unvaulting` | The vault has its unvault tx broadcasted |
| 7 | `unvaulted` | The vault has its unvault tx confirmed |
| 8 | `cancelling` | The vault has its cancel tx broadcasted, funds are sent to an other vault |
| 9 | `cancelled` | The vault has its cancel tx confirmed, funds are in an other vault |
| 8 | `cancelling` | The vault has one cancel tx broadcasted, funds are sent to an other vault |
| 9 | `cancelled` | The vault has one cancel tx confirmed, funds are in an other vault |
| 4 / 8 | `emergency_vaulting` | The vault has its emergency tx broadcasted, funds are sent to the Deep Emergency Vault |
| 5 / 9 | `emergency_vaulted` | The vault has its emergency tx confirmed, funds are in the Deep Emergency Vault |
| 8 | `spendable` | The vault has its unvault tx timelock expired and can be spent |
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -250,11 +250,11 @@ known and confirmed ([`funded`](#vault-statuses)) vault.

#### Response

| Field | Type | Description |
| ---------------------- | ------ | ----------------------------------------------------------- |
| `cancel_tx` | string | Base64-encoded Cancel transaction PSBT |
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |
| Field | Type | Description |
| ---------------------- | ------------ | ----------------------------------------------------------- |
| `cancel_txs` | string array | List of the base64-encoded Cancel transactions PSBTs |
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |


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

#### Request

| Field | Type | Description |
| ---------------------- | ------ | ----------------------------------------------------------- |
| `outpoint` | string | Deposit outpoint of the vault |
| `cancel_tx` | string | Base64-encoded Cancel transaction PSBT |
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |
| Field | Type | Description |
| ---------------------- | ------------ | ----------------------------------------------------------- |
| `outpoint` | string | Deposit outpoint of the vault |
| `cancel_txs` | string array | List of base64-encoded Cancel transactions PSBTs |
| `emergency_tx` | string | Base64-encoded Emergency transaction PSBT |
| `emergency_unvault_tx` | string | Base64-encoded Unvault Emergency transaction PSBT |


#### Response
Expand Down
63 changes: 35 additions & 28 deletions src/bitcoind/poller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
bitcoind::{
interface::{BitcoinD, DepositsState, SyncInfo, UnvaultsState, UtxoInfo},
utils::{
cancel_txid, emer_txid, populate_deposit_cache, populate_unvaults_cache,
cancel_txids, emer_txid, populate_deposit_cache, populate_unvaults_cache,
presigned_transactions, unemer_txid, unvault_txid, unvault_txin_from_deposit,
vault_deposit_utxo,
},
Expand All @@ -21,10 +21,10 @@ use crate::{
db_update_first_stage_blockheight_from_unvault_txid, db_update_tip,
},
interface::{
db_broadcastable_spend_transactions, db_canceling_vaults, db_cpfpable_spends,
db_cpfpable_unvaults, db_emering_vaults, db_exec, db_spending_vaults, db_tip,
db_txids_unvaulted_no_bh, db_unemering_vaults, db_unvault_dbtx, db_unvault_transaction,
db_vault_by_deposit, db_vault_by_unvault_txid, db_vaults_dbtx, db_wallet,
db_broadcastable_spend_transactions, db_cpfpable_spends, db_cpfpable_unvaults,
db_emering_vaults, db_exec, db_spending_vaults, db_tip, db_txids_unvaulted_no_bh,
db_unemering_vaults, db_unvault_dbtx, db_unvault_transaction, db_vault_by_deposit,
db_vault_by_unvault_txid, db_vaults_by_status, db_vaults_dbtx, db_wallet,
},
schema::DbVault,
},
Expand Down Expand Up @@ -264,9 +264,11 @@ fn mark_confirmed_cancels(
) -> Result<(), BitcoindError> {
let db_path = revaultd.read().unwrap().db_file();

for (db_vault, cancel_tx) in db_canceling_vaults(&db_path)? {
let cancel_txid = cancel_tx.txid();
match maybe_confirm_cancel(&db_path, bitcoind, &db_vault, &cancel_txid) {
for db_vault in db_vaults_by_status(&db_path, VaultStatus::Canceling)? {
let cancel_txid = &db_vault
.final_txid
.expect("Must be there in Canceling state");
match maybe_confirm_cancel(&db_path, bitcoind, &db_vault, cancel_txid) {
Ok(false) => {}
Ok(true) => continue,
Err(e) => {
Expand All @@ -278,7 +280,7 @@ fn mark_confirmed_cancels(
}
};

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

pub fn fees(&self) -> Amount {
// TODO(revault_tx): fees() should return an Amount!
Amount::from_sat(match self {
match self {
Self::Spend(s) => s.fees(),
Self::Unvault(u) => u.fees(),
})
}
}
}

Expand Down Expand Up @@ -832,9 +833,10 @@ fn rebroadcast_transactions(
db_vault.status,
VaultStatus::Canceling | VaultStatus::Canceled
) {
let cancel_txid =
cancel_txid(revaultd, &db_vault).expect("Must be able to derive cancel txid");
if let Err(e) = bitcoind.rebroadcast_wallet_tx(&cancel_txid) {
let cancel_txid = &db_vault
.final_txid
.expect("Must be there for canceling/canceled");
if let Err(e) = bitcoind.rebroadcast_wallet_tx(cancel_txid) {
log::debug!(
"Error re-broadcasting Cancel tx for vault {}: '{}'",
&db_vault.deposit_outpoint,
Expand Down Expand Up @@ -1111,7 +1113,7 @@ fn update_tip(
// Which kind of transaction may spend the Unvault transaction.
#[derive(Debug)]
enum UnvaultSpender {
// The Cancel, spending via the stakeholders path to a new deposit
// A Cancel, spending via the stakeholders path to a new deposit
Cancel(Txid),
// The Spend, any transaction spending via the managers path
Spend(Txid),
Expand All @@ -1135,13 +1137,17 @@ fn unvault_spender(
))
})?;

// First, check if it was spent by a Cancel, it's cheaper.
let cancel_txid = cancel_txid(revaultd, &vault)?;
if bitcoind.is_current(&cancel_txid)? {
return Ok(Some(UnvaultSpender::Cancel(cancel_txid)));
// First, check if it was spent by a Cancel, it's cheaper than the Spend and more likely than
// the UnvaultEmergency.
let cancel_txids = cancel_txids(revaultd, &vault)?;
for txid in cancel_txids.iter() {
if bitcoind.is_current(&txid)? {
return Ok(Some(UnvaultSpender::Cancel(*txid)));
}
}

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

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

let txo_value = utxo.txo.value;
// emer_tx and unemer_tx are None for managers
let (unvault_tx, cancel_tx, emer_tx, unemer_tx) =
let (unvault_tx, cancel_batch, emer_tx, unemer_tx) =
match presigned_transactions(&revaultd.read().unwrap(), outpoint, utxo) {
Ok(txs) => txs,
Err(e) => {
Expand All @@ -1403,7 +1410,7 @@ fn handle_confirmed_deposit(
blockheight,
blocktime,
&unvault_tx,
&cancel_tx,
&cancel_batch,
emer_tx.as_ref(),
unemer_tx.as_ref(),
)?;
Expand Down
Loading