diff --git a/Cargo.lock b/Cargo.lock index e511ec416a0..609a9f14d5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2061,7 +2061,7 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", - "bitcoin 0.30.2", + "bitcoin 0.32.3", "curve25519-dalek", "fedimint-arti-client", "fedimint-core", @@ -2167,7 +2167,7 @@ version = "0.5.0-alpha" dependencies = [ "anyhow", "async-trait", - "bitcoin 0.30.2", + "bitcoin 0.32.3", "clap", "clap_complete", "fedimint-aead", @@ -2205,7 +2205,7 @@ dependencies = [ "aquamarine", "async-stream", "async-trait", - "bitcoin 0.30.2", + "bitcoin 0.32.3", "fedimint-aead", "fedimint-api-client", "fedimint-build", @@ -2216,6 +2216,7 @@ dependencies = [ "itertools 0.13.0", "rand", "reqwest 0.12.8", + "secp256k1 0.27.0", "serde", "serde_json", "strum 0.26.3", @@ -2291,6 +2292,7 @@ dependencies = [ "parity-scale-codec", "rand", "secp256k1 0.27.0", + "secp256k1 0.29.1", "serde", "serde_json", "serdect", @@ -2490,7 +2492,7 @@ name = "fedimint-gateway-cli" version = "0.5.0-alpha" dependencies = [ "anyhow", - "bitcoin 0.30.2", + "bitcoin 0.32.3", "clap", "clap_complete", "fedimint-build", @@ -2775,7 +2777,6 @@ name = "fedimint-load-test-tool" version = "0.5.0-alpha" dependencies = [ "anyhow", - "bitcoin 0.30.2", "clap", "devimint", "fedimint-api-client", @@ -2792,6 +2793,7 @@ dependencies = [ "jsonrpsee-ws-client", "lightning-invoice 0.31.0", "rand", + "secp256k1 0.27.0", "serde", "serde_json", "tokio", @@ -3012,7 +3014,7 @@ name = "fedimint-recoverytool" version = "0.5.0-alpha" dependencies = [ "anyhow", - "bitcoin 0.30.2", + "bitcoin 0.32.3", "clap", "fedimint-build", "fedimint-core", diff --git a/Cargo.toml b/Cargo.toml index 05d494e6f16..4195c89aa95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -169,6 +169,7 @@ reqwest = { version = "0.12.8", features = [ ], default-features = false } ring = "0.17.8" secp256k1 = { version = "0.27.0", default-features = false } +secp256k1_29 = { package = "secp256k1", version = "0.29.0", default-features = false } semver = "1.0.23" serde = { version = "1.0.213", features = ["derive"] } serdect = "0.2.0" diff --git a/fedimint-api-client/Cargo.toml b/fedimint-api-client/Cargo.toml index f935e3ec0ce..519cc723dd2 100644 --- a/fedimint-api-client/Cargo.toml +++ b/fedimint-api-client/Cargo.toml @@ -29,7 +29,7 @@ path = "src/lib.rs" anyhow = { workspace = true } async-trait = { workspace = true } base64 = { workspace = true } -bitcoin30 = { workspace = true } +bitcoin = { workspace = true } fedimint-core = { workspace = true } fedimint-logging = { workspace = true } futures = { workspace = true } diff --git a/fedimint-api-client/src/api/global_api.rs b/fedimint-api-client/src/api/global_api.rs index 1113f8e574f..a93b2f05344 100644 --- a/fedimint-api-client/src/api/global_api.rs +++ b/fedimint-api-client/src/api/global_api.rs @@ -5,8 +5,8 @@ use std::result; use std::sync::Arc; use anyhow::anyhow; -use bitcoin30::hashes::sha256; -use bitcoin30::secp256k1; +use bitcoin::hashes::sha256; +use bitcoin::secp256k1; use fedimint_core::admin_client::{ ConfigGenConnectionsRequest, ConfigGenParamsRequest, ConfigGenParamsResponse, PeerServerParams, }; diff --git a/fedimint-api-client/src/api/mod.rs b/fedimint-api-client/src/api/mod.rs index 67bf1a19f4b..f2dfacba6a4 100644 --- a/fedimint-api-client/src/api/mod.rs +++ b/fedimint-api-client/src/api/mod.rs @@ -9,8 +9,8 @@ use anyhow::anyhow; #[cfg(all(feature = "tor", not(target_family = "wasm")))] use arti_client::{TorAddr, TorClient, TorClientConfig}; use base64::Engine as _; -use bitcoin30::hashes::sha256; -use bitcoin30::secp256k1; +use bitcoin::hashes::sha256; +use bitcoin::secp256k1; pub use error::{FederationError, OutputOutcomeError, PeerError}; use fedimint_core::admin_client::{ ConfigGenConnectionsRequest, ConfigGenParamsRequest, ConfigGenParamsResponse, PeerServerParams, diff --git a/fedimint-cli/Cargo.toml b/fedimint-cli/Cargo.toml index 48c2f08230e..67d4ae9d1c5 100644 --- a/fedimint-cli/Cargo.toml +++ b/fedimint-cli/Cargo.toml @@ -26,7 +26,7 @@ path = "src/lib.rs" [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } -bitcoin30 = { workspace = true } +bitcoin = { workspace = true } clap = { workspace = true } clap_complete = "4.5.35" fedimint-aead = { workspace = true } diff --git a/fedimint-cli/src/client.rs b/fedimint-cli/src/client.rs index 101d87a1da0..fb669cd2300 100644 --- a/fedimint-cli/src/client.rs +++ b/fedimint-cli/src/client.rs @@ -4,12 +4,16 @@ use std::str::FromStr; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use anyhow::{bail, Context}; -use bitcoin30::address::NetworkUnchecked; -use bitcoin30::{secp256k1, Network}; +use bitcoin::address::NetworkUnchecked; +use bitcoin::{secp256k1, Network}; use clap::Subcommand; use fedimint_bip39::Mnemonic; use fedimint_client::backup::Metadata; use fedimint_client::ClientHandleArc; +use fedimint_core::bitcoin_migration::{ + bitcoin30_to_bitcoin32_network, bitcoin32_to_bitcoin30_amount, + bitcoin32_to_bitcoin30_secp256k1_pubkey, bitcoin32_to_bitcoin30_unchecked_address, +}; use fedimint_core::config::{ClientModuleConfig, FederationId}; use fedimint_core::core::{ModuleInstanceId, ModuleKind, OperationId}; use fedimint_core::encoding::Encodable; @@ -155,7 +159,7 @@ pub enum ClientCmd { #[clap(long)] amount: BitcoinAmountOrAll, #[clap(long)] - address: bitcoin30::Address, + address: bitcoin::Address, }, /// Upload the (encrypted) snapshot of mint notes to federation Backup { @@ -340,7 +344,10 @@ pub async fn handle_command( warn!("Command deprecated. Use `fedimint-cli module ln invoice` instead."); let lightning_module = client.get_first_module::()?; let ln_gateway = lightning_module - .get_gateway(gateway_id, force_internal) + .get_gateway( + gateway_id.map(|pk| bitcoin32_to_bitcoin30_secp256k1_pubkey(&pk)), + force_internal, + ) .await?; let lightning_module = client.get_first_module::()?; @@ -398,7 +405,10 @@ pub async fn handle_command( info!("Paying invoice: {bolt11}"); let lightning_module = client.get_first_module::()?; let ln_gateway = lightning_module - .get_gateway(gateway_id, force_internal) + .get_gateway( + gateway_id.map(|pk| bitcoin32_to_bitcoin30_secp256k1_pubkey(&pk)), + force_internal, + ) .await?; let lightning_module = client.get_first_module::()?; @@ -544,10 +554,14 @@ pub async fn handle_command( // If the amount is "all", then we need to subtract the fees from // the amount we are withdrawing BitcoinAmountOrAll::All => { - let balance = - bitcoin30::Amount::from_sat(client.get_balance().await.msats / 1000); + let balance = bitcoin32_to_bitcoin30_amount(&bitcoin::Amount::from_sat( + client.get_balance().await.msats / 1000, + )); let fees = wallet_module - .get_withdraw_fees(address.clone(), balance) + .get_withdraw_fees( + bitcoin32_to_bitcoin30_unchecked_address(&address), + balance, + ) .await?; let amount = balance.checked_sub(fees.amount()); if amount.is_none() { @@ -558,7 +572,10 @@ pub async fn handle_command( BitcoinAmountOrAll::Amount(amount) => ( amount, wallet_module - .get_withdraw_fees(address.clone(), amount) + .get_withdraw_fees( + bitcoin32_to_bitcoin30_unchecked_address(&address), + amount, + ) .await?, ), }; @@ -566,7 +583,14 @@ pub async fn handle_command( info!("Attempting withdraw with fees: {fees:?}"); - let operation_id = wallet_module.withdraw(address, amount, fees, ()).await?; + let operation_id = wallet_module + .withdraw( + bitcoin32_to_bitcoin30_unchecked_address(&address), + amount, + fees, + (), + ) + .await?; let mut updates = wallet_module .subscribe_withdraw_updates(operation_id) @@ -656,7 +680,7 @@ async fn get_note_summary(client: &ClientHandleArc) -> anyhow::Result) { bail!("Guardian public key not found for peer {}", peer_id); }; - if !announcement.verify(SECP256K1, guardian_pub_key) { + if !announcement.verify(SECP256K1, &bitcoin32_to_bitcoin30_secp256k1_pubkey(guardian_pub_key)) { bail!("Failed to verify announcement for peer {}", peer_id); } } diff --git a/fedimint-client/src/backup.rs b/fedimint-client/src/backup.rs index 1fb396ae17c..c18634f979a 100644 --- a/fedimint-client/src/backup.rs +++ b/fedimint-client/src/backup.rs @@ -3,8 +3,11 @@ use std::collections::{BTreeMap, BTreeSet}; use std::io::{Cursor, Error, Read, Write}; use anyhow::{bail, ensure, Context, Result}; -use bitcoin30::secp256k1::{KeyPair, PublicKey, Secp256k1, SignOnly}; +use bitcoin::secp256k1::{Keypair, PublicKey}; use fedimint_api_client::api::DynGlobalApi; +use fedimint_core::bitcoin_migration::{ + bitcoin30_to_bitcoin32_keypair, bitcoin32_to_bitcoin30_keypair, +}; use fedimint_core::core::backup::{ BackupRequest, SignedBackupRequest, BACKUP_REQUEST_MAX_PAYLOAD_SIZE_BYTES, }; @@ -14,6 +17,7 @@ use fedimint_core::encoding::{Decodable, DecodeError, Encodable}; use fedimint_core::module::registry::ModuleDecoderRegistry; use fedimint_derive_secret::DerivableSecret; use fedimint_logging::{LOG_CLIENT, LOG_CLIENT_BACKUP, LOG_CLIENT_RECOVERY}; +use secp256k1::{Secp256k1, SignOnly}; use serde::{Deserialize, Serialize}; use tracing::{debug, info, warn}; @@ -223,14 +227,16 @@ impl EncryptedClientBackup { )?) } - pub fn into_backup_request(self, keypair: &KeyPair) -> Result { + pub fn into_backup_request(self, keypair: &Keypair) -> Result { + let keypair = bitcoin32_to_bitcoin30_keypair(keypair); + let request = BackupRequest { id: keypair.public_key(), timestamp: fedimint_core::time::now(), payload: self.0, }; - request.sign(keypair) + request.sign(&keypair) } pub fn len(&self) -> usize { @@ -402,17 +408,19 @@ impl Client { /// Static version of [`Self::get_derived_backup_signing_key`] for testing /// without creating whole `MintClient` - fn get_derived_backup_signing_key_static(secret: &DerivableSecret) -> KeyPair { - secret - .derive_backup_secret() - .to_secp_key(&Secp256k1::::gen_new()) + fn get_derived_backup_signing_key_static(secret: &DerivableSecret) -> Keypair { + bitcoin30_to_bitcoin32_keypair( + &secret + .derive_backup_secret() + .to_secp_key(&Secp256k1::::gen_new()), + ) } fn get_derived_backup_encryption_key(&self) -> fedimint_aead::LessSafeKey { Self::get_derived_backup_encryption_key_static(&self.root_secret()) } - fn get_derived_backup_signing_key(&self) -> KeyPair { + fn get_derived_backup_signing_key(&self) -> Keypair { Self::get_derived_backup_signing_key_static(&self.root_secret()) } diff --git a/fedimint-client/src/lib.rs b/fedimint-client/src/lib.rs index f44858b46e1..7f728e57027 100644 --- a/fedimint-client/src/lib.rs +++ b/fedimint-client/src/lib.rs @@ -91,7 +91,7 @@ use anyhow::{anyhow, bail, ensure, format_err, Context}; use api::ClientRawFederationApiExt as _; use async_stream::{stream, try_stream}; use backup::ClientBackup; -use bitcoin30::secp256k1; +use bitcoin::secp256k1; use db::event_log::{ self, run_event_log_ordering_task, DBTransactionEventLogExt, Event, EventKind, EventLogEntry, EventLogId, @@ -107,6 +107,7 @@ use fedimint_api_client::api::{ ApiVersionSet, DynGlobalApi, DynModuleApi, FederationApiExt, GlobalFederationApiWithCacheExt, IGlobalFederationApi, WsFederationApi, }; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_secp256k1_pubkey; use fedimint_core::config::{ ClientConfig, FederationId, GlobalClientConfig, JsonClientConfig, ModuleInitRegistry, }; @@ -2076,7 +2077,7 @@ impl Client { dbtx.insert_entry(&ClientConfigKey, &new_config).await; *(self.config.write().await) = new_config; guardian_pub_keys - }; + }.into_iter().map(|(peer_id, pubkey)| (peer_id, bitcoin30_to_bitcoin32_secp256k1_pubkey(&pubkey))).collect(); Result::<_, ()>::Ok(guardian_pub_keys) }), None).await.expect("Will retry forever") diff --git a/fedimint-client/src/module/mod.rs b/fedimint-client/src/module/mod.rs index a722a415c16..766d556d9ae 100644 --- a/fedimint-client/src/module/mod.rs +++ b/fedimint-client/src/module/mod.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use std::{ffi, marker, ops}; use anyhow::{anyhow, bail}; -use bitcoin30::secp256k1::PublicKey; +use bitcoin::secp256k1::PublicKey; use fedimint_api_client::api::DynGlobalApi; use fedimint_core::config::ClientConfig; use fedimint_core::core::{ diff --git a/fedimint-client/src/transaction/builder.rs b/fedimint-client/src/transaction/builder.rs index bc006abc61b..b616c41a424 100644 --- a/fedimint-client/src/transaction/builder.rs +++ b/fedimint-client/src/transaction/builder.rs @@ -1,7 +1,8 @@ use std::sync::Arc; -use bitcoin30::key::KeyPair; -use bitcoin30::secp256k1; +use bitcoin::key::Keypair; +use bitcoin::secp256k1; +use fedimint_core::bitcoin_migration::bitcoin32_to_bitcoin30_schnorr_signature; use fedimint_core::core::{DynInput, DynOutput, IInput, IntoDynInstance, ModuleInstanceId}; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::task::{MaybeSend, MaybeSync}; @@ -21,7 +22,7 @@ use crate::{ #[derive(Clone)] pub struct ClientInput { pub input: I, - pub keys: Vec, + pub keys: Vec, pub amount: Amount, } @@ -294,12 +295,14 @@ impl TransactionBuilder { let nonce: [u8; 8] = rng.gen(); let txid = Transaction::tx_hash_from_parts(&inputs, &outputs, nonce); - let msg = secp256k1::Message::from_slice(&txid[..]).expect("txid has right length"); + let msg = secp256k1::Message::from_digest_slice(&txid[..]).expect("txid has right length"); let signatures = input_keys .into_iter() .flatten() - .map(|keypair| secp_ctx.sign_schnorr(&msg, &keypair)) + .map(|keypair| { + bitcoin32_to_bitcoin30_schnorr_signature(&secp_ctx.sign_schnorr(&msg, &keypair)) + }) .collect(); let transaction = Transaction { diff --git a/fedimint-core/Cargo.toml b/fedimint-core/Cargo.toml index e908a9ba531..5cad877d396 100644 --- a/fedimint-core/Cargo.toml +++ b/fedimint-core/Cargo.toml @@ -52,6 +52,7 @@ miniscript = { workspace = true, features = ["serde"] } parity-scale-codec = { version = "3.6.12", features = ["derive"] } rand = { workspace = true } secp256k1 = { workspace = true, features = ["global-context", "rand-std"] } +secp256k1_29 = { workspace = true, features = ["global-context", "rand-std"] } serde = { workspace = true } serde_json = { workspace = true } serdect = { workspace = true } diff --git a/fedimint-core/src/bitcoin_migration.rs b/fedimint-core/src/bitcoin_migration.rs index 5fe84fd9ec4..dc2f74087af 100644 --- a/fedimint-core/src/bitcoin_migration.rs +++ b/fedimint-core/src/bitcoin_migration.rs @@ -50,46 +50,107 @@ pub fn checked_address_to_unchecked_address( pub fn bitcoin30_to_bitcoin32_invoice( invoice: &lightning_invoice::Bolt11Invoice, ) -> lightning_invoice32::Bolt11Invoice { - bincode::deserialize( - &bincode::serialize(&invoice).expect("Failed to serialize bitcoin30 invoice"), + lightning_invoice32::Bolt11Invoice::from_str(&invoice.to_string()) + .expect("Failed to convert bitcoin30 invoice to bitcoin32 invoice") +} + +pub fn bitcoin30_to_bitcoin32_keypair( + keypair: &bitcoin30::secp256k1::KeyPair, +) -> bitcoin::secp256k1::Keypair { + bitcoin::secp256k1::Keypair::from_secret_key( + bitcoin::secp256k1::SECP256K1, + &bitcoin30_to_bitcoin32_secp256k1_secret_key(&keypair.secret_key()), + ) +} + +pub fn bitcoin32_to_bitcoin30_keypair( + keypair: &bitcoin::secp256k1::Keypair, +) -> bitcoin30::secp256k1::KeyPair { + bitcoin30::secp256k1::KeyPair::from_secret_key( + bitcoin30::secp256k1::SECP256K1, + &bitcoin32_to_bitcoin30_secp256k1_secret_key(&keypair.secret_key()), + ) +} + +pub fn bitcoin30_to_bitcoin32_secp256k1_secret_key( + secret_key: &bitcoin30::secp256k1::SecretKey, +) -> bitcoin::secp256k1::SecretKey { + bitcoin::secp256k1::SecretKey::from_slice(secret_key.as_ref()).expect( + "Failed to convert bitcoin30 secp256k1 secret key to bitcoin32 secp256k1 secret key", + ) +} + +pub fn bitcoin32_to_bitcoin30_secp256k1_secret_key( + secret_key: &bitcoin::secp256k1::SecretKey, +) -> bitcoin30::secp256k1::SecretKey { + bitcoin30::secp256k1::SecretKey::from_slice(secret_key.as_ref()).expect( + "Failed to convert bitcoin32 secp256k1 secret key to bitcoin30 secp256k1 secret key", ) - .expect("Failed to convert bitcoin30 invoice to bitcoin32 invoice") } pub fn bitcoin30_to_bitcoin32_secp256k1_pubkey( pubkey: &bitcoin30::secp256k1::PublicKey, ) -> bitcoin::secp256k1::PublicKey { - bincode::deserialize( - &bincode::serialize(&pubkey).expect("Failed to serialize bitcoin30 secp256k1 pubkey"), - ) - .expect("Failed to convert bitcoin30 secp256k1 pubkey to bitcoin32 secp256k1 pubkey") + bitcoin::secp256k1::PublicKey::from_slice(&pubkey.serialize()) + .expect("Failed to convert bitcoin30 secp256k1 pubkey to bitcoin32 secp256k1 pubkey") } pub fn bitcoin32_to_bitcoin30_secp256k1_pubkey( pubkey: &bitcoin::secp256k1::PublicKey, ) -> bitcoin30::secp256k1::PublicKey { - bincode::deserialize( - &bincode::serialize(&pubkey).expect("Failed to serialize bitcoin32 secp256k1 pubkey"), - ) - .expect("Failed to convert bitcoin32 secp256k1 pubkey to bitcoin30 secp256k1 pubkey") + bitcoin30::secp256k1::PublicKey::from_slice(&pubkey.serialize()) + .expect("Failed to convert bitcoin32 secp256k1 pubkey to bitcoin30 secp256k1 pubkey") } pub fn bitcoin30_to_bitcoin32_address(address: &bitcoin30::Address) -> bitcoin::Address { // The bitcoin crate only allows for deserializing an address as unchecked. // However, we can safely call `assume_checked()` since the input address is // checked. - bincode::deserialize::>( - &bincode::serialize(address).expect("Failed to serialize bitcoin30 address"), - ) - .expect("Failed to convert bitcoin30 address to bitcoin32 address") - .assume_checked() + bitcoin::Address::from_str(&address.to_string()) + .expect("Failed to convert bitcoin30 address to bitcoin32 address") + .assume_checked() +} + +pub fn bitcoin32_to_bitcoin30_unchecked_address( + address: &bitcoin::Address, +) -> bitcoin30::Address { + // The bitcoin crate only implements `ToString` for checked addresses. + // However, this is fine since we're returning an unchecked address. + bitcoin30::Address::from_str(&address.assume_checked_ref().to_string()) + .expect("Failed to convert bitcoin32 address to bitcoin30 address") +} + +pub fn bitcoin30_to_bitcoin32_amount(amount: &bitcoin30::Amount) -> bitcoin::Amount { + bitcoin::Amount::from_sat(amount.to_sat()) +} + +pub fn bitcoin32_to_bitcoin30_amount(amount: &bitcoin::Amount) -> bitcoin30::Amount { + bitcoin30::Amount::from_sat(amount.to_sat()) } pub fn bitcoin30_to_bitcoin32_network(network: &bitcoin30::Network) -> bitcoin::Network { - bincode::deserialize( - &bincode::serialize(network).expect("Failed to serialize bitcoin30 network"), - ) - .expect("Failed to convert bitcoin30 network to bitcoin32 network") + match *network { + bitcoin30::Network::Bitcoin => bitcoin::Network::Bitcoin, + bitcoin30::Network::Testnet => bitcoin::Network::Testnet, + bitcoin30::Network::Signet => bitcoin::Network::Signet, + bitcoin30::Network::Regtest => bitcoin::Network::Regtest, + _ => panic!("There are no other enum cases, this should never be hit."), + } +} + +pub fn bitcoin32_to_bitcoin30_network(network: &bitcoin::Network) -> bitcoin30::Network { + match *network { + bitcoin::Network::Bitcoin => bitcoin30::Network::Bitcoin, + bitcoin::Network::Testnet => bitcoin30::Network::Testnet, + bitcoin::Network::Signet => bitcoin30::Network::Signet, + bitcoin::Network::Regtest => bitcoin30::Network::Regtest, + _ => panic!("There are no other enum cases, this should never be hit."), + } +} + +fn bitcoin30_to_bitcoin32_txid(txid: &bitcoin30::Txid) -> bitcoin::Txid { + bitcoin::Txid::from_str(&txid.to_string()) + .expect("Failed to convert bitcoin30 txid to bitcoin32 txid") } fn bitcoin32_to_bitcoin30_txid(txid: &bitcoin::Txid) -> bitcoin30::Txid { @@ -97,6 +158,13 @@ fn bitcoin32_to_bitcoin30_txid(txid: &bitcoin::Txid) -> bitcoin30::Txid { .expect("Failed to convert bitcoin32 txid to bitcoin30 txid") } +pub fn bitcoin30_to_bitcoin32_outpoint(outpoint: &bitcoin30::OutPoint) -> bitcoin::OutPoint { + bitcoin::OutPoint { + txid: bitcoin30_to_bitcoin32_txid(&outpoint.txid), + vout: outpoint.vout, + } +} + pub fn bitcoin32_to_bitcoin30_outpoint(outpoint: &bitcoin::OutPoint) -> bitcoin30::OutPoint { bitcoin30::OutPoint { txid: bitcoin32_to_bitcoin30_txid(&outpoint.txid), @@ -110,6 +178,19 @@ pub fn bitcoin30_to_bitcoin32_payment_preimage( lightning_types::payment::PaymentPreimage(preimage.0) } +pub fn bitcoin30_to_bitcoin32_sha256_hash( + hash: &bitcoin30::hashes::sha256::Hash, +) -> bitcoin::hashes::sha256::Hash { + *bitcoin::hashes::sha256::Hash::from_bytes_ref(hash.as_ref()) +} + +pub fn bitcoin32_to_bitcoin30_schnorr_signature( + signature: &bitcoin::secp256k1::schnorr::Signature, +) -> bitcoin30::secp256k1::schnorr::Signature { + bitcoin30::secp256k1::schnorr::Signature::from_slice(signature.as_ref()) + .expect("Failed to convert bitcoin32 schnorr signature to bitcoin30 schnorr signature") +} + #[cfg(test)] mod tests { use super::*; diff --git a/fedimint-core/src/config.rs b/fedimint-core/src/config.rs index 6297fb25fb8..c2c9d832f65 100644 --- a/fedimint-core/src/config.rs +++ b/fedimint-core/src/config.rs @@ -402,10 +402,10 @@ impl FederationId { /// other LN senders will know that they cannot pay the invoice. pub fn to_fake_ln_pub_key( &self, - secp: &secp256k1::Secp256k1, - ) -> anyhow::Result { - let sk = secp256k1::SecretKey::from_slice(&self.0.to_byte_array())?; - Ok(secp256k1::PublicKey::from_secret_key(secp, &sk)) + secp: &bitcoin::secp256k1::Secp256k1, + ) -> anyhow::Result { + let sk = bitcoin::secp256k1::SecretKey::from_slice(&self.0.to_byte_array())?; + Ok(bitcoin::secp256k1::PublicKey::from_secret_key(secp, &sk)) } } diff --git a/fedimint-core/src/lib.rs b/fedimint-core/src/lib.rs index 32ce4167ca7..70d4d48f254 100644 --- a/fedimint-core/src/lib.rs +++ b/fedimint-core/src/lib.rs @@ -54,7 +54,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; pub use tiered::Tiered; pub use tiered_multi::*; -pub use {hex, secp256k1}; +pub use {hex, secp256k1, secp256k1_29}; pub use crate::core::server; use crate::encoding::{Decodable, DecodeError, Encodable}; diff --git a/fedimint-load-test-tool/Cargo.toml b/fedimint-load-test-tool/Cargo.toml index f1b967b8061..d15a7d0b8b6 100644 --- a/fedimint-load-test-tool/Cargo.toml +++ b/fedimint-load-test-tool/Cargo.toml @@ -13,7 +13,6 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -bitcoin30 = { workspace = true } clap = { workspace = true } devimint = { workspace = true } fedimint-api-client = { workspace = true } @@ -29,6 +28,7 @@ futures = { workspace = true } jsonrpsee-core = { version = "0.24.7", features = ["client"] } lightning-invoice = { workspace = true } rand = { workspace = true } +secp256k1 = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true, features = ["full", "tracing"] } diff --git a/fedimint-load-test-tool/src/common.rs b/fedimint-load-test-tool/src/common.rs index 0fb5815e392..66c1fd606da 100644 --- a/fedimint-load-test-tool/src/common.rs +++ b/fedimint-load-test-tool/src/common.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use std::time::Duration; use anyhow::{anyhow, bail, Context, Result}; -use bitcoin30::secp256k1; use devimint::cmd; use devimint::util::{ClnLightningCli, FedimintCli, LnCli}; use fedimint_client::secret::{PlainRootSecretStrategy, RootSecretStrategy}; diff --git a/fedimint-recoverytool/Cargo.toml b/fedimint-recoverytool/Cargo.toml index 9ec61613bac..9453b2f3434 100644 --- a/fedimint-recoverytool/Cargo.toml +++ b/fedimint-recoverytool/Cargo.toml @@ -17,7 +17,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -bitcoin30 = { workspace = true } +bitcoin = { workspace = true } clap = { workspace = true } fedimint-core = { workspace = true } fedimint-logging = { workspace = true } diff --git a/fedimint-recoverytool/src/key.rs b/fedimint-recoverytool/src/key.rs index 3f689437f9b..43862982d5f 100644 --- a/fedimint-recoverytool/src/key.rs +++ b/fedimint-recoverytool/src/key.rs @@ -2,6 +2,7 @@ use std::cmp::Ordering; use std::fmt::{Display, Formatter}; use std::hash::Hasher; +use fedimint_core::bitcoin_migration::bitcoin32_to_bitcoin30_secp256k1_secret_key; use fedimint_wallet_server::common::keys::CompressedPublicKey; use miniscript::MiniscriptKey; @@ -10,7 +11,7 @@ use miniscript::MiniscriptKey; #[derive(Debug, Clone, Copy, Eq)] pub enum Key { Public(CompressedPublicKey), - Private(bitcoin30::key::PrivateKey), + Private(bitcoin::key::PrivateKey), } impl PartialOrd for Key { @@ -47,7 +48,9 @@ impl Key { match self { Key::Public(pk) => pk, Key::Private(sk) => { - CompressedPublicKey::new(secp256k1::PublicKey::from_secret_key_global(&sk.inner)) + CompressedPublicKey::new(secp256k1::PublicKey::from_secret_key_global( + &bitcoin32_to_bitcoin30_secp256k1_secret_key(&sk.inner), + )) } } } @@ -71,8 +74,8 @@ impl MiniscriptKey for Key { 0 } - type Sha256 = bitcoin30::hashes::sha256::Hash; + type Sha256 = bitcoin::hashes::sha256::Hash; type Hash256 = miniscript::hash256::Hash; - type Ripemd160 = bitcoin30::hashes::ripemd160::Hash; - type Hash160 = bitcoin30::hashes::hash160::Hash; + type Ripemd160 = bitcoin::hashes::ripemd160::Hash; + type Hash160 = bitcoin::hashes::hash160::Hash; } diff --git a/fedimint-recoverytool/src/main.rs b/fedimint-recoverytool/src/main.rs index 37ea4c0db19..83935eb1942 100644 --- a/fedimint-recoverytool/src/main.rs +++ b/fedimint-recoverytool/src/main.rs @@ -7,9 +7,13 @@ use std::collections::BTreeSet; use std::path::{Path, PathBuf}; use anyhow::anyhow; -use bitcoin30::network::constants::Network; -use bitcoin30::OutPoint; +use bitcoin::network::Network; +use bitcoin::OutPoint; use clap::{ArgGroup, Parser, Subcommand}; +use fedimint_core::bitcoin_migration::{ + bitcoin30_to_bitcoin32_amount, bitcoin30_to_bitcoin32_network, bitcoin30_to_bitcoin32_outpoint, + bitcoin30_to_bitcoin32_secp256k1_secret_key, +}; use fedimint_core::core::LEGACY_HARDCODED_INSTANCE_ID_WALLET; use fedimint_core::db::{Database, IDatabaseTransactionOpsCoreTyped}; use fedimint_core::epoch::ConsensusItem; @@ -125,7 +129,7 @@ async fn main() -> anyhow::Result<()> { .expect("Malformed wallet config"); let base_descriptor = wallet_cfg.consensus.peg_in_descriptor; let base_key = wallet_cfg.private.peg_in_key; - let network = wallet_cfg.consensus.network; + let network = bitcoin30_to_bitcoin32_network(&wallet_cfg.consensus.network); (base_descriptor, base_key, network) } else if let (Some(descriptor), Some(key)) = (opts.descriptor, opts.key) { @@ -172,9 +176,9 @@ async fn process_and_print_tweak_source( let descriptor = tweak_descriptor(base_descriptor, base_key, &tweak, network); ImportableWallet { - outpoint, + outpoint: bitcoin30_to_bitcoin32_outpoint(&outpoint), descriptor, - amount_sat: amount, + amount_sat: bitcoin30_to_bitcoin32_amount(&amount), } }) .collect() @@ -293,10 +297,10 @@ fn tweak_descriptor( base_descriptor .tweak(tweak, secp256k1::SECP256K1) .translate_pk(&mut SecretKeyInjector { - secret: bitcoin30::key::PrivateKey { + secret: bitcoin::key::PrivateKey { compressed: true, - network, - inner: secret_key, + network: network.into(), + inner: bitcoin30_to_bitcoin32_secp256k1_secret_key(&secret_key), }, public: pub_key, }) @@ -308,8 +312,8 @@ fn tweak_descriptor( struct ImportableWallet { outpoint: OutPoint, descriptor: Descriptor, - #[serde(with = "bitcoin30::amount::serde::as_sat")] - amount_sat: bitcoin30::Amount, + #[serde(with = "bitcoin::amount::serde::as_sat")] + amount_sat: bitcoin::Amount, } /// A Bitcoin Core importable descriptor @@ -322,7 +326,7 @@ struct ImportableWalletMin { /// know. #[derive(Debug)] struct SecretKeyInjector { - secret: bitcoin30::key::PrivateKey, + secret: bitcoin::key::PrivateKey, public: CompressedPublicKey, } diff --git a/fedimint-server/src/consensus/engine.rs b/fedimint-server/src/consensus/engine.rs index 064eb41ba4c..68a932a193c 100644 --- a/fedimint-server/src/consensus/engine.rs +++ b/fedimint-server/src/consensus/engine.rs @@ -10,6 +10,7 @@ use anyhow::{anyhow, bail}; use async_channel::Receiver; use fedimint_api_client::api::{DynGlobalApi, FederationApiExt, PeerConnectionStatus}; use fedimint_api_client::query::FilterMap; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_sha256_hash; use fedimint_core::core::{DynOutput, MODULE_INSTANCE_ID_GLOBAL}; use fedimint_core::db::{Database, DatabaseTransaction, IDatabaseTransactionOpsCoreTyped}; use fedimint_core::encoding::Decodable; @@ -211,7 +212,7 @@ impl ConsensusEngine { loop { match self.federation_api.server_config_consensus_hash().await { Ok(consensus_hash) => { - if consensus_hash != our_hash { + if consensus_hash != bitcoin30_to_bitcoin32_sha256_hash(&our_hash) { bail!("Our consensus config doesn't match peers!") } diff --git a/gateway/cli/Cargo.toml b/gateway/cli/Cargo.toml index c121dd7acc3..9cf7d8963c3 100644 --- a/gateway/cli/Cargo.toml +++ b/gateway/cli/Cargo.toml @@ -20,7 +20,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -bitcoin30 = { workspace = true } +bitcoin = { workspace = true } clap = { workspace = true } clap_complete = "4.5.35" fedimint-core = { workspace = true } diff --git a/gateway/cli/src/general_commands.rs b/gateway/cli/src/general_commands.rs index 7f04fa349cb..074ec512272 100644 --- a/gateway/cli/src/general_commands.rs +++ b/gateway/cli/src/general_commands.rs @@ -1,7 +1,10 @@ use anyhow::bail; -use bitcoin30::address::NetworkUnchecked; -use bitcoin30::Address; +use bitcoin::address::NetworkUnchecked; +use bitcoin::Address; use clap::Subcommand; +use fedimint_core::bitcoin_migration::{ + bitcoin32_to_bitcoin30_network, bitcoin32_to_bitcoin30_unchecked_address, +}; use fedimint_core::config::FederationId; use fedimint_core::{fedimint_build_code_version_env, Amount, BitcoinAmountOrAll}; use fedimint_mint_client::OOBNotes; @@ -115,7 +118,7 @@ pub enum GeneralCommands { routing_fees: Option, #[clap(long)] - network: Option, + network: Option, /// Format federation id,base msat,proportional to millionths part. Any /// other federations not given here will keep their current fees. @@ -202,7 +205,7 @@ impl GeneralCommands { .withdraw(WithdrawPayload { federation_id, amount, - address, + address: bitcoin32_to_bitcoin30_unchecked_address(&address), }) .await?; @@ -250,7 +253,7 @@ impl GeneralCommands { password, num_route_hints, routing_fees, - network, + network: network.map(|network| bitcoin32_to_bitcoin30_network(&network)), per_federation_routing_fees, }) .await?; diff --git a/gateway/cli/src/lightning_commands.rs b/gateway/cli/src/lightning_commands.rs index 28263c28b17..3baad1554d8 100644 --- a/gateway/cli/src/lightning_commands.rs +++ b/gateway/cli/src/lightning_commands.rs @@ -1,7 +1,10 @@ use std::time::Duration; -use bitcoin30::address::NetworkUnchecked; +use bitcoin::address::NetworkUnchecked; use clap::Subcommand; +use fedimint_core::bitcoin_migration::{ + bitcoin32_to_bitcoin30_secp256k1_pubkey, bitcoin32_to_bitcoin30_unchecked_address, +}; use fedimint_core::util::{backoff_util, retry}; use fedimint_core::BitcoinAmountOrAll; use lightning_invoice::Bolt11Invoice; @@ -40,7 +43,7 @@ pub enum LightningCommands { OpenChannel { /// The public key of the node to open a channel with #[clap(long)] - pubkey: bitcoin30::secp256k1::PublicKey, + pubkey: bitcoin::secp256k1::PublicKey, #[clap(long)] host: String, @@ -58,7 +61,7 @@ pub enum LightningCommands { CloseChannelsWithPeer { // The public key of the node to close channels with #[clap(long)] - pubkey: bitcoin30::secp256k1::PublicKey, + pubkey: bitcoin::secp256k1::PublicKey, }, /// List active channels. ListActiveChannels, @@ -67,7 +70,7 @@ pub enum LightningCommands { WithdrawOnchain { /// The address to withdraw funds to. #[clap(long)] - address: bitcoin30::Address, + address: bitcoin::Address, /// The amount to withdraw. /// Can be "all" to withdraw all funds, an amount + unit (e.g. "1000 @@ -136,6 +139,8 @@ impl LightningCommands { channel_size_sats, push_amount_sats, } => { + let pubkey = bitcoin32_to_bitcoin30_secp256k1_pubkey(&pubkey); + let funding_txid = create_client() .open_channel(OpenChannelPayload { pubkey, @@ -147,6 +152,8 @@ impl LightningCommands { println!("{funding_txid}"); } Self::CloseChannelsWithPeer { pubkey } => { + let pubkey = bitcoin32_to_bitcoin30_secp256k1_pubkey(&pubkey); + let response = create_client() .close_channels_with_peer(CloseChannelsWithPeerPayload { pubkey }) .await?; @@ -161,6 +168,8 @@ impl LightningCommands { amount, fee_rate_sats_per_vbyte, } => { + let address = bitcoin32_to_bitcoin30_unchecked_address(&address); + let response = create_client() .withdraw_onchain(WithdrawOnchainPayload { address, diff --git a/gateway/ln-gateway/src/gateway_module_v2/receive_sm.rs b/gateway/ln-gateway/src/gateway_module_v2/receive_sm.rs index 121438f8bb8..4957ac12843 100644 --- a/gateway/ln-gateway/src/gateway_module_v2/receive_sm.rs +++ b/gateway/ln-gateway/src/gateway_module_v2/receive_sm.rs @@ -9,6 +9,7 @@ use fedimint_api_client::query::FilterMapThreshold; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::{Decoder, OperationId}; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::endpoint_constants::AWAIT_OUTPUT_OUTCOME_ENDPOINT; @@ -261,7 +262,9 @@ impl ReceiveStateMachine { agg_decryption_key, )), amount: old_state.common.contract.commitment.amount, - keys: vec![old_state.common.refund_keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair( + &old_state.common.refund_keypair, + )], }; let outpoints = global_context diff --git a/gateway/ln-gateway/src/gateway_module_v2/send_sm.rs b/gateway/ln-gateway/src/gateway_module_v2/send_sm.rs index 69c6660640a..e5cdb2477e3 100644 --- a/gateway/ln-gateway/src/gateway_module_v2/send_sm.rs +++ b/gateway/ln-gateway/src/gateway_module_v2/send_sm.rs @@ -3,6 +3,7 @@ use std::fmt; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::secp256k1::KeyPair; @@ -218,7 +219,9 @@ impl SendStateMachine { OutgoingWitness::Claim(preimage), )), amount: old_state.common.contract.amount, - keys: vec![old_state.common.claim_keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair( + &old_state.common.claim_keypair, + )], }; let outpoints = global_context diff --git a/gateway/ln-gateway/src/state_machine/pay.rs b/gateway/ln-gateway/src/state_machine/pay.rs index bbfec17e063..145bde1e501 100644 --- a/gateway/ln-gateway/src/state_machine/pay.rs +++ b/gateway/ln-gateway/src/state_machine/pay.rs @@ -5,6 +5,7 @@ use bitcoin_hashes::sha256; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle, ClientOutput}; use fedimint_client::{ClientHandleArc, DynGlobalClientContext}; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; @@ -712,7 +713,7 @@ impl GatewayPayClaimOutgoingContract { let client_input = ClientInput:: { input: claim_input, amount: contract.amount, - keys: vec![context.redeem_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&context.redeem_key)], }; let out_points = global_context diff --git a/gateway/ln-gateway/tests/tests.rs b/gateway/ln-gateway/tests/tests.rs index 3a212683991..61be8e3d26a 100644 --- a/gateway/ln-gateway/tests/tests.rs +++ b/gateway/ln-gateway/tests/tests.rs @@ -10,6 +10,7 @@ use assert_matches::assert_matches; use bitcoin_hashes::{sha256, Hash}; use fedimint_client::transaction::{ClientInput, ClientOutput, TransactionBuilder}; use fedimint_client::ClientHandleArc; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::FederationId; use fedimint_core::core::{IntoDynInstance, OperationId}; use fedimint_core::encoding::Encodable; @@ -386,7 +387,7 @@ async fn test_gateway_cannot_claim_invalid_preimage() -> anyhow::Result<()> { let client_input = ClientInput:: { input: claim_input, amount: outgoing_contract.amount, - keys: vec![gateway_module.redeem_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&gateway_module.redeem_key)], }; let tx = TransactionBuilder::new().with_input(client_input.into_dyn(gateway_module.id)); diff --git a/modules/fedimint-dummy-client/src/lib.rs b/modules/fedimint-dummy-client/src/lib.rs index a948b1089ba..091aa431cc8 100644 --- a/modules/fedimint-dummy-client/src/lib.rs +++ b/modules/fedimint-dummy-client/src/lib.rs @@ -20,6 +20,7 @@ use fedimint_client::sm::{Context, ModuleNotifier}; use fedimint_client::transaction::{ ClientInput, ClientInputBundle, ClientInputSM, ClientOutput, TransactionBuilder, }; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::{Decoder, ModuleKind, OperationId}; use fedimint_core::db::{ Database, DatabaseTransaction, DatabaseVersion, IDatabaseTransactionOpsCoreTyped, @@ -127,7 +128,7 @@ impl ClientModule for DummyClientModule { account: self.key.public_key(), }, amount: missing_input_amount, - keys: vec![self.key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&self.key)], }; let input_sm = ClientInputSM { state_machines: Arc::new(move |txid, _| { @@ -229,7 +230,7 @@ impl DummyClientModule { account: account_kp.public_key(), }, amount, - keys: vec![account_kp], + keys: vec![bitcoin30_to_bitcoin32_keypair(&account_kp)], }; // Build and send tx to the fed diff --git a/modules/fedimint-dummy-tests/tests/tests.rs b/modules/fedimint-dummy-tests/tests/tests.rs index 8bdb172bdfa..20a645cb8e3 100644 --- a/modules/fedimint-dummy-tests/tests/tests.rs +++ b/modules/fedimint-dummy-tests/tests/tests.rs @@ -2,11 +2,12 @@ use std::sync::Arc; use anyhow::bail; use fedimint_client::transaction::{ClientInput, ClientOutput, TransactionBuilder}; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::ClientModuleConfig; use fedimint_core::core::{IntoDynInstance, ModuleKind, OperationId}; use fedimint_core::db::mem_impl::MemDatabase; use fedimint_core::module::ModuleConsensusVersion; -use fedimint_core::secp256k1::Secp256k1; +use fedimint_core::secp256k1_29::Secp256k1; use fedimint_core::{sats, Amount, OutPoint}; use fedimint_dummy_client::states::DummyStateMachine; use fedimint_dummy_client::{DummyClientInit, DummyClientModule}; @@ -92,7 +93,7 @@ async fn federation_should_abort_if_balance_sheet_is_negative() -> anyhow::Resul account: account_kp.public_key(), }, amount: sats(1000), - keys: vec![account_kp], + keys: vec![bitcoin30_to_bitcoin32_keypair(&account_kp)], }; let tx = TransactionBuilder::new().with_input(input.into_dyn(dummy.id)); diff --git a/modules/fedimint-ln-client/src/incoming.rs b/modules/fedimint-ln-client/src/incoming.rs index eda41a5b521..993f8e07489 100644 --- a/modules/fedimint-ln-client/src/incoming.rs +++ b/modules/fedimint-ln-client/src/incoming.rs @@ -14,6 +14,7 @@ use bitcoin30::hashes::sha256; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::runtime::sleep; @@ -352,7 +353,7 @@ impl DecryptingPreimageState { let client_input = ClientInput:: { input: claim_input, amount: contract.amount, - keys: vec![context.redeem_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&context.redeem_key)], }; let out_points = global_context diff --git a/modules/fedimint-ln-client/src/lib.rs b/modules/fedimint-ln-client/src/lib.rs index 13582362eef..20d9e5ca6c9 100644 --- a/modules/fedimint-ln-client/src/lib.rs +++ b/modules/fedimint-ln-client/src/lib.rs @@ -42,6 +42,9 @@ use fedimint_client::transaction::{ ClientInput, ClientInputBundle, ClientOutput, TransactionBuilder, }; use fedimint_client::{sm_enum_variant_translation, DynGlobalClientContext}; +use fedimint_core::bitcoin_migration::{ + bitcoin30_to_bitcoin32_keypair, bitcoin32_to_bitcoin30_secp256k1_pubkey, +}; use fedimint_core::config::FederationId; use fedimint_core::core::{Decoder, IntoDynInstance, ModuleInstanceId, ModuleKind, OperationId}; use fedimint_core::db::{DatabaseTransaction, DatabaseVersion, IDatabaseTransactionOpsCoreTyped}; @@ -1118,7 +1121,13 @@ impl LightningClientModule { let markers = self.client_ctx.get_internal_payment_markers()?; - let mut is_internal_payment = invoice_has_internal_payment_markers(&invoice, markers); + let mut is_internal_payment = invoice_has_internal_payment_markers( + &invoice, + ( + bitcoin32_to_bitcoin30_secp256k1_pubkey(&markers.0), + markers.1, + ), + ); if !is_internal_payment { let gateways = dbtx .find_by_prefix(&LightningGatewayKeyPrefix) @@ -1463,7 +1472,7 @@ impl LightningClientModule { let client_input = ClientInput:: { input, amount: incoming_contract_account.amount, - keys: vec![key_pair], + keys: vec![bitcoin30_to_bitcoin32_keypair(&key_pair)], }; let tx = TransactionBuilder::new().with_inputs( @@ -1576,7 +1585,11 @@ impl LightningClientModule { } else { // If no gateway is provided, this is assumed to be an internal payment. let markers = self.client_ctx.get_internal_payment_markers()?; - (markers.0, markers.1, vec![]) + ( + bitcoin32_to_bitcoin30_secp256k1_pubkey(&markers.0), + markers.1, + vec![], + ) }; debug!(target: LOG_CLIENT_MODULE_LN, ?gateway_id, %amount, "Selected LN gateway for invoice generation"); diff --git a/modules/fedimint-ln-client/src/pay.rs b/modules/fedimint-ln-client/src/pay.rs index 31be379b43d..a52bb615991 100644 --- a/modules/fedimint-ln-client/src/pay.rs +++ b/modules/fedimint-ln-client/src/pay.rs @@ -4,6 +4,7 @@ use bitcoin30::hashes::sha256; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::FederationId; use fedimint_core::core::{Decoder, OperationId}; use fedimint_core::encoding::{Decodable, Encodable}; @@ -546,7 +547,7 @@ async fn try_refund_outgoing_contract( let refund_client_input = ClientInput:: { input: refund_input, amount: contract_data.contract_account.amount, - keys: vec![refund_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&refund_key)], }; let (txid, out_points) = global_context diff --git a/modules/fedimint-ln-client/src/receive.rs b/modules/fedimint-ln-client/src/receive.rs index f7d285eac48..5068b9817c6 100644 --- a/modules/fedimint-ln-client/src/receive.rs +++ b/modules/fedimint-ln-client/src/receive.rs @@ -5,6 +5,7 @@ use fedimint_api_client::api::DynModuleApi; use fedimint_client::sm::{ClientSMDatabaseTransaction, DynState, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::{IntoDynInstance, ModuleInstanceId, OperationId}; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::task::sleep; @@ -284,7 +285,7 @@ impl LightningReceiveConfirmedInvoice { let client_input = ClientInput:: { input, amount: contract.amount, - keys: vec![keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair(&keypair)], }; global_context diff --git a/modules/fedimint-lnv2-client/src/receive_sm.rs b/modules/fedimint-lnv2-client/src/receive_sm.rs index 453cc224a5b..515bd399116 100644 --- a/modules/fedimint-lnv2-client/src/receive_sm.rs +++ b/modules/fedimint-lnv2-client/src/receive_sm.rs @@ -2,6 +2,7 @@ use bitcoin30::key::KeyPair; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::OutPoint; @@ -114,7 +115,9 @@ impl ReceiveStateMachine { old_state.common.agg_decryption_key, )), amount: old_state.common.contract.commitment.amount, - keys: vec![old_state.common.claim_keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair( + &old_state.common.claim_keypair, + )], }; let out_points = global_context diff --git a/modules/fedimint-lnv2-client/src/send_sm.rs b/modules/fedimint-lnv2-client/src/send_sm.rs index 8f55c03ff95..a71b050a054 100644 --- a/modules/fedimint-lnv2-client/src/send_sm.rs +++ b/modules/fedimint-lnv2-client/src/send_sm.rs @@ -5,6 +5,7 @@ use bitcoin30::secp256k1; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; @@ -218,7 +219,9 @@ impl SendStateMachine { OutgoingWitness::Cancel(signature), )), amount: old_state.common.contract.amount, - keys: vec![old_state.common.refund_keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair( + &old_state.common.refund_keypair, + )], }; let outpoints = global_context @@ -277,7 +280,9 @@ impl SendStateMachine { OutgoingWitness::Refund, )), amount: old_state.common.contract.amount, - keys: vec![old_state.common.refund_keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair( + &old_state.common.refund_keypair, + )], }; let outpoints = global_context diff --git a/modules/fedimint-lnv2-tests/tests/tests.rs b/modules/fedimint-lnv2-tests/tests/tests.rs index 596f2cd481b..5af6a152624 100644 --- a/modules/fedimint-lnv2-tests/tests/tests.rs +++ b/modules/fedimint-lnv2-tests/tests/tests.rs @@ -3,6 +3,7 @@ mod mock; use std::sync::Arc; use fedimint_client::transaction::{ClientInput, ClientInputBundle, TransactionBuilder}; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::util::NextOrPending as _; use fedimint_core::{sats, Amount}; @@ -208,7 +209,7 @@ async fn claiming_outgoing_contract_triggers_success() -> anyhow::Result<()> { OutgoingWitness::Claim(MOCK_INVOICE_PREIMAGE), )), amount: contract.amount, - keys: vec![mock::gateway_keypair()], + keys: vec![bitcoin30_to_bitcoin32_keypair(&mock::gateway_keypair())], }; client diff --git a/modules/fedimint-mint-client/src/input.rs b/modules/fedimint-mint-client/src/input.rs index a906086810e..c737404f4e7 100644 --- a/modules/fedimint-mint-client/src/input.rs +++ b/modules/fedimint-mint-client/src/input.rs @@ -1,6 +1,7 @@ use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::{Amount, TransactionId}; @@ -140,7 +141,7 @@ impl MintInputStateCreated { let refund_input = ClientInput:: { input: MintInput::new_v0(amount, spendable_note.note()), - keys: vec![spendable_note.spend_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&spendable_note.spend_key)], amount, }; diff --git a/modules/fedimint-mint-client/src/lib.rs b/modules/fedimint-mint-client/src/lib.rs index 687311cfcea..1ff19e36b0f 100644 --- a/modules/fedimint-mint-client/src/lib.rs +++ b/modules/fedimint-mint-client/src/lib.rs @@ -49,6 +49,7 @@ use fedimint_client::transaction::{ ClientInput, ClientInputBundle, ClientInputSM, ClientOutput, TransactionBuilder, }; use fedimint_client::{sm_enum_variant_translation, DynGlobalClientContext}; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::{FederationId, FederationIdPrefix}; use fedimint_core::core::{Decoder, IntoDynInstance, ModuleInstanceId, ModuleKind, OperationId}; use fedimint_core::db::{ @@ -1230,7 +1231,7 @@ impl MintClientModule { inputs.push(ClientInput { input: MintInput::new_v0(amount, note), - keys: vec![spendable_note.spend_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&spendable_note.spend_key)], amount, }); diff --git a/modules/fedimint-mint-client/src/oob.rs b/modules/fedimint-mint-client/src/oob.rs index 12e1e61eab5..0f59eb26b34 100644 --- a/modules/fedimint-mint-client/src/oob.rs +++ b/modules/fedimint-mint-client/src/oob.rs @@ -4,6 +4,7 @@ use std::time::SystemTime; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle, ClientInputSM}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::{runtime, Amount, TransactionId}; @@ -179,7 +180,7 @@ async fn try_cancel_oob_spend( ( ClientInput { input: MintInput::new_v0(amount, spendable_note.note()), - keys: vec![spendable_note.spend_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&spendable_note.spend_key)], amount, }, ClientInputSM { diff --git a/modules/fedimint-mint-tests/tests/tests.rs b/modules/fedimint-mint-tests/tests/tests.rs index 6f3921e136e..452075cd004 100644 --- a/modules/fedimint-mint-tests/tests/tests.rs +++ b/modules/fedimint-mint-tests/tests/tests.rs @@ -4,6 +4,7 @@ use std::time::Duration; use bls12_381::G1Affine; use fedimint_client::backup::{ClientBackup, Metadata}; use fedimint_client::transaction::{ClientInput, ClientInputBundle, TransactionBuilder}; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::config::EmptyGenParams; use fedimint_core::core::OperationId; use fedimint_core::secp256k1::KeyPair; @@ -68,7 +69,7 @@ async fn transaction_with_invalid_signature_is_rejected() -> anyhow::Result<()> }, }), amount: Amount::from_msats(1024), - keys: vec![keypair], + keys: vec![bitcoin30_to_bitcoin32_keypair(&keypair)], }; let operation_id = OperationId::new_random(); diff --git a/modules/fedimint-wallet-client/src/deposit.rs b/modules/fedimint-wallet-client/src/deposit.rs index cac5d477c46..3e3646f368a 100644 --- a/modules/fedimint-wallet-client/src/deposit.rs +++ b/modules/fedimint-wallet-client/src/deposit.rs @@ -4,6 +4,7 @@ use std::time::{Duration, SystemTime}; use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition}; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; use fedimint_client::DynGlobalClientContext; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::encoding::{Decodable, Encodable}; use fedimint_core::task::sleep; @@ -278,7 +279,9 @@ pub(crate) async fn transition_btc_tx_confirmed( let client_input = ClientInput:: { input: wallet_input, - keys: vec![awaiting_confirmation_state.tweak_key], + keys: vec![bitcoin30_to_bitcoin32_keypair( + &awaiting_confirmation_state.tweak_key, + )], amount, }; diff --git a/modules/fedimint-wallet-client/src/pegin_monitor.rs b/modules/fedimint-wallet-client/src/pegin_monitor.rs index 84cd739f26e..081e137353c 100644 --- a/modules/fedimint-wallet-client/src/pegin_monitor.rs +++ b/modules/fedimint-wallet-client/src/pegin_monitor.rs @@ -6,6 +6,7 @@ use fedimint_api_client::api::DynModuleApi; use fedimint_bitcoind::DynBitcoindRpc; use fedimint_client::module::ClientContext; use fedimint_client::transaction::{ClientInput, ClientInputBundle}; +use fedimint_core::bitcoin_migration::bitcoin30_to_bitcoin32_keypair; use fedimint_core::core::OperationId; use fedimint_core::db::{ AutocommitError, Database, DatabaseTransaction, IDatabaseTransactionOpsCoreTyped as _, @@ -425,7 +426,7 @@ async fn claim_peg_in( let client_input = ClientInput:: { input: wallet_input, - keys: vec![tweak_key], + keys: vec![bitcoin30_to_bitcoin32_keypair(&tweak_key)], amount, };