From 25a891d636151a23e7c343c077aa4b698656a5fa Mon Sep 17 00:00:00 2001 From: BinChengZhao Date: Wed, 3 Jul 2024 23:29:47 +0800 Subject: [PATCH] feat: testnet4 is supported with the latest rust-bitcoin --- Cargo.lock | 113 ++++++++++++++++++++-- Cargo.toml | 21 +++- src/bin/tx-fingerprint-stats.rs | 2 +- src/chain.rs | 46 +++++++-- src/config.rs | 29 ++++-- src/electrum/discovery.rs | 6 +- src/electrum/discovery/default_servers.rs | 2 +- src/new_index/fetch.rs | 70 +++++++++++++- src/new_index/mempool.rs | 2 +- src/new_index/query.rs | 2 +- src/new_index/schema.rs | 12 +-- src/rest.rs | 33 ++++--- src/util/electrum_merkle.rs | 2 +- src/util/script.rs | 3 +- src/util/transaction.rs | 4 +- 15 files changed, 290 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba517f5e4..0ac81cafc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "ascii" version = "1.1.0" @@ -123,6 +129,16 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base58ck" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +dependencies = [ + "bitcoin-internals 0.3.0", + "bitcoin_hashes 0.14.0", +] + [[package]] name = "base64" version = "0.10.1" @@ -177,6 +193,12 @@ version = "0.10.0-beta" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "bincode" version = "1.3.3" @@ -226,14 +248,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae" dependencies = [ "bech32 0.10.0-beta", - "bitcoin-internals", + "bitcoin-internals 0.2.0", "bitcoin_hashes 0.13.0", - "hex-conservative", + "hex-conservative 0.1.1", "hex_lit", "secp256k1 0.28.2", "serde", ] +[[package]] +name = "bitcoin" +version = "0.32.0-rc1" +source = "git+https://github.com/rust-bitcoin/rust-bitcoin.git?rev=refs/pull/2945/head#5c5ad25bcd203274b2e88b5b4c7bddf8fc328ff2" +dependencies = [ + "base58ck", + "bech32 0.11.0", + "bitcoin-internals 0.3.0", + "bitcoin-io", + "bitcoin-units", + "bitcoin_hashes 0.14.0", + "hex-conservative 0.2.1", + "secp256k1 0.29.0", + "serde", +] + [[package]] name = "bitcoin-internals" version = "0.2.0" @@ -243,12 +281,35 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin-internals" +version = "0.3.0" +source = "git+https://github.com/rust-bitcoin/rust-bitcoin.git?rev=refs/pull/2945/head#5c5ad25bcd203274b2e88b5b4c7bddf8fc328ff2" +dependencies = [ + "serde", +] + +[[package]] +name = "bitcoin-io" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" + [[package]] name = "bitcoin-private" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" +[[package]] +name = "bitcoin-units" +version = "0.1.1" +source = "git+https://github.com/rust-bitcoin/rust-bitcoin.git?rev=refs/pull/2945/head#5c5ad25bcd203274b2e88b5b4c7bddf8fc328ff2" +dependencies = [ + "bitcoin-internals 0.3.0", + "serde", +] + [[package]] name = "bitcoin_hashes" version = "0.10.0" @@ -273,8 +334,18 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" dependencies = [ - "bitcoin-internals", - "hex-conservative", + "bitcoin-internals 0.2.0", + "hex-conservative 0.1.1", + "serde", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "git+https://github.com/rust-bitcoin/rust-bitcoin.git?rev=refs/pull/2945/head#5c5ad25bcd203274b2e88b5b4c7bddf8fc328ff2" +dependencies = [ + "bitcoin-io", + "hex-conservative 0.2.1", "serde", ] @@ -641,7 +712,8 @@ dependencies = [ "arrayref", "base64 0.22.0", "bincode", - "bitcoin 0.31.2", + "bitcoin 0.32.0-rc1", + "bitcoin-io", "bitcoind 0.35.1", "clap", "crossbeam-channel", @@ -652,7 +724,7 @@ dependencies = [ "elementsd", "error-chain", "glob", - "hex-conservative", + "hex-conservative 0.2.1", "hyper", "hyperlocal", "itertools", @@ -936,6 +1008,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + [[package]] name = "hex_lit" version = "0.1.1" @@ -1887,6 +1968,17 @@ dependencies = [ "serde", ] +[[package]] +name = "secp256k1" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" +dependencies = [ + "bitcoin_hashes 0.13.0", + "secp256k1-sys 0.10.0", + "serde", +] + [[package]] name = "secp256k1-sys" version = "0.4.2" @@ -1905,6 +1997,15 @@ dependencies = [ "cc", ] +[[package]] +name = "secp256k1-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b" +dependencies = [ + "cc", +] + [[package]] name = "secp256k1-zkp" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index 72c569a86..da195f28c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,14 +20,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.0-rc1", 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 } 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" @@ -77,3 +78,19 @@ rev = "d3792352992a539afffbe11501d1aff9fd5b919d" # add-peer branch [patch.crates-io.electrumd] git = "https://github.com/shesek/electrumd" rev = "996fe2a8e563bc1bde6bbc2e0c2a2f4421abcdbc" + +[patch.crates-io.bitcoin] +git = "https://github.com/rust-bitcoin/rust-bitcoin.git" +rev = "refs/pull/2945/head" + +[patch.crates-io.bitcoin-units] +git = "https://github.com/rust-bitcoin/rust-bitcoin.git" +rev = "refs/pull/2945/head" + +[patch.crates-io.bitcoin_hashes] +git = "https://github.com/rust-bitcoin/rust-bitcoin.git" +rev = "refs/pull/2945/head" + +[patch.crates-io.bitcoin-internals] +git = "https://github.com/rust-bitcoin/rust-bitcoin.git" +rev = "refs/pull/2945/head" \ No newline at end of file diff --git a/src/bin/tx-fingerprint-stats.rs b/src/bin/tx-fingerprint-stats.rs index 8e4c35e30..e1f836add 100644 --- a/src/bin/tx-fingerprint-stats.rs +++ b/src/bin/tx-fingerprint-stats.rs @@ -61,7 +61,7 @@ fn main() { } let tx: Transaction = deserialize(&value).expect("failed to parse Transaction"); - let txid = tx.txid(); + let txid = tx.compute_txid(); iter.next(); diff --git a/src/chain.rs b/src/chain.rs index 16ebe75da..cc43e5069 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -14,8 +14,8 @@ pub use { }, }; -use bitcoin::blockdata::constants::genesis_block; pub use bitcoin::network::Network as BNetwork; +use bitcoin::{blockdata::constants::genesis_block, TestnetVersion as BTestnetVersion}; #[cfg(not(feature = "liquid"))] pub type Value = u64; @@ -27,7 +27,7 @@ pub enum Network { #[cfg(not(feature = "liquid"))] Bitcoin, #[cfg(not(feature = "liquid"))] - Testnet, + Testnet(TestnetVersion), #[cfg(not(feature = "liquid"))] Regtest, #[cfg(not(feature = "liquid"))] @@ -41,6 +41,15 @@ pub enum Network { LiquidRegtest, } +#[derive(Debug, Copy, Clone, PartialEq, Hash, Serialize, Ord, PartialOrd, Eq)] +pub enum TestnetVersion { + /// Testnet version 3. + V3, + /// Testnet version 4. + /// This is the latest testnet version. + V4, +} + impl Network { #[cfg(not(feature = "liquid"))] pub fn magic(self) -> u32 { @@ -97,6 +106,7 @@ impl Network { return vec![ "mainnet".to_string(), "testnet".to_string(), + "testnet4".to_string(), "regtest".to_string(), "signet".to_string(), ]; @@ -121,8 +131,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(); + genesis_block(BNetwork::Testnet(BTestnetVersion::V3)).block_hash(); + // TESTNET4_GENESIS is BlockHash of testnet4 + static ref TESTNET4_GENESIS: bitcoin::BlockHash = + genesis_block(BNetwork::Testnet(BTestnetVersion::V4)).block_hash(); static ref REGTEST_GENESIS: bitcoin::BlockHash = genesis_block(BNetwork::Regtest).block_hash(); static ref SIGNET_GENESIS: bitcoin::BlockHash = @@ -130,7 +144,8 @@ pub fn bitcoin_genesis_hash(network: BNetwork) -> bitcoin::BlockHash { } match network { BNetwork::Bitcoin => *BITCOIN_GENESIS, - BNetwork::Testnet => *TESTNET_GENESIS, + BNetwork::Testnet(BTestnetVersion::V3) => *TESTNET_GENESIS, + BNetwork::Testnet(BTestnetVersion::V4) => *TESTNET4_GENESIS, BNetwork::Regtest => *REGTEST_GENESIS, BNetwork::Signet => *SIGNET_GENESIS, _ => panic!("unknown network {:?}", network), @@ -163,7 +178,9 @@ impl From<&str> for Network { #[cfg(not(feature = "liquid"))] "mainnet" => Network::Bitcoin, #[cfg(not(feature = "liquid"))] - "testnet" => Network::Testnet, + "testnet" => Network::Testnet(TestnetVersion::V3), + #[cfg(not(feature = "liquid"))] + "testnet4" => Network::Testnet(TestnetVersion::V4), #[cfg(not(feature = "liquid"))] "regtest" => Network::Regtest, #[cfg(not(feature = "liquid"))] @@ -186,7 +203,8 @@ impl From for BNetwork { fn from(network: Network) -> Self { match network { Network::Bitcoin => BNetwork::Bitcoin, - Network::Testnet => BNetwork::Testnet, + Network::Testnet(TestnetVersion::V3) => BNetwork::Testnet(BTestnetVersion::V3), + Network::Testnet(TestnetVersion::V4) => BNetwork::Testnet(BTestnetVersion::V4), Network::Regtest => BNetwork::Regtest, Network::Signet => BNetwork::Signet, } @@ -198,10 +216,24 @@ impl From for Network { fn from(network: BNetwork) -> Self { match network { BNetwork::Bitcoin => Network::Bitcoin, - BNetwork::Testnet => Network::Testnet, + BNetwork::Testnet(BTestnetVersion::V3) => Network::Testnet(TestnetVersion::V3), + BNetwork::Testnet(BTestnetVersion::V4) => Network::Testnet(TestnetVersion::V4), BNetwork::Regtest => Network::Regtest, BNetwork::Signet => Network::Signet, _ => panic!("unknown network {:?}", network), } } } + +#[cfg(not(feature = "liquid"))] +impl From for &'static bitcoin::params::Params { + fn from(network: Network) -> Self { + match network { + Network::Bitcoin => &bitcoin::params::MAINNET, + Network::Testnet(TestnetVersion::V3) => &bitcoin::params::TESTNET, + Network::Testnet(TestnetVersion::V4) => &bitcoin::params::TESTNET4, + Network::Regtest => &bitcoin::params::REGTEST, + Network::Signet => &bitcoin::params::SIGNET, + } + } +} diff --git a/src/config.rs b/src/config.rs index 8696ecf8f..c0c78e307 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use stderrlog; use crate::chain::Network; +use crate::chain::TestnetVersion; use crate::daemon::CookieGetter; use crate::errors::*; @@ -117,25 +118,25 @@ 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( 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( @@ -257,7 +258,9 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Bitcoin => 8332, #[cfg(not(feature = "liquid"))] - Network::Testnet => 18332, + Network::Testnet(TestnetVersion::V3) => 18332, + #[cfg(not(feature = "liquid"))] + Network::Testnet(TestnetVersion::V4) => 48332, #[cfg(not(feature = "liquid"))] Network::Regtest => 18443, #[cfg(not(feature = "liquid"))] @@ -272,7 +275,9 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Bitcoin => 50001, #[cfg(not(feature = "liquid"))] - Network::Testnet => 60001, + Network::Testnet(TestnetVersion::V3) => 60001, + #[cfg(not(feature = "liquid"))] + Network::Testnet(TestnetVersion::V4) => 40001, #[cfg(not(feature = "liquid"))] Network::Regtest => 60401, #[cfg(not(feature = "liquid"))] @@ -289,7 +294,9 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Bitcoin => 3000, #[cfg(not(feature = "liquid"))] - Network::Testnet => 3001, + Network::Testnet(TestnetVersion::V3) => 3001, + #[cfg(not(feature = "liquid"))] + Network::Testnet(TestnetVersion::V4) => 3004, #[cfg(not(feature = "liquid"))] Network::Regtest => 3002, #[cfg(not(feature = "liquid"))] @@ -306,7 +313,9 @@ impl Config { #[cfg(not(feature = "liquid"))] Network::Bitcoin => 4224, #[cfg(not(feature = "liquid"))] - Network::Testnet => 14224, + Network::Testnet(TestnetVersion::V3) => 14224, + #[cfg(not(feature = "liquid"))] + Network::Testnet(TestnetVersion::V4) => 44224, #[cfg(not(feature = "liquid"))] Network::Regtest => 24224, #[cfg(not(feature = "liquid"))] @@ -461,7 +470,9 @@ pub fn get_network_subdir(network: Network) -> Option<&'static str> { #[cfg(not(feature = "liquid"))] Network::Bitcoin => None, #[cfg(not(feature = "liquid"))] - Network::Testnet => Some("testnet3"), + Network::Testnet(TestnetVersion::V3) => Some("testnet3"), + #[cfg(not(feature = "liquid"))] + Network::Testnet(TestnetVersion::V4) => Some("testnet4"), #[cfg(not(feature = "liquid"))] Network::Regtest => Some("regtest"), #[cfg(not(feature = "liquid"))] diff --git a/src/electrum/discovery.rs b/src/electrum/discovery.rs index cf70221f6..b270047f9 100644 --- a/src/electrum/discovery.rs +++ b/src/electrum/discovery.rs @@ -10,7 +10,7 @@ use std::time::{Duration, Instant}; use electrum_client::ElectrumApi; -use crate::chain::Network; +use crate::chain::{Network, TestnetVersion}; use crate::electrum::{Client, Hostname, Port, ProtocolVersion, ServerFeatures}; use crate::errors::{Result, ResultExt}; use crate::util::spawn_thread; @@ -534,14 +534,14 @@ mod tests { let features = ServerFeatures { hosts: serde_json::from_str("{\"test.foobar.example\":{\"tcp_port\":60002}}").unwrap(), server_version: format!("electrs-esplora 9"), - genesis_hash: genesis_hash(Network::Testnet), + genesis_hash: genesis_hash(Network::Testnet(TestnetVersion::V3)), protocol_min: PROTOCOL_VERSION, protocol_max: PROTOCOL_VERSION, hash_function: "sha256".into(), pruning: None, }; let discovery = Arc::new(DiscoveryManager::new( - Network::Testnet, + Network::Testnet(TestnetVersion::V3), features, PROTOCOL_VERSION, false, diff --git a/src/electrum/discovery/default_servers.rs b/src/electrum/discovery/default_servers.rs index 95754ecef..b5e2d795a 100644 --- a/src/electrum/discovery/default_servers.rs +++ b/src/electrum/discovery/default_servers.rs @@ -403,7 +403,7 @@ pub fn add_default_servers(discovery: &DiscoveryManager, network: Network) { .ok(); } #[cfg(not(feature = "liquid"))] - Network::Testnet => { + Network::Testnet(TestnetVersion::V3) => { discovery .add_default_server( "hsmithsxurybd7uh.onion".into(), diff --git a/src/new_index/fetch.rs b/src/new_index/fetch.rs index 54369b5e5..3291299a8 100644 --- a/src/new_index/fetch.rs +++ b/src/new_index/fetch.rs @@ -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; @@ -187,7 +186,7 @@ fn blkfiles_parser(blobs: Fetcher>, magic: u32) -> Fetcher, magic: u32) -> Result> { - let mut cursor = Cursor::new(&blob); + let mut cursor = cursor::Cursor::new(&blob); let mut slices = vec![]; let max_pos = blob.len() as u64; @@ -235,3 +234,70 @@ fn parse_blocks(blob: Vec, magic: u32) -> Result> { .collect() })) } + +mod cursor { + use std::convert::TryInto; + + pub struct Cursor { + inner: T, + pos: u64, + } + + impl> Cursor { + /// 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 + } + } + + impl> bitcoin_io::Read for Cursor { + #[inline] + fn read(&mut self, buf: &mut [u8]) -> Result { + 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) + } + } + + impl> bitcoin_io::BufRead for Cursor { + #[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; + } + } +} diff --git a/src/new_index/mempool.rs b/src/new_index/mempool.rs index 179829fd2..689e9bbdc 100644 --- a/src/new_index/mempool.rs +++ b/src/new_index/mempool.rs @@ -305,7 +305,7 @@ impl Mempool { let mut txids = vec![]; // Phase 1: add to txstore for tx in txs { - let txid = tx.txid(); + let txid = tx.compute_txid(); txids.push(txid); self.txstore.insert(txid, tx); } diff --git a/src/new_index/query.rs b/src/new_index/query.rs index 1e621ac0d..e57c3d0cd 100644 --- a/src/new_index/query.rs +++ b/src/new_index/query.rs @@ -132,7 +132,7 @@ impl Query { } pub fn lookup_tx_spends(&self, tx: Transaction) -> Vec> { - let txid = tx.txid(); + let txid = tx.compute_txid(); tx.output .par_iter() diff --git a/src/new_index/schema.rs b/src/new_index/schema.rs index d5eba9a51..ee2660f96 100644 --- a/src/new_index/schema.rs +++ b/src/new_index/schema.rs @@ -830,7 +830,7 @@ impl ChainQuery { let _timer = self.start_timer("lookup_txn"); self.lookup_raw_txn(txid, blockhash).map(|rawtx| { let txn: Transaction = deserialize(&rawtx).expect("failed to parse Transaction"); - assert_eq!(*txid, txn.txid()); + assert_eq!(*txid, txn.compute_txid()); txn }) } @@ -982,7 +982,7 @@ fn add_blocks(block_entries: &[BlockEntry], iconfig: &IndexerConfig) -> Vec = b.block.txdata.iter().map(|tx| tx.txid()).collect(); + let txids: Vec = b.block.txdata.iter().map(|tx| tx.compute_txid()).collect(); for tx in &b.block.txdata { add_transaction(tx, blockhash, &mut rows, iconfig); } @@ -1012,7 +1012,7 @@ fn add_transaction( rows.push(TxRow::new(tx).into_row()); } - let txid = full_hash(&tx.txid()[..]); + let txid = full_hash(&tx.compute_txid()[..]); for (txo_index, txo) in tx.output.iter().enumerate() { if is_spendable(txo) { rows.push(TxOutRow::new(&txid, txo_index, txo).into_row()); @@ -1099,7 +1099,7 @@ fn index_transaction( // H{funding-scripthash}{spending-height}S{spending-txid:vin}{funding-txid:vout} → "" // persist "edges" for fast is-this-TXO-spent check // S{funding-txid:vout}{spending-txid:vin} → "" - let txid = full_hash(&tx.txid()[..]); + let txid = full_hash(&tx.compute_txid()[..]); for (txo_index, txo) in tx.output.iter().enumerate() { if is_spendable(txo) || iconfig.index_unspendables { let history = TxHistoryRow::new( @@ -1200,7 +1200,7 @@ struct TxRow { impl TxRow { fn new(txn: &Transaction) -> TxRow { - let txid = full_hash(&txn.txid()[..]); + let txid = full_hash(&txn.compute_txid()[..]); TxRow { key: TxRowKey { code: b'T', txid }, value: serialize(txn), @@ -1233,7 +1233,7 @@ struct TxConfRow { impl TxConfRow { fn new(txn: &Transaction, blockhash: FullHash) -> TxConfRow { - let txid = full_hash(&txn.txid()[..]); + let txid = full_hash(&txn.compute_txid()[..]); TxConfRow { key: TxConfKey { code: b'C', diff --git a/src/rest.rs b/src/rest.rs index 336c43f4a..483925680 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -81,8 +81,9 @@ struct BlockValue { impl BlockValue { #[cfg_attr(feature = "liquid", allow(unused_variables))] - fn new(blockhm: BlockHeaderMeta) -> Self { + fn new(blockhm: BlockHeaderMeta, network: Network) -> Self { let header = blockhm.header_entry.header(); + let bnetwork: bitcoin::Network = network.into(); BlockValue { id: header.block_hash(), height: blockhm.header_entry.height() as u32, @@ -107,7 +108,7 @@ impl BlockValue { #[cfg(not(feature = "liquid"))] nonce: header.nonce, #[cfg(not(feature = "liquid"))] - difficulty: header.difficulty_float(), + difficulty: header.difficulty_float(bnetwork), #[cfg(feature = "liquid")] ext: Some(header.ext.clone()), @@ -158,7 +159,7 @@ impl TransactionValue { let weight = weight.to_wu(); TransactionValue { - txid: tx.txid(), + txid: tx.compute_txid(), #[cfg(not(feature = "liquid"))] version: tx.version.0 as u32, #[cfg(feature = "liquid")] @@ -319,7 +320,7 @@ impl TxOutValue { "v0_p2wsh" } else if script.is_p2tr() { "v1_p2tr" - } else if script.is_provably_unspendable() { + } else if script.is_op_return() { "provably_unspendable" } else { "unknown" @@ -618,7 +619,7 @@ fn handle_request( (&Method::GET, Some(&"blocks"), start_height, None, None, None) => { let start_height = start_height.and_then(|height| height.parse::().ok()); - blocks(&query, start_height) + blocks(&query, start_height, config.network_type) } (&Method::GET, Some(&"block-height"), Some(height), None, None, None) => { let height = height.parse::()?; @@ -635,7 +636,7 @@ fn handle_request( .chain() .get_block_with_meta(&hash) .ok_or_else(|| HttpError::not_found("Block not found".to_string()))?; - let block_value = BlockValue::new(blockhm); + let block_value = BlockValue::new(blockhm, config.network_type); json_response(block_value, TTL_LONG) } (&Method::GET, Some(&"block"), Some(hash), Some(&"status"), None, None) => { @@ -1154,7 +1155,11 @@ fn json_response(value: T, ttl: u32) -> Result, Htt .unwrap()) } -fn blocks(query: &Query, start_height: Option) -> Result, HttpError> { +fn blocks( + query: &Query, + start_height: Option, + network: Network, +) -> Result, HttpError> { let mut values = Vec::new(); let mut current_hash = match start_height { Some(height) => *query @@ -1174,7 +1179,7 @@ fn blocks(query: &Query, start_height: Option) -> Result, current_hash = blockhm.header_entry.header().prev_blockhash; #[allow(unused_mut)] - let mut value = BlockValue::new(blockhm); + let mut value = BlockValue::new(blockhm, network); #[cfg(feature = "liquid")] { @@ -1266,12 +1271,12 @@ impl From for HttpError { HttpError::from("Invalid hex string".to_string()) } } -impl From for HttpError { - fn from(_e: bitcoin::address::Error) -> Self { - //HttpError::from(e.description().to_string()) - HttpError::from("Invalid Bitcoin address".to_string()) - } -} +// impl From for HttpError { +// fn from(_e: bitcoin::address::Error) -> Self { +// //HttpError::from(e.description().to_string()) +// HttpError::from("Invalid Bitcoin address".to_string()) +// } +// } impl From for HttpError { fn from(e: errors::Error) -> Self { warn!("errors::Error: {:?}", e); diff --git a/src/util/electrum_merkle.rs b/src/util/electrum_merkle.rs index 954782a7d..479126da2 100644 --- a/src/util/electrum_merkle.rs +++ b/src/util/electrum_merkle.rs @@ -1,7 +1,7 @@ use crate::chain::{BlockHash, Txid}; use crate::errors::*; use crate::new_index::ChainQuery; -use bitcoin::hashes::{sha256d::Hash as Sha256dHash, Hash}; +use bitcoin::hashes::sha256d::Hash as Sha256dHash; pub fn get_tx_merkle_proof( chain: &ChainQuery, diff --git a/src/util/script.rs b/src/util/script.rs index 8d6d42e73..5a5d35c37 100644 --- a/src/util/script.rs +++ b/src/util/script.rs @@ -27,7 +27,8 @@ pub trait ScriptToAddr { #[cfg(not(feature = "liquid"))] impl ScriptToAddr for bitcoin::Script { fn to_address_str(&self, network: Network) -> Option { - bitcoin::Address::from_script(self, network.into()) + let bnetwork = bitcoin::Network::from(network); + bitcoin::Address::from_script(self, bnetwork) .map(|s| s.to_string()) .ok() } diff --git a/src/util/transaction.rs b/src/util/transaction.rs index dda5e4f7c..209032cdd 100644 --- a/src/util/transaction.rs +++ b/src/util/transaction.rs @@ -70,9 +70,9 @@ pub fn has_prevout(txin: &TxIn) -> bool { pub fn is_spendable(txout: &TxOut) -> bool { #[cfg(not(feature = "liquid"))] - return !txout.script_pubkey.is_provably_unspendable(); + return !txout.script_pubkey.is_op_return(); #[cfg(feature = "liquid")] - return !txout.is_fee() && !txout.script_pubkey.is_provably_unspendable(); + return !txout.is_fee() && !txout.script_pubkey.is_op_return(); } pub fn extract_tx_prevouts<'a>(