Skip to content

Commit

Permalink
Merge pull request #518 from interlay/fix/migration-pruned
Browse files Browse the repository at this point in the history
fix: migration for pruned nodes
  • Loading branch information
gregdhill authored Sep 6, 2023
2 parents 57a5e67 + 5870ce0 commit 06fd50b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
4 changes: 2 additions & 2 deletions bitcoin/src/electrs/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct TransactionStatus {
}

// https://github.com/Blockstream/electrs/blob/adedee15f1fe460398a7045b292604df2161adc0/src/rest.rs#L167-L189
#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct TxInValue {
pub txid: Txid,
pub vout: u32,
Expand All @@ -33,7 +33,7 @@ pub struct TxInValue {
}

// https://github.com/Blockstream/electrs/blob/adedee15f1fe460398a7045b292604df2161adc0/src/rest.rs#L239-L270
#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct TxOutValue {
pub scriptpubkey: ScriptBuf,
pub scriptpubkey_asm: String,
Expand Down
25 changes: 24 additions & 1 deletion bitcoin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,11 @@ impl BitcoinCore {

// Make sure signing is successful
if signed_funded_raw_tx.errors.is_some() {
log::warn!(
"Received bitcoin funding errors (complete={}): {:?}",
signed_funded_raw_tx.complete,
signed_funded_raw_tx.errors
);
return Err(Error::TransactionSigningError);
}

Expand Down Expand Up @@ -1092,7 +1097,7 @@ impl BitcoinCoreApi for BitcoinCore {
// filter to only import
// a) payments in the blockchain (not in mempool), and
// b) payments TO the address (as bitcoin core will already know about transactions spending FROM it)
let confirmed_payments_to = all_transactions.into_iter().filter(|tx| {
let confirmed_payments_to = all_transactions.iter().filter(|tx| {
if let Some(status) = &tx.status {
if !status.confirmed {
return false;
Expand All @@ -1113,6 +1118,24 @@ impl BitcoinCoreApi for BitcoinCore {
&[serde_json::to_value(raw_tx)?, serde_json::to_value(raw_merkle_proof)?],
)?;
}
// TODO: remove this migration after the next runtime upgrade
// filter to remove spent funds, the previous wallet migration caused
// signing failures for pruned nodes because they tried to double spend
let confirmed_payments_from = all_transactions.iter().filter(|tx| {
if let Some(status) = &tx.status {
if !status.confirmed {
return false;
}
};
tx.vin
.iter()
.filter_map(|input| input.prevout.clone())
.any(|output| matches!(&output.scriptpubkey_address, Some(addr) if addr == &address))
});
for transaction in confirmed_payments_from {
self.rpc
.call("removeprunedfunds", &[serde_json::to_value(transaction.txid)?])?;
}
}
Ok(())
}
Expand Down
9 changes: 8 additions & 1 deletion vault/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,23 @@ impl VaultIdManager {
}

tracing::info!("Merging wallet for {:?}", vault_id);
let all_addresses = btc_rpc.list_addresses()?;
// issue keys should be imported separately but we need to iterate
// through currency specific wallets to get change addresses
for address in btc_rpc.list_addresses()? {
for address in &all_addresses {
tracing::info!("Found {:?}", address);
// get private key from currency specific wallet
let private_key = btc_rpc.dump_private_key(&address)?;
// import key into main wallet
btc_rpc_shared.import_private_key(&private_key, false)?;
}

if btc_rpc_shared.get_pruned_height().await? != 0 {
// rescan via electrs to import or remove change utxos
// this is required because pruned nodes cannot rescan themselves
btc_rpc_shared.rescan_electrs_for_addresses(all_addresses).await?;
}

tracing::info!("Initializing metrics...");
let metrics = PerCurrencyMetrics::new(&vault_id);
let data = VaultData {
Expand Down

0 comments on commit 06fd50b

Please sign in to comment.