Skip to content

Commit

Permalink
Merge pull request #293 from nomic-io/bitcoin-network-validation
Browse files Browse the repository at this point in the history
Bitcoin network validation
  • Loading branch information
mappum authored Sep 6, 2024
2 parents b1616c3 + 587925a commit f3a9322
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 10 deletions.
24 changes: 24 additions & 0 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 @@ -406,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 @@ -833,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 @@ -959,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
19 changes: 17 additions & 2 deletions src/bin/nomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ use nomic::app::IbcDest;
use nomic::app::InnerApp;
use nomic::app::Nom;
use nomic::bitcoin::adapter::Adapter;
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 @@ -1429,6 +1429,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 @@ -1803,6 +1810,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
17 changes: 13 additions & 4 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
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

0 comments on commit f3a9322

Please sign in to comment.