1
0
mirror of https://github.com/romanz/electrs.git synced 2024-11-19 01:43:29 +01:00

Upgrade bitcoin to 0.30 (#865)

* Upgrade `bitcoin` to 0.30

This upgrades `bitcoin` to the newest release.

Closes #863
This commit is contained in:
Martin Habovštiak 2023-03-29 21:44:25 +02:00 committed by GitHub
parent 3fa3e644ce
commit a0f8f148ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 165 additions and 137 deletions

83
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
@ -78,22 +80,31 @@ dependencies = [
[[package]]
name = "bitcoin"
version = "0.29.2"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3"
checksum = "b36f4c848f6bd9ff208128f08751135846cc23ae57d66ab10a22efff1c675f3c"
dependencies = [
"bech32",
"bitcoin-private",
"bitcoin_hashes",
"hex_lit",
"secp256k1",
"serde",
]
[[package]]
name = "bitcoin_hashes"
version = "0.11.0"
name = "bitcoin-private"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57"
[[package]]
name = "bitcoin_hashes"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
dependencies = [
"bitcoin-private",
"serde",
]
@ -111,12 +122,11 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cargo_toml"
version = "0.8.1"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513d17226888c7b8283ac02a1c1b0d8a9d4cbf6db65dfadb79f598f5d7966fe9"
checksum = "1aecd74f843e919090741163a59948751f6f57b5a9b3d7a4a4d278e17b6a16cf"
dependencies = [
"serde",
"serde_derive",
"toml",
]
@ -181,13 +191,12 @@ dependencies = [
[[package]]
name = "configure_me_codegen"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "981fb98983781be95b91dc4ce7c178ae000f91350d783d43d1ce8adc4963c91f"
checksum = "ad4bfdee5b1410b1d3b4239172e6f4573d2d47a14a11cd397dac083233dbe3e3"
dependencies = [
"cargo_toml",
"fmt2io",
"man",
"serde",
"serde_derive",
"toml",
@ -288,6 +297,7 @@ dependencies = [
"electrs-bitcoincore-rpc",
"electrs-rocksdb",
"env_logger",
"hex_lit",
"log",
"parking_lot",
"prometheus",
@ -302,10 +312,11 @@ dependencies = [
[[package]]
name = "electrs-bitcoincore-rpc"
version = "0.17.0-e1"
version = "0.17.0-e3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6335d754b72adc93ad32888179f44e1541ed2c96d3fecd6a85ceab593cd47a"
checksum = "eaf7b2057d11c3e4313cd0934f71383956f33433828e8a3cd0c8284b4a61fdd8"
dependencies = [
"bitcoin-private",
"electrs-bitcoincore-rpc-json",
"jsonrpc",
"log",
@ -315,11 +326,12 @@ dependencies = [
[[package]]
name = "electrs-bitcoincore-rpc-json"
version = "0.17.0-e1"
version = "0.17.0-e3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39db3b291c38e433fcfc1ab70f2cd9b9af44c6a8d24fca477ca00cd9574dcbe6"
checksum = "49a4aae914a774c9b5dcff9c21bdb39557e61e7970f56729db1de5002eb83085"
dependencies = [
"bitcoin",
"bitcoin-private",
"serde",
"serde_json",
]
@ -445,6 +457,12 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hex_lit"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
[[package]]
name = "httpdate"
version = "1.0.2"
@ -554,15 +572,6 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "man"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccbbb1d623a3cbcaeef9a072f7ccbd6f8ca1e788f3e301d5c49bdd67b1f5a942"
dependencies = [
"roff",
]
[[package]]
name = "memchr"
version = "2.4.1"
@ -647,9 +656,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "ppv-lite86"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
@ -796,12 +805,6 @@ version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "roff"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33e4fb37ba46888052c763e4ec2acfedd8f00f62897b630cadb6298b833675e"
[[package]]
name = "rustc-hash"
version = "1.1.0"
@ -836,9 +839,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "secp256k1"
version = "0.24.2"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3"
checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
dependencies = [
"bitcoin_hashes",
"rand",
@ -848,27 +851,27 @@ dependencies = [
[[package]]
name = "secp256k1-sys"
version = "0.6.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7058dc8eaf3f2810d7828680320acda0b25a288f6d288e19278e249bbf74226b"
checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
dependencies = [
"cc",
]
[[package]]
name = "serde"
version = "1.0.142"
version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2"
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.142"
version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e"
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
dependencies = [
"proc-macro2",
"quote",

View File

@ -22,7 +22,7 @@ spec = "internal/config_specification.toml"
[dependencies]
anyhow = "1.0"
bitcoin = { version = "0.29.2", features = ["serde", "rand"] }
bitcoin = { version = "0.30.0", features = ["serde", "rand-std"] }
configure_me = "0.4"
crossbeam-channel = "0.5"
dirs-next = "2.0"
@ -36,9 +36,10 @@ serde_derive = "1.0"
serde_json = "1.0"
signal-hook = "0.3"
tiny_http = { version = "0.12", optional = true }
hex_lit = "0.1.1"
[dependencies.electrs-bitcoincore-rpc]
version = "0.17.0-e1"
version = "0.17.0-e3"
[dependencies.electrs-rocksdb]
# Workaround the following issues:
@ -51,7 +52,7 @@ default-features = false
features = ["zstd", "snappy"]
[build-dependencies]
configure_me_codegen = "0.4.3"
configure_me_codegen = { version = "0.4.3", default-features = false }
[dev-dependencies]
tempfile = "3.4"

View File

@ -1,7 +1,8 @@
use std::collections::HashMap;
use bitcoin::blockdata::block::Header as BlockHeader;
use bitcoin::network::constants;
use bitcoin::{BlockHash, BlockHeader};
use bitcoin::BlockHash;
/// A new header found, to be added to the chain at specific height
pub(crate) struct NewHeader {
@ -145,41 +146,43 @@ impl Chain {
#[cfg(test)]
mod tests {
use super::{Chain, NewHeader};
use bitcoin::blockdata::block::Header as BlockHeader;
use bitcoin::consensus::deserialize;
use bitcoin::hashes::hex::{FromHex, ToHex};
use bitcoin::network::constants::Network::Regtest;
use bitcoin::BlockHeader;
use hex_lit::hex;
#[test]
fn test_genesis() {
let regtest = Chain::new(Regtest);
assert_eq!(regtest.height(), 0);
assert_eq!(
regtest.tip().to_hex(),
regtest.tip(),
"0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
.parse()
.unwrap()
);
}
#[test]
fn test_updates() {
let hex_headers = vec![
"0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f1d14d3c7ff12d6adf494ebbcfba69baa915a066358b68a2b8c37126f74de396b1d61cc60ffff7f2000000000",
"00000020d700ae5d3c705702e0a5d9ababd22ded079f8a63b880b1866321d6bfcb028c3fc816efcf0e84ccafa1dda26be337f58d41b438170c357cda33a68af5550590bc1e61cc60ffff7f2004000000",
"00000020d13731bc59bc0989e06a5e7cab9843a4e17ad65c7ca47cd77f50dfd24f1f55793f7f342526aca9adb6ce8f33d8a07662c97d29d83b9e18117fb3eceecb2ab99b1e61cc60ffff7f2001000000",
"00000020a603def3e1255cadfb6df072946327c58b344f9bfb133e8e3e280d1c2d55b31c731a68f70219472864a7cb010cd53dc7e0f67e57f7d08b97e5e092b0c3942ad51f61cc60ffff7f2001000000",
"0000002041dd202b3b2edcdd3c8582117376347d48ff79ff97c95e5ac814820462012e785142dc360975b982ca43eecd14b4ba6f019041819d4fc5936255d7a2c45a96651f61cc60ffff7f2000000000",
"0000002072e297a2d6b633c44f3c9b1a340d06f3ce4e6bcd79ebd4c4ff1c249a77e1e37c59c7be1ca0964452e1735c0d2740f0d98a11445a6140c36b55770b5c0bcf801f1f61cc60ffff7f2000000000",
"000000200c9eb5889a8e924d1c4e8e79a716514579e41114ef37d72295df8869d6718e4ac5840f28de43ff25c7b9200aaf7873b20587c92827eaa61943484ca828bdd2e11f61cc60ffff7f2000000000",
"000000205873f322b333933e656b07881bb399dae61a6c0fa74188b5fb0e3dd71c9e2442f9e2f433f54466900407cf6a9f676913dd54aad977f7b05afcd6dcd81e98ee752061cc60ffff7f2004000000",
"00000020fd1120713506267f1dba2e1856ca1d4490077d261cde8d3e182677880df0d856bf94cfa5e189c85462813751ab4059643759ed319a81e0617113758f8adf67bc2061cc60ffff7f2000000000",
"000000200030d7f9c11ef35b89a0eefb9a5e449909339b5e7854d99804ea8d6a49bf900a0304d2e55fe0b6415949cff9bca0f88c0717884a5e5797509f89f856af93624a2061cc60ffff7f2002000000",
let byte_headers = [
hex!("0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f1d14d3c7ff12d6adf494ebbcfba69baa915a066358b68a2b8c37126f74de396b1d61cc60ffff7f2000000000"),
hex!("00000020d700ae5d3c705702e0a5d9ababd22ded079f8a63b880b1866321d6bfcb028c3fc816efcf0e84ccafa1dda26be337f58d41b438170c357cda33a68af5550590bc1e61cc60ffff7f2004000000"),
hex!("00000020d13731bc59bc0989e06a5e7cab9843a4e17ad65c7ca47cd77f50dfd24f1f55793f7f342526aca9adb6ce8f33d8a07662c97d29d83b9e18117fb3eceecb2ab99b1e61cc60ffff7f2001000000"),
hex!("00000020a603def3e1255cadfb6df072946327c58b344f9bfb133e8e3e280d1c2d55b31c731a68f70219472864a7cb010cd53dc7e0f67e57f7d08b97e5e092b0c3942ad51f61cc60ffff7f2001000000"),
hex!("0000002041dd202b3b2edcdd3c8582117376347d48ff79ff97c95e5ac814820462012e785142dc360975b982ca43eecd14b4ba6f019041819d4fc5936255d7a2c45a96651f61cc60ffff7f2000000000"),
hex!("0000002072e297a2d6b633c44f3c9b1a340d06f3ce4e6bcd79ebd4c4ff1c249a77e1e37c59c7be1ca0964452e1735c0d2740f0d98a11445a6140c36b55770b5c0bcf801f1f61cc60ffff7f2000000000"),
hex!("000000200c9eb5889a8e924d1c4e8e79a716514579e41114ef37d72295df8869d6718e4ac5840f28de43ff25c7b9200aaf7873b20587c92827eaa61943484ca828bdd2e11f61cc60ffff7f2000000000"),
hex!("000000205873f322b333933e656b07881bb399dae61a6c0fa74188b5fb0e3dd71c9e2442f9e2f433f54466900407cf6a9f676913dd54aad977f7b05afcd6dcd81e98ee752061cc60ffff7f2004000000"),
hex!("00000020fd1120713506267f1dba2e1856ca1d4490077d261cde8d3e182677880df0d856bf94cfa5e189c85462813751ab4059643759ed319a81e0617113758f8adf67bc2061cc60ffff7f2000000000"),
hex!("000000200030d7f9c11ef35b89a0eefb9a5e449909339b5e7854d99804ea8d6a49bf900a0304d2e55fe0b6415949cff9bca0f88c0717884a5e5797509f89f856af93624a2061cc60ffff7f2002000000"),
];
let headers: Vec<BlockHeader> = hex_headers
let headers: Vec<BlockHeader> = byte_headers
.iter()
.map(|hex_header| deserialize(&Vec::from_hex(hex_header).unwrap()).unwrap())
.map(|byte_header| deserialize(byte_header).unwrap())
.collect();
for chunk_size in 1..hex_headers.len() {
for chunk_size in 1..headers.len() {
let mut regtest = Chain::new(Regtest);
let mut height = 0;
let mut tip = regtest.tip();
@ -220,15 +223,19 @@ mod tests {
}
assert_eq!(regtest.height(), 0);
assert_eq!(
regtest.tip().to_hex(),
regtest.tip(),
"0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
.parse()
.unwrap()
);
regtest.drop_last_headers(1);
assert_eq!(regtest.height(), 0);
assert_eq!(
regtest.tip().to_hex(),
regtest.tip(),
"0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
.parse()
.unwrap()
);
// test reorg
@ -236,12 +243,14 @@ mod tests {
regtest.load(headers.clone(), headers.last().unwrap().block_hash());
let height = regtest.height();
let new_header: BlockHeader = deserialize(&Vec::from_hex("000000200030d7f9c11ef35b89a0eefb9a5e449909339b5e7854d99804ea8d6a49bf900a0304d2e55fe0b6415949cff9bca0f88c0717884a5e5797509f89f856af93624a7a6bcc60ffff7f2000000000").unwrap()).unwrap();
let new_header: BlockHeader = deserialize(&hex!("000000200030d7f9c11ef35b89a0eefb9a5e449909339b5e7854d99804ea8d6a49bf900a0304d2e55fe0b6415949cff9bca0f88c0717884a5e5797509f89f856af93624a7a6bcc60ffff7f2000000000")).unwrap();
regtest.update(vec![NewHeader::from((new_header, height))]);
assert_eq!(regtest.height(), height);
assert_eq!(
regtest.tip().to_hex(),
regtest.tip(),
"0e16637fe0700a7c52e9a6eaa58bd6ac7202652103be8f778680c66f51ad2e9b"
.parse()
.unwrap()
);
}
}

View File

@ -142,7 +142,7 @@ pub struct Config {
pub sync_once: bool,
pub disable_electrum_rpc: bool,
pub server_banner: String,
pub signet_magic: u32,
pub signet_magic: bitcoin::network::Magic,
pub args: Vec<String>,
}
@ -196,11 +196,17 @@ impl Config {
internal::Config::including_optional_config_files(default_config_files())
.unwrap_or_exit();
fn unsupported_network(network: Network) -> ! {
eprintln!("Error: unsupported network: {}", network);
std::process::exit(1);
}
let db_subdir = match config.network {
Network::Bitcoin => "bitcoin",
Network::Testnet => "testnet",
Network::Regtest => "regtest",
Network::Signet => "signet",
unsupported => unsupported_network(unsupported),
};
config.db_dir.push(db_subdir);
@ -210,36 +216,38 @@ impl Config {
Network::Testnet => 18332,
Network::Regtest => 18443,
Network::Signet => 38332,
unsupported => unsupported_network(unsupported),
};
let default_daemon_p2p_port = match config.network {
Network::Bitcoin => 8333,
Network::Testnet => 18333,
Network::Regtest => 18444,
Network::Signet => 38333,
unsupported => unsupported_network(unsupported),
};
let default_electrum_port = match config.network {
Network::Bitcoin => 50001,
Network::Testnet => 60001,
Network::Regtest => 60401,
Network::Signet => 60601,
unsupported => unsupported_network(unsupported),
};
let default_monitoring_port = match config.network {
Network::Bitcoin => 4224,
Network::Testnet => 14224,
Network::Regtest => 24224,
Network::Signet => 34224,
unsupported => unsupported_network(unsupported),
};
let magic = match (config.network, config.signet_magic) {
(Network::Signet, Some(magic)) => u32::from_str_radix(&magic, 16)
.unwrap_or_else(|error| {
eprintln!(
"Error: signet magic '{}' is not a valid hex string: {}",
magic, error
);
std::process::exit(1);
})
.swap_bytes(),
(Network::Signet, Some(magic)) => magic.parse().unwrap_or_else(|error| {
eprintln!(
"Error: signet magic '{}' is not a valid hex string: {}",
magic, error
);
std::process::exit(1);
}),
(network, None) => network.magic(),
(_, Some(_)) => {
eprintln!("Error: signet magic only available on signet");
@ -276,6 +284,7 @@ impl Config {
Network::Testnet => config.daemon_dir.push("testnet3"),
Network::Regtest => config.daemon_dir.push("regtest"),
Network::Signet => config.daemon_dir.push("signet"),
unsupported => unsupported_network(unsupported),
}
let daemon_dir = &config.daemon_dir;

View File

@ -1,8 +1,6 @@
use anyhow::{Context, Result};
use bitcoin::{
consensus::serialize, hashes::hex::ToHex, Amount, Block, BlockHash, Transaction, Txid,
};
use bitcoin::{Amount, Block, BlockHash, Transaction, Txid};
use bitcoincore_rpc::{json, jsonrpc, Auth, Client, RpcApi};
use crossbeam_channel::Receiver;
use parking_lot::Mutex;
@ -183,8 +181,13 @@ impl Daemon {
txid: &Txid,
blockhash: Option<BlockHash>,
) -> Result<Value> {
use bitcoin::consensus::serde::{hex::Lower, Hex, With};
let tx = self.get_transaction(txid, blockhash)?;
Ok(json!(serialize(&tx).to_hex()))
#[derive(serde::Serialize)]
#[serde(transparent)]
struct TxAsHex(#[serde(with = "With::<Hex<Lower>>")] Transaction);
serde_json::to_value(&TxAsHex(tx)).map_err(Into::into)
}
pub(crate) fn get_transaction(

View File

@ -1,7 +1,7 @@
use anyhow::{bail, Context, Result};
use bitcoin::{
consensus::{deserialize, serialize},
hashes::hex::{FromHex, ToHex},
consensus::{deserialize, encode::serialize_hex},
hashes::hex::FromHex,
BlockHash, Txid,
};
use crossbeam_channel::Receiver;
@ -193,7 +193,7 @@ impl Rpc {
let header = chain.get_block_header(height).unwrap();
notifications.push(notification(
"blockchain.headers.subscribe",
&[json!({"hex": serialize(&header).to_hex(), "height": height})],
&[json!({"hex": serialize_hex(&header), "height": height})],
));
}
}
@ -205,7 +205,7 @@ impl Rpc {
client.tip = Some(chain.tip());
let height = chain.height();
let header = chain.get_block_header(height).unwrap();
Ok(json!({"hex": serialize(header).to_hex(), "height": height}))
Ok(json!({"hex": serialize_hex(header), "height": height}))
}
fn block_header(&self, (height,): (usize,)) -> Result<Value> {
@ -214,7 +214,7 @@ impl Rpc {
None => bail!("no header at {}", height),
Some(header) => header,
};
Ok(json!(serialize(header).to_hex()))
Ok(json!(serialize_hex(header)))
}
fn block_headers(&self, (start_height, count): (usize, usize)) -> Result<Value> {
@ -230,7 +230,7 @@ impl Rpc {
let hex_headers = heights.filter_map(|height| {
chain
.get_block_header(height)
.map(|header| serialize(header).to_hex())
.map(|header| serialize_hex(header))
});
Ok(json!({"count": count, "hex": String::from_iter(hex_headers), "max": max_count}))
@ -374,8 +374,8 @@ impl Rpc {
.map(|(blockhash, _tx)| blockhash);
return self.daemon.get_transaction_info(&txid, blockhash);
}
if let Some(tx) = self.cache.get_tx(&txid, |tx| serialize(tx)) {
return Ok(json!(tx.to_hex()));
if let Some(tx) = self.cache.get_tx(&txid, |tx| serialize_hex(tx)) {
return Ok(json!(tx));
}
debug!("tx cache miss: txid={}", txid);
// use internal index to load confirmed transaction without an RPC
@ -384,7 +384,7 @@ impl Rpc {
.lookup_transaction(&self.daemon, txid)?
.map(|(_blockhash, tx)| tx)
{
return Ok(json!(serialize(&tx).to_hex()));
return Ok(json!(serialize_hex(&tx)));
}
// load unconfirmed transaction via RPC
Ok(json!(self.daemon.get_transaction_hex(&txid, None)?))

View File

@ -38,12 +38,12 @@ pub(crate) struct Mempool {
// Smallest possible txid
fn txid_min() -> Txid {
Txid::from_inner([0x00; 32])
Txid::all_zeros()
}
// Largest possible txid
fn txid_max() -> Txid {
Txid::from_inner([0xFF; 32])
Txid::from_byte_array([0xFF; 32])
}
impl Mempool {

View File

@ -1,7 +1,4 @@
use bitcoin::{
hashes::{hex::ToHex, Hash},
TxMerkleNode, Txid,
};
use bitcoin::{hash_types::TxMerkleNode, hashes::Hash, Txid};
pub(crate) struct Proof {
proof: Vec<TxMerkleNode>,
@ -14,7 +11,7 @@ impl Proof {
let mut offset = position;
let mut hashes: Vec<TxMerkleNode> = txids
.iter()
.map(|txid| TxMerkleNode::from_hash(txid.as_hash()))
.map(|txid| TxMerkleNode::from_raw_hash(txid.to_raw_hash()))
.collect();
let mut proof = vec![];
@ -44,7 +41,10 @@ impl Proof {
}
pub(crate) fn to_hex(&self) -> Vec<String> {
self.proof.iter().map(|node| node.to_hex()).collect()
self.proof
.iter()
.map(|node| format!("{:x}", node))
.collect()
}
pub(crate) fn position(&self) -> usize {

View File

@ -1,10 +1,11 @@
use anyhow::{Context, Result};
use bitcoin::blockdata::block::Header as BlockHeader;
use bitcoin::{
consensus::{
encode::{self, ReadExt, VarInt},
Decodable,
},
hashes::{hex::ToHex, Hash},
hashes::Hash,
network::{
address, constants,
message::{self, CommandString, NetworkMessage},
@ -12,7 +13,7 @@ use bitcoin::{
message_network,
},
secp256k1::{self, rand::Rng},
Block, BlockHash, BlockHeader, Network,
Block, BlockHash, Network,
};
use crossbeam_channel::{bounded, select, Receiver, Sender};
@ -129,7 +130,7 @@ impl Connection {
network: Network,
address: SocketAddr,
metrics: &Metrics,
magic: u32,
magic: bitcoin::network::Magic,
) -> Result<Self> {
let conn = Arc::new(
TcpStream::connect(address)
@ -252,7 +253,7 @@ impl Connection {
let label = format!("parse_{}", raw_msg.cmd.as_ref());
let msg = match parse_duration.observe_duration(&label, || raw_msg.parse()) {
Ok(msg) => msg,
Err(err) => bail!("failed to parse '{}({})': {}", raw_msg.cmd, raw_msg.raw.to_hex(), err),
Err(err) => bail!("failed to parse '{}({:?})': {}", raw_msg.cmd, raw_msg.raw, err),
};
trace!("recv: {:?}", msg);
@ -336,7 +337,7 @@ fn build_version_message() -> NetworkMessage {
}
struct RawNetworkMessage {
magic: u32,
magic: bitcoin::network::Magic,
cmd: CommandString,
raw: Vec<u8>,
}
@ -364,9 +365,9 @@ impl RawNetworkMessage {
"alert" => NetworkMessage::Alert(Decodable::consensus_decode(&mut raw)?),
"addr" => NetworkMessage::Addr(Decodable::consensus_decode(&mut raw)?),
_ => bail!(
"unsupported message: command={}, payload={}",
"unsupported message: command={}, payload={:?}",
self.cmd,
self.raw.to_hex()
self.raw
),
};
Ok(payload)

View File

@ -92,7 +92,7 @@ pub(crate) struct HistoryEntry {
height: Height,
#[serde(
skip_serializing_if = "Option::is_none",
with = "bitcoin::util::amount::serde::as_sat::opt"
with = "bitcoin::amount::serde::as_sat::opt"
)]
fee: Option<Amount>,
}
@ -135,9 +135,9 @@ pub struct ScriptHashStatus {
/// Specific scripthash balance
#[derive(Default, Eq, PartialEq, Serialize)]
pub(crate) struct Balance {
#[serde(with = "bitcoin::util::amount::serde::as_sat", rename = "confirmed")]
#[serde(with = "bitcoin::amount::serde::as_sat", rename = "confirmed")]
confirmed_balance: Amount,
#[serde(with = "bitcoin::util::amount::serde::as_sat", rename = "unconfirmed")]
#[serde(with = "bitcoin::amount::serde::as_sat", rename = "unconfirmed")]
mempool_delta: SignedAmount,
}
@ -148,7 +148,7 @@ pub(crate) struct UnspentEntry {
height: usize, // 0 = mempool entry
tx_hash: Txid,
tx_pos: u32,
#[serde(with = "bitcoin::util::amount::serde::as_sat")]
#[serde(with = "bitcoin::amount::serde::as_sat")]
value: Amount,
}
@ -542,14 +542,14 @@ fn filter_block_txs<T: Send>(
#[cfg(test)]
mod tests {
use super::HistoryEntry;
use bitcoin::{hashes::hex::FromHex, Amount, Txid};
use bitcoin::Amount;
use serde_json::json;
#[test]
fn test_txinfo_json() {
let txid =
Txid::from_hex("5b75086dafeede555fc8f9a810d8b10df57c46f9f176ccc3dd8d2fa20edd685b")
.unwrap();
let txid = "5b75086dafeede555fc8f9a810d8b10df57c46f9f176ccc3dd8d2fa20edd685b"
.parse()
.unwrap();
assert_eq!(
json!(HistoryEntry::confirmed(txid, 123456)),
json!({"tx_hash": "5b75086dafeede555fc8f9a810d8b10df57c46f9f176ccc3dd8d2fa20edd685b", "height": 123456})

View File

@ -2,10 +2,11 @@ use anyhow::Result;
use std::convert::TryFrom;
use bitcoin::blockdata::block::Header as BlockHeader;
use bitcoin::{
consensus::encode::{deserialize, serialize, Decodable, Encodable},
hashes::{hash_newtype, sha256, Hash},
BlockHeader, OutPoint, Script, Txid,
OutPoint, Script, Txid,
};
use crate::db;
@ -64,17 +65,15 @@ impl HashPrefixRow {
impl_consensus_encoding!(HashPrefixRow, prefix, height);
hash_newtype!(
ScriptHash,
sha256::Hash,
32,
doc = "https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html#script-hashes",
true
);
hash_newtype! {
/// https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html#script-hashes
#[hash_newtype(backward)]
pub struct ScriptHash(sha256::Hash);
}
impl ScriptHash {
pub fn new(script: &Script) -> Self {
ScriptHash::hash(&script[..])
ScriptHash::hash(script.as_bytes())
}
fn prefix(&self) -> HashPrefix {
@ -101,13 +100,10 @@ impl ScriptHashRow {
// ***************************************************************************
hash_newtype!(
StatusHash,
sha256::Hash,
32,
doc = "https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html#status",
false
);
hash_newtype! {
/// https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html#status
pub struct StatusHash(sha256::Hash);
}
// ***************************************************************************
@ -182,7 +178,8 @@ impl HeaderRow {
#[cfg(test)]
mod tests {
use crate::types::{spending_prefix, HashPrefixRow, ScriptHash, ScriptHashRow, TxidRow};
use bitcoin::{hashes::hex::ToHex, Address, OutPoint, Txid};
use bitcoin::{Address, OutPoint, Txid};
use hex_lit::hex;
use serde_json::{from_str, json};
use std::str::FromStr;
@ -201,18 +198,22 @@ mod tests {
let scripthash: ScriptHash = from_str(&hex).unwrap();
let row1 = ScriptHashRow::row(scripthash, 123456);
let db_row = row1.to_db_row();
assert_eq!(db_row[..].to_hex(), "a384491d38929fcc40e20100");
assert_eq!(&*db_row, &hex!("a384491d38929fcc40e20100"));
let row2 = HashPrefixRow::from_db_row(&db_row);
assert_eq!(row1, row2);
}
#[test]
fn test_scripthash() {
let addr = Address::from_str("1KVNjD3AAnQ3gTMqoTKcWFeqSFujq9gTBT").unwrap();
let addr = Address::from_str("1KVNjD3AAnQ3gTMqoTKcWFeqSFujq9gTBT")
.unwrap()
.assume_checked();
let scripthash = ScriptHash::new(&addr.script_pubkey());
assert_eq!(
scripthash.to_hex(),
scripthash,
"00dfb264221d07712a144bda338e89237d1abd2db4086057573895ea2659766a"
.parse()
.unwrap()
);
}
@ -225,8 +226,8 @@ mod tests {
let row1 = TxidRow::row(txid, 91812);
let row2 = TxidRow::row(txid, 91842);
assert_eq!(row1.to_db_row().to_hex(), "9985d82954e10f22a4660100");
assert_eq!(row2.to_db_row().to_hex(), "9985d82954e10f22c2660100");
assert_eq!(&*row1.to_db_row(), &hex!("9985d82954e10f22a4660100"));
assert_eq!(&*row2.to_db_row(), &hex!("9985d82954e10f22c2660100"));
}
#[test]
@ -239,14 +240,15 @@ mod tests {
let row2 = TxidRow::row(txid, 91880);
// low-endian encoding => rows should be sorted according to block height
assert_eq!(row1.to_db_row().to_hex(), "68b45f58b674e94e4a660100");
assert_eq!(row2.to_db_row().to_hex(), "68b45f58b674e94ee8660100");
assert_eq!(&*row1.to_db_row(), &hex!("68b45f58b674e94e4a660100"));
assert_eq!(&*row2.to_db_row(), &hex!("68b45f58b674e94ee8660100"));
}
#[test]
fn test_spending_prefix() {
let hex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
let txid = Txid::from_str(hex).unwrap();
let txid = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
.parse()
.unwrap();
assert_eq!(
spending_prefix(OutPoint { txid, vout: 0 }),