Skip to content
Open
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
24 changes: 23 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use stderrlog;

use crate::chain::Network;
use crate::chain::{Network, Txid};
use crate::daemon::CookieGetter;
use crate::errors::*;

Expand Down Expand Up @@ -71,6 +71,8 @@ pub struct Config {
pub parent_network: BNetwork,
#[cfg(feature = "liquid")]
pub asset_db_path: Option<PathBuf>,
#[cfg(feature = "liquid")]
pub initial_issuance_prevout: Option<Txid>,

#[cfg(feature = "electrum-discovery")]
pub electrum_public_hosts: Option<crate::electrum::ServerHosts>,
Expand Down Expand Up @@ -279,6 +281,12 @@ impl Config {
.long("asset-db-path")
.help("Directory for liquid/elements asset db")
.takes_value(true),
)
.arg(
Arg::with_name("initial_issuance_prevout")
.long("initial-issuance-prevout")
.help("Custom initial issuance prevout TXID (required for custom liquid testnets/signets)")
.takes_value(true),
);

#[cfg(feature = "electrum-discovery")]
Expand Down Expand Up @@ -318,6 +326,12 @@ impl Config {
#[cfg(feature = "liquid")]
let asset_db_path = m.value_of("asset_db_path").map(PathBuf::from);

#[cfg(feature = "liquid")]
let initial_issuance_prevout = m.value_of("initial_issuance_prevout").map(|s| {
s.parse::<Txid>()
.expect("invalid initial-issuance-prevout TXID")
});

let default_daemon_port = match network_type {
#[cfg(not(feature = "liquid"))]
Network::Bitcoin => 8332,
Expand Down Expand Up @@ -497,6 +511,8 @@ impl Config {
parent_network,
#[cfg(feature = "liquid")]
asset_db_path,
#[cfg(feature = "liquid")]
initial_issuance_prevout,

#[cfg(feature = "electrum-discovery")]
electrum_public_hosts,
Expand All @@ -505,6 +521,12 @@ impl Config {
#[cfg(feature = "electrum-discovery")]
tor_proxy: m.value_of("tor_proxy").map(|s| s.parse().unwrap()),
};

#[cfg(feature = "liquid")]
if let Some(txid) = config.initial_issuance_prevout {
crate::util::transaction::set_custom_initial_issuance_prevout(txid);
}

eprintln!("{:?}", config);
config
}
Expand Down
2 changes: 1 addition & 1 deletion src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod block;
mod script;
mod transaction;
pub mod transaction;

pub mod bincode;
pub mod electrum_merkle;
Expand Down
37 changes: 32 additions & 5 deletions src/util/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use crate::util::BlockId;

use std::collections::{BTreeSet, HashMap};

#[cfg(feature = "liquid")]
use std::sync::RwLock;

#[cfg(feature = "liquid")]
lazy_static! {
static ref REGTEST_INITIAL_ISSUANCE_PREVOUT: Txid =
Expand All @@ -13,6 +16,14 @@ lazy_static! {
"0c52d2526a5c9f00e9fb74afd15dd3caaf17c823159a514f929ae25193a43a52"
.parse()
.unwrap();
// Ref. https://github.com/Blockstream/electrs/issues/125
static ref CUSTOM_INITIAL_ISSUANCE_PREVOUT: RwLock<Option<Txid>> = RwLock::new(None);
}

#[cfg(feature = "liquid")]
pub fn set_custom_initial_issuance_prevout(txid: Txid) {
let mut lock = CUSTOM_INITIAL_ISSUANCE_PREVOUT.write().unwrap();
*lock = Some(txid);
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -77,11 +88,27 @@ pub fn is_coinbase(txin: &TxIn) -> bool {
pub fn has_prevout(txin: &TxIn) -> bool {
#[cfg(not(feature = "liquid"))]
return !txin.previous_output.is_null();

#[cfg(feature = "liquid")]
return !txin.is_coinbase()
&& !txin.is_pegin
&& txin.previous_output.txid != *REGTEST_INITIAL_ISSUANCE_PREVOUT
&& txin.previous_output.txid != *TESTNET_INITIAL_ISSUANCE_PREVOUT;
{
// 1. Check standard liquid conditions
if txin.is_coinbase() || txin.is_pegin {
return false;
}

// 2. Check against the CUSTOM dummy prevout passed from Config
if let Ok(lock) = CUSTOM_INITIAL_ISSUANCE_PREVOUT.read() {
if let Some(custom_txid) = *lock {
if txin.previous_output.txid == custom_txid {
return false; // Ignore this input!
}
}
}

// 3. Check against hardcoded defaults
return txin.previous_output.txid != *REGTEST_INITIAL_ISSUANCE_PREVOUT
&& txin.previous_output.txid != *TESTNET_INITIAL_ISSUANCE_PREVOUT;
}
}

pub fn is_spendable(txout: &TxOut) -> bool {
Expand Down Expand Up @@ -203,4 +230,4 @@ mod test {
Some(value)
);
}
}
}