Skip to content

Commit

Permalink
Merge branch 'develop' into mempool-scan-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
cwlittle committed Sep 9, 2024
2 parents 4ebf259 + f3a9322 commit 2150192
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 30 deletions.
34 changes: 31 additions & 3 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use crate::airdrop::Airdrop;
use crate::bitcoin::adapter::Adapter;
use crate::bitcoin::matches_bitcoin_network;
use crate::bitcoin::{Bitcoin, Nbtc};
use crate::cosmos::{Chain, Cosmos, Proof};

Expand Down Expand Up @@ -280,6 +281,7 @@ impl InnerApp {
match dest {
Dest::Address(addr) => self.bitcoin.accounts.deposit(addr, nbtc),
Dest::Ibc(dest) => dest.transfer(nbtc, &mut self.bitcoin, &mut self.ibc),
Dest::Fee => Ok(self.bitcoin.give_rewards(nbtc)?),
}
}

Expand Down Expand Up @@ -405,6 +407,13 @@ impl FromStr for NbtcMemo {
}
let dest = parts[1];
let script = if let Ok(addr) = bitcoin::Address::from_str(dest) {
if !matches_bitcoin_network(&addr.network) {
return Err(Error::App(format!(
"Invalid network for nBTC memo. Got {}, Expected {}",
addr.network,
crate::bitcoin::NETWORK
)));
}
addr.script_pubkey()
} else {
bitcoin::Script::from_str(parts[1]).map_err(|e| Error::App(e.to_string()))?
Expand Down Expand Up @@ -832,6 +841,14 @@ impl ConvertSdkTx for InnerApp {
let dest_addr: bitcoin::Address = msg.dst_address.parse().map_err(
|e: bitcoin::util::address::Error| Error::App(e.to_string()),
)?;
if !matches_bitcoin_network(&dest_addr.network) {
return Err(Error::App(format!(
"Invalid network for destination address. Got {}, Expected {}",
dest_addr.network,
crate::bitcoin::NETWORK
)));
}

let dest_script =
crate::bitcoin::adapter::Adapter::new(dest_addr.script_pubkey());

Expand Down Expand Up @@ -958,6 +975,14 @@ impl ConvertSdkTx for InnerApp {
.parse()
.map_err(|_| Error::App("Invalid recovery address".to_string()))?;

if !matches_bitcoin_network(&recovery_addr.network) {
return Err(Error::App(format!(
"Invalid network for recovery address. Got {}, Expected {}",
recovery_addr.network,
crate::bitcoin::NETWORK
)));
}

let script =
crate::bitcoin::adapter::Adapter::new(recovery_addr.script_pubkey());

Expand Down Expand Up @@ -1015,13 +1040,15 @@ pub struct MsgIbcTransfer {
pub enum Dest {
Address(Address),
Ibc(IbcDest),
Fee,
}

impl Dest {
pub fn to_receiver_addr(&self) -> String {
pub fn to_receiver_addr(&self) -> Option<String> {
match self {
Dest::Address(addr) => addr.to_string(),
Dest::Ibc(dest) => dest.receiver.0.to_string(),
Dest::Address(addr) => Some(addr.to_string()),
Dest::Ibc(dest) => Some(dest.receiver.0.to_string()),
Dest::Fee => None,
}
}
}
Expand Down Expand Up @@ -1112,6 +1139,7 @@ impl Dest {
let bytes = match self {
Address(addr) => addr.bytes().into(),
Ibc(dest) => Sha256::digest(dest.encode()?).to_vec(),
Fee => vec![1],
};

Ok(bytes)
Expand Down
22 changes: 19 additions & 3 deletions src/bin/nomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ use nomic::app::InnerApp;
use nomic::app::Nom;
use nomic::bitcoin::adapter::Adapter;
use nomic::bitcoin::deposit_index::DepositIndex;
use nomic::bitcoin::matches_bitcoin_network;
use nomic::bitcoin::signatory::SignatorySet;
use nomic::bitcoin::Nbtc;
use nomic::bitcoin::{relayer::Relayer, signer::Signer};
use nomic::error::Result;
use nomic::utils::load_bitcoin_key;
use nomic::utils::load_or_generate;
use nomic::utils::{load_bitcoin_key, load_or_generate};
use orga::abci::Node;
use orga::client::wallet::{SimpleWallet, Wallet};
use orga::coins::{Address, Commission, Decimal, Declaration, Symbol};
Expand Down Expand Up @@ -1330,7 +1330,8 @@ async fn deposit(
))
})
.await?;
let script = sigset.output_script(dest.commitment_bytes()?.as_slice(), threshold)?;
let commitment_bytes = dest.commitment_bytes()?;
let script = sigset.output_script(&commitment_bytes, threshold)?;
let btc_addr = bitcoin::Address::from_script(&script, nomic::bitcoin::NETWORK).unwrap();

let mut successes = 0;
Expand Down Expand Up @@ -1431,6 +1432,13 @@ pub struct WithdrawCmd {
impl WithdrawCmd {
async fn run(&self) -> Result<()> {
let script = self.dest.script_pubkey();
if !matches_bitcoin_network(&self.dest.network) {
return Err(nomic::error::Error::Address(format!(
"Invalid network for destination address. Got {}, Expected {}",
self.dest.network,
nomic::bitcoin::NETWORK
)));
}

self.config
.client()
Expand Down Expand Up @@ -1805,6 +1813,14 @@ pub struct SetRecoveryAddressCmd {
impl SetRecoveryAddressCmd {
async fn run(&self) -> Result<()> {
let script = self.address.script_pubkey();
if !matches_bitcoin_network(&self.address.network) {
return Err(nomic::error::Error::Address(format!(
"Invalid network for recovery address. Got {}, Expected {}",
self.address.network,
nomic::bitcoin::NETWORK
)));
}

Ok(self
.config
.client()
Expand Down
22 changes: 16 additions & 6 deletions src/bitcoin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,18 @@ impl Default for Config {
}
}

pub fn matches_bitcoin_network(network: &bitcoin::Network) -> bool {
match crate::bitcoin::NETWORK {
bitcoin::Network::Bitcoin => network == &crate::bitcoin::NETWORK,
bitcoin::Network::Regtest => {
network == &bitcoin::Network::Regtest || network == &bitcoin::Network::Testnet
}
bitcoin::Network::Testnet | bitcoin::Network::Signet => {
network == &bitcoin::Network::Testnet || network == &bitcoin::Network::Signet
}
}
}

/// Calculates the bridge fee for a deposit of the given amount of BTC, in
/// satoshis.
pub fn calc_deposit_fee(amount: u64) -> u64 {
Expand Down Expand Up @@ -475,10 +487,7 @@ impl Bitcoin {
))
})?;

let regtest_mode = self.network() == bitcoin::Network::Regtest
&& _signatory_key.network == bitcoin::Network::Testnet;

if !regtest_mode && _signatory_key.network != self.network() {
if !matches_bitcoin_network(&_signatory_key.network) {
return Err(Error::Orga(orga::Error::App(
"Signatory key network does not match network".to_string(),
)));
Expand Down Expand Up @@ -591,7 +600,6 @@ impl Bitcoin {

let checkpoint = self.checkpoints.get(sigset_index)?;
let sigset = checkpoint.sigset.clone();

let dest_bytes = dest.commitment_bytes()?;
let expected_script =
sigset.output_script(&dest_bytes, self.checkpoints.config.sigset_threshold)?;
Expand Down Expand Up @@ -662,7 +670,9 @@ impl Bitcoin {
// TODO: keep in excess queue if full

let deposit_fee = nbtc.take(calc_deposit_fee(nbtc.amount.into()))?;
self.give_rewards(deposit_fee)?;
self.checkpoints
.building_mut()?
.insert_pending(Dest::Fee, deposit_fee)?;

self.checkpoints
.building_mut()?
Expand Down
5 changes: 3 additions & 2 deletions src/bitcoin/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,18 @@ impl RecoveryTxs {
.output
.get(args.vout as usize)
.ok_or_else(|| Error::Signer("Invalid recovery tx vout".to_string()))?;
let commitment_bytes = args.dest.commitment_bytes()?;

let input = Input::new(
OutPoint::new(args.expired_tx.txid(), args.vout),
args.old_sigset,
&args.dest.commitment_bytes()?,
&commitment_bytes,
expired_output.value,
args.threshold,
)?;
let script_pubkey = args
.new_sigset
.output_script(args.dest.commitment_bytes()?.as_slice(), args.threshold)?;
.output_script(&commitment_bytes, args.threshold)?;
let output = TxOut {
value: expired_output.value,
script_pubkey,
Expand Down
16 changes: 12 additions & 4 deletions src/bitcoin/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,12 @@ impl Relayer {
)?;

let mut index = index.lock().await;
let receiver_addr = match dest.to_receiver_addr() {
Some(addr) => addr,
None => continue,
};
index.insert_deposit(
dest.to_receiver_addr(),
receiver_addr,
bitcoin_address,
Deposit::new(txid, vout as u32, output.value, None),
)
Expand Down Expand Up @@ -870,6 +874,10 @@ impl Relayer {
let txid = tx.txid();
let outpoint = (txid.into_inner(), output.vout);
let dest = output.dest.clone();
if dest.to_receiver_addr().is_none() {
return Ok(());
}
let receiver_addr = dest.to_receiver_addr().unwrap();
let vout = output.vout;
let contains_outpoint = app_client(&self.app_client_addr)
.query(|app| app.bitcoin.processed_outpoints.contains(outpoint))
Expand All @@ -882,13 +890,13 @@ impl Relayer {

if contains_outpoint {
let mut index = index.lock().await;
index.remove_deposit(dest.to_receiver_addr(), deposit_address, txid, vout)?;
index.remove_deposit(receiver_addr, deposit_address, txid, vout)?;
return Ok(());
}

let mut index_guard = index.lock().await;
index_guard.insert_deposit(
dest.to_receiver_addr(),
receiver_addr,
deposit_address.clone(),
Deposit::new(
txid,
Expand Down Expand Up @@ -1193,7 +1201,7 @@ impl WatchedScripts {
sigset: &SignatorySet,
threshold: (u64, u64),
) -> Result<::bitcoin::Script> {
sigset.output_script(dest.commitment_bytes()?.as_slice(), threshold)
sigset.output_script(&dest.commitment_bytes()?, threshold)
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ pub fn make_std_tx(
pub fn generate_bitcoin_key(network: bitcoin::Network) -> Result<ExtendedPrivKey> {
let seed: [u8; 32] = rand::thread_rng().gen();

let network = if network == bitcoin::Network::Regtest {
bitcoin::Network::Testnet
} else {
network
let network = match network {
bitcoin::Network::Bitcoin => bitcoin::Network::Bitcoin,
bitcoin::Network::Testnet | bitcoin::Network::Signet | bitcoin::Network::Regtest => {
bitcoin::Network::Testnet
}
};

Ok(ExtendedPrivKey::new_master(network, seed.as_slice())?)
Expand Down
16 changes: 8 additions & 8 deletions tests/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,14 +461,6 @@ async fn bitcoin_test() {
let balance = poll_for_updated_balance(funded_accounts[1].address, expected_balance).await;
assert_eq!(balance, Amount::from(expected_balance));

withdraw_bitcoin(
&funded_accounts[0],
bitcoin::Amount::from_sat(7000),
&withdraw_address,
)
.await
.unwrap();

app_client()
.with_wallet(funded_accounts[0].wallet.clone())
.call(
Expand All @@ -477,6 +469,14 @@ async fn bitcoin_test() {
)
.await?;

withdraw_bitcoin(
&funded_accounts[0],
bitcoin::Amount::from_sat(7000),
&withdraw_address,
)
.await
.unwrap();

btc_client
.generate_to_address(4, &async_wallet_address)
.await
Expand Down

0 comments on commit 2150192

Please sign in to comment.