Skip to content

Commit

Permalink
feat: testnet4 is supported with the latest rust-bitcoin
Browse files Browse the repository at this point in the history
  • Loading branch information
BinChengZhao committed Dec 22, 2024
1 parent ebc9312 commit 0fe9284
Show file tree
Hide file tree
Showing 12 changed files with 965 additions and 381 deletions.
1,126 changes: 776 additions & 350 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ arraydeque = "0.5.1"
arrayref = "0.3.6"
base64 = "0.22"
bincode = "1.3.1"
bitcoin = { version = "0.31", features = ["serde"] }
bitcoin = { version = "0.32.5", features = [ "serde" ] }
bitcoin-io = "0.1.2"
clap = "2.33.3"
crossbeam-channel = "0.5.0"
dirs = "5.0.1"
elements = { version = "0.24", features = ["serde"], optional = true }
elements = { version = "0.25.1", features = ["serde"], optional = true }
error-chain = "0.12.4"
glob = "0.3"
hex = { package = "hex-conservative", version = "0.1.1" }
hex = { package = "hex-conservative", version = "0.2.1" }
itertools = "0.12"
lazy_static = "1.3.0"
libc = "0.2.81"
Expand Down
4 changes: 2 additions & 2 deletions src/bin/tx-fingerprint-stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() {
use bitcoin::blockdata::script::ScriptBuf;
use bitcoin::consensus::encode::deserialize;
use electrs::{
chain::Transaction,
chain::{Transaction, TxOperations},
config::Config,
daemon::Daemon,
metrics::Metrics,
Expand Down Expand Up @@ -62,7 +62,7 @@ fn main() {
}

let tx: Transaction = deserialize(&value).expect("failed to parse Transaction");
let txid = tx.txid();
let txid = TxOperations::txid(&tx);

iter.next();

Expand Down
46 changes: 46 additions & 0 deletions src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub enum Network {
#[cfg(not(feature = "liquid"))]
Testnet,
#[cfg(not(feature = "liquid"))]
Testnet4,
#[cfg(not(feature = "liquid"))]
Regtest,
#[cfg(not(feature = "liquid"))]
Signet,
Expand Down Expand Up @@ -97,6 +99,7 @@ impl Network {
return vec![
"mainnet".to_string(),
"testnet".to_string(),
"testnet4".to_string(),
"regtest".to_string(),
"signet".to_string(),
];
Expand All @@ -110,6 +113,27 @@ impl Network {
}
}

/// Because `rust-bitcoin` uses the `txid` function will cause a warning,
/// Need to use `compute_txid` instead,
/// So abstract a trait to handle the access of `txid`
pub trait TxOperations {
fn txid(&self) -> Txid;
}

#[cfg(not(feature = "liquid"))]
impl TxOperations for Transaction {
fn txid(&self) -> Txid {
self.compute_txid()
}
}

#[cfg(feature = "liquid")]
impl TxOperations for Transaction {
fn txid(&self) -> Txid {
Transaction::txid(self)
}
}

pub fn genesis_hash(network: Network) -> BlockHash {
#[cfg(not(feature = "liquid"))]
return bitcoin_genesis_hash(network.into());
Expand All @@ -121,8 +145,12 @@ pub fn bitcoin_genesis_hash(network: BNetwork) -> bitcoin::BlockHash {
lazy_static! {
static ref BITCOIN_GENESIS: bitcoin::BlockHash =
genesis_block(BNetwork::Bitcoin).block_hash();
// TESTNET_GENESIS is BlockHash of testnet3
static ref TESTNET_GENESIS: bitcoin::BlockHash =
genesis_block(BNetwork::Testnet).block_hash();
// TESTNET4_GENESIS is BlockHash of testnet4
static ref TESTNET4_GENESIS: bitcoin::BlockHash =
genesis_block(BNetwork::Testnet4).block_hash();
static ref REGTEST_GENESIS: bitcoin::BlockHash =
genesis_block(BNetwork::Regtest).block_hash();
static ref SIGNET_GENESIS: bitcoin::BlockHash =
Expand All @@ -131,6 +159,7 @@ pub fn bitcoin_genesis_hash(network: BNetwork) -> bitcoin::BlockHash {
match network {
BNetwork::Bitcoin => *BITCOIN_GENESIS,
BNetwork::Testnet => *TESTNET_GENESIS,
BNetwork::Testnet4 => *TESTNET4_GENESIS,
BNetwork::Regtest => *REGTEST_GENESIS,
BNetwork::Signet => *SIGNET_GENESIS,
_ => panic!("unknown network {:?}", network),
Expand Down Expand Up @@ -165,6 +194,8 @@ impl From<&str> for Network {
#[cfg(not(feature = "liquid"))]
"testnet" => Network::Testnet,
#[cfg(not(feature = "liquid"))]
"testnet4" => Network::Testnet4,
#[cfg(not(feature = "liquid"))]
"regtest" => Network::Regtest,
#[cfg(not(feature = "liquid"))]
"signet" => Network::Signet,
Expand All @@ -187,6 +218,7 @@ impl From<Network> for BNetwork {
match network {
Network::Bitcoin => BNetwork::Bitcoin,
Network::Testnet => BNetwork::Testnet,
Network::Testnet4 => BNetwork::Testnet4,
Network::Regtest => BNetwork::Regtest,
Network::Signet => BNetwork::Signet,
}
Expand All @@ -199,9 +231,23 @@ impl From<BNetwork> for Network {
match network {
BNetwork::Bitcoin => Network::Bitcoin,
BNetwork::Testnet => Network::Testnet,
BNetwork::Testnet4 => Network::Testnet4,
BNetwork::Regtest => Network::Regtest,
BNetwork::Signet => Network::Signet,
_ => panic!("unknown network {:?}", network),
}
}
}

#[cfg(not(feature = "liquid"))]
impl From<Network> for &'static bitcoin::params::Params {
fn from(network: Network) -> Self {
match network {
Network::Bitcoin => &bitcoin::params::MAINNET,
Network::Testnet => &bitcoin::params::TESTNET3,
Network::Testnet4 => &bitcoin::params::TESTNET4,
Network::Regtest => &bitcoin::params::REGTEST,
Network::Signet => &bitcoin::params::SIGNET,
}
}
}
18 changes: 14 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,19 +125,19 @@ impl Config {
.arg(
Arg::with_name("electrum_rpc_addr")
.long("electrum-rpc-addr")
.help("Electrum server JSONRPC 'addr:port' to listen on (default: '127.0.0.1:50001' for mainnet, '127.0.0.1:60001' for testnet and '127.0.0.1:60401' for regtest)")
.help("Electrum server JSONRPC 'addr:port' to listen on (default: '127.0.0.1:50001' for mainnet, '127.0.0.1:60001' for testnet3 and '127.0.0.1:40001' for testnet4 and '127.0.0.1:60401' for regtest)")
.takes_value(true),
)
.arg(
Arg::with_name("http_addr")
.long("http-addr")
.help("HTTP server 'addr:port' to listen on (default: '127.0.0.1:3000' for mainnet, '127.0.0.1:3001' for testnet and '127.0.0.1:3002' for regtest)")
.help("HTTP server 'addr:port' to listen on (default: '127.0.0.1:3000' for mainnet, '127.0.0.1:3001' for testnet3 and '127.0.0.1:3004' for testnet4 and '127.0.0.1:3002' for regtest)")
.takes_value(true),
)
.arg(
Arg::with_name("daemon_rpc_addr")
.long("daemon-rpc-addr")
.help("Bitcoin daemon JSONRPC 'addr:port' to connect (default: 127.0.0.1:8332 for mainnet, 127.0.0.1:18332 for testnet and 127.0.0.1:18443 for regtest)")
.help("Bitcoin daemon JSONRPC 'addr:port' to connect (default: 127.0.0.1:8332 for mainnet, 127.0.0.1:18332 for testnet3 and 127.0.0.1:48332 for testnet4 and 127.0.0.1:18443 for regtest)")
.takes_value(true),
)
.arg(
Expand All @@ -149,7 +149,7 @@ impl Config {
.arg(
Arg::with_name("monitoring_addr")
.long("monitoring-addr")
.help("Prometheus monitoring 'addr:port' to listen on (default: 127.0.0.1:4224 for mainnet, 127.0.0.1:14224 for testnet and 127.0.0.1:24224 for regtest)")
.help("Prometheus monitoring 'addr:port' to listen on (default: 127.0.0.1:4224 for mainnet, 127.0.0.1:14224 for testnet3 and 127.0.0.1:44224 for testnet4 and 127.0.0.1:24224 for regtest)")
.takes_value(true),
)
.arg(
Expand Down Expand Up @@ -282,6 +282,8 @@ impl Config {
#[cfg(not(feature = "liquid"))]
Network::Testnet => 18332,
#[cfg(not(feature = "liquid"))]
Network::Testnet4 => 48332,
#[cfg(not(feature = "liquid"))]
Network::Regtest => 18443,
#[cfg(not(feature = "liquid"))]
Network::Signet => 38332,
Expand All @@ -297,6 +299,8 @@ impl Config {
#[cfg(not(feature = "liquid"))]
Network::Testnet => 60001,
#[cfg(not(feature = "liquid"))]
Network::Testnet4 => 40001,
#[cfg(not(feature = "liquid"))]
Network::Regtest => 60401,
#[cfg(not(feature = "liquid"))]
Network::Signet => 60601,
Expand All @@ -314,6 +318,8 @@ impl Config {
#[cfg(not(feature = "liquid"))]
Network::Testnet => 3001,
#[cfg(not(feature = "liquid"))]
Network::Testnet4 => 3004,
#[cfg(not(feature = "liquid"))]
Network::Regtest => 3002,
#[cfg(not(feature = "liquid"))]
Network::Signet => 3003,
Expand All @@ -331,6 +337,8 @@ impl Config {
#[cfg(not(feature = "liquid"))]
Network::Testnet => 14224,
#[cfg(not(feature = "liquid"))]
Network::Testnet4 => 44224,
#[cfg(not(feature = "liquid"))]
Network::Regtest => 24224,
#[cfg(not(feature = "liquid"))]
Network::Signet => 54224,
Expand Down Expand Up @@ -492,6 +500,8 @@ pub fn get_network_subdir(network: Network) -> Option<&'static str> {
#[cfg(not(feature = "liquid"))]
Network::Testnet => Some("testnet3"),
#[cfg(not(feature = "liquid"))]
Network::Testnet4 => Some("testnet4"),
#[cfg(not(feature = "liquid"))]
Network::Regtest => Some("regtest"),
#[cfg(not(feature = "liquid"))]
Network::Signet => Some("signet"),
Expand Down
103 changes: 101 additions & 2 deletions src/new_index/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use elements::encode::{deserialize, Decodable};

use std::collections::HashMap;
use std::fs;
use std::io::Cursor;
use std::path::PathBuf;
use std::sync::mpsc::Receiver;
use std::thread;
Expand Down Expand Up @@ -201,7 +200,7 @@ fn blkfiles_parser(blobs: Fetcher<Vec<u8>>, magic: u32) -> Fetcher<Vec<SizedBloc
}

fn parse_blocks(blob: Vec<u8>, magic: u32) -> Result<Vec<SizedBlock>> {
let mut cursor = Cursor::new(&blob);
let mut cursor = cursor::Cursor::new(&blob);
let mut slices = vec![];
let max_pos = blob.len() as u64;

Expand Down Expand Up @@ -249,3 +248,103 @@ fn parse_blocks(blob: Vec<u8>, magic: u32) -> Result<Vec<SizedBlock>> {
.collect()
}))
}

mod cursor {
use std::convert::TryInto;

pub struct Cursor<T> {
inner: T,
pos: u64,
}

impl<T: AsRef<[u8]>> Cursor<T> {
/// Creates a `Cursor` by wrapping `inner`.
#[inline]
pub fn new(inner: T) -> Self {
Cursor { inner, pos: 0 }
}

/// Returns the position read up to thus far.
#[inline]
pub fn position(&self) -> u64 {
self.pos
}

/// Sets the position to `pos`.
#[inline]
pub fn set_position(&mut self, pos: u64) {
self.pos = pos;
}

/// Returns the inner buffer.
///
/// This is the whole wrapped buffer, including the bytes already read.
#[inline]
#[allow(dead_code)]
pub fn into_inner(self) -> T {
self.inner
}
}

#[cfg(not(feature = "liquid"))]
impl<T: AsRef<[u8]>> bitcoin_io::Read for Cursor<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, bitcoin_io::Error> {
let inner: &[u8] = self.inner.as_ref();
let start_pos = self.pos.try_into().unwrap_or(inner.len());
let read = core::cmp::min(inner.len().saturating_sub(start_pos), buf.len());
buf[..read].copy_from_slice(&inner[start_pos..start_pos + read]);
self.pos = self.pos.saturating_add(
read.try_into()
.unwrap_or(u64::max_value() /* unreachable */),
);
Ok(read)
}
}

#[cfg(not(feature = "liquid"))]
impl<T: AsRef<[u8]>> bitcoin_io::BufRead for Cursor<T> {
#[inline]
fn fill_buf(&mut self) -> Result<&[u8], bitcoin_io::Error> {
let inner: &[u8] = self.inner.as_ref();
Ok(&inner[self.pos as usize..])
}

#[inline]
fn consume(&mut self, amount: usize) {
assert!(amount <= self.inner.as_ref().len());
self.pos += amount as u64;
}
}

#[cfg(feature = "liquid")]
impl<T: AsRef<[u8]>> std::io::Read for Cursor<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
let inner: &[u8] = self.inner.as_ref();
let start_pos = self.pos.try_into().unwrap_or(inner.len());
let read = core::cmp::min(inner.len().saturating_sub(start_pos), buf.len());
buf[..read].copy_from_slice(&inner[start_pos..start_pos + read]);
self.pos = self.pos.saturating_add(
read.try_into()
.unwrap_or(u64::max_value() /* unreachable */),
);
Ok(read)
}
}

#[cfg(feature = "liquid")]
impl<T: AsRef<[u8]>> std::io::BufRead for Cursor<T> {
#[inline]
fn fill_buf(&mut self) -> Result<&[u8], std::io::Error> {
let inner: &[u8] = self.inner.as_ref();
Ok(&inner[self.pos as usize..])
}

#[inline]
fn consume(&mut self, amount: usize) {
assert!(amount <= self.inner.as_ref().len());
self.pos += amount as u64;
}
}
}
4 changes: 2 additions & 2 deletions src/new_index/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::{BTreeSet, HashMap};
use std::sync::{Arc, RwLock, RwLockReadGuard};
use std::time::{Duration, Instant};

use crate::chain::{Network, OutPoint, Transaction, TxOut, Txid};
use crate::chain::{Network, OutPoint, Transaction, TxOperations, TxOut, Txid};
use crate::config::Config;
use crate::daemon::Daemon;
use crate::errors::*;
Expand Down Expand Up @@ -133,7 +133,7 @@ impl Query {
}

pub fn lookup_tx_spends(&self, tx: Transaction) -> Vec<Option<SpendingInput>> {
let txid = tx.txid();
let txid = TxOperations::txid(&tx);

tx.output
.par_iter()
Expand Down
Loading

0 comments on commit 0fe9284

Please sign in to comment.