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:
parent
3fa3e644ce
commit
a0f8f148ea
83
Cargo.lock
generated
83
Cargo.lock
generated
@ -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",
|
||||
|
@ -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"
|
||||
|
53
src/chain.rs
53
src/chain.rs
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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)?))
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
15
src/p2p.rs
15
src/p2p.rs
@ -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)
|
||||
|
@ -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})
|
||||
|
54
src/types.rs
54
src/types.rs
@ -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 }),
|
||||
|
Loading…
Reference in New Issue
Block a user