├── .gitignore ├── src ├── wallet │ ├── mod.rs │ └── mnemonic.rs ├── network │ ├── mod.rs │ ├── seed_iter.rs │ └── network.rs ├── lib.rs ├── util │ ├── serdes.rs │ ├── hash160.rs │ ├── mod.rs │ ├── var_int.rs │ ├── latch.rs │ ├── future.rs │ ├── result.rs │ ├── hash256.rs │ ├── bits.rs │ ├── bloom_filter.rs │ └── rx.rs ├── messages │ ├── ping.rs │ ├── fee_filter.rs │ ├── tx_out.rs │ ├── node_addr_ex.rs │ ├── out_point.rs │ ├── send_cmpct.rs │ ├── inv_vect.rs │ ├── tx_in.rs │ ├── filter_add.rs │ ├── node_addr.rs │ ├── block_locator.rs │ ├── filter_load.rs │ ├── inv.rs │ ├── mod.rs │ ├── addr.rs │ ├── headers.rs │ ├── reject.rs │ ├── message_header.rs │ ├── block_header.rs │ ├── version.rs │ ├── block.rs │ └── merkle_block.rs ├── transaction │ ├── mod.rs │ ├── p2pkh.rs │ └── sighash.rs ├── peer │ ├── mod.rs │ └── atomic_reader.rs ├── address │ └── mod.rs └── script │ ├── stack.rs │ └── mod.rs ├── README.md ├── Cargo.toml └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | # Outputs 2 | /target/ 3 | 4 | # Backup files generated by rust-fmt 5 | **/*.rs.bk 6 | 7 | # Local dependencies 8 | Cargo.lock 9 | 10 | # OS and IDE files 11 | .DS_STORE 12 | .vscode 13 | 14 | -------------------------------------------------------------------------------- /src/wallet/mod.rs: -------------------------------------------------------------------------------- 1 | //! Wallet and key management 2 | 3 | mod extended_key; 4 | mod mnemonic; 5 | 6 | pub use self::extended_key::{ 7 | derive_extended_key, ExtendedKey, ExtendedKeyType, HARDENED_KEY, MAINNET_PRIVATE_EXTENDED_KEY, 8 | MAINNET_PUBLIC_EXTENDED_KEY, TESTNET_PRIVATE_EXTENDED_KEY, TESTNET_PUBLIC_EXTENDED_KEY, 9 | }; 10 | pub use self::mnemonic::{load_wordlist, mnemonic_decode, mnemonic_encode, Wordlist}; 11 | -------------------------------------------------------------------------------- /src/network/mod.rs: -------------------------------------------------------------------------------- 1 | //! Configuration for mainnet and testnet 2 | //! 3 | //! # Examples 4 | //! 5 | //! Iterate through seed nodes: 6 | //! 7 | //! ```no_run, rust 8 | //! use sv::network::Network; 9 | //! 10 | //! for (ip, port) in Network::Mainnet.seed_iter() { 11 | //! println!("Seed node {:?}:{}", ip, port); 12 | //! } 13 | //! ``` 14 | 15 | mod network; 16 | mod seed_iter; 17 | 18 | pub use self::network::Network; 19 | pub use self::seed_iter::SeedIter; 20 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A foundation for building applications on Bitcoin SV using Rust. 2 | 3 | extern crate byteorder; 4 | extern crate digest; 5 | extern crate dns_lookup; 6 | extern crate hex; 7 | #[macro_use] 8 | extern crate log; 9 | extern crate linked_hash_map; 10 | extern crate murmur3; 11 | extern crate rand; 12 | extern crate ring; 13 | extern crate ripemd160; 14 | extern crate rust_base58; 15 | extern crate secp256k1; 16 | extern crate snowflake; 17 | 18 | pub mod address; 19 | pub mod messages; 20 | pub mod network; 21 | pub mod peer; 22 | pub mod script; 23 | pub mod transaction; 24 | pub mod util; 25 | pub mod wallet; 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust-SV 2 | 3 | A library to build Bitcoin SV applications and infrastructure in Rust. 4 | 5 | [Documentation](https://docs.rs/sv/) 6 | 7 | Features 8 | 9 | * P2P protocol messages (construction and serialization) 10 | * Address encoding and decoding 11 | * Transaction signing 12 | * Script evaluation 13 | * Node connections and basic message handling 14 | * Wallet key derivation and mnemonic parsing 15 | * Mainnet and testnet support 16 | * Various Bitcoin primitives 17 | * Genesis upgrade support 18 | 19 | # Installation 20 | 21 | Add ```sv = "0.2"``` to Cargo.toml 22 | 23 | # Known limitations 24 | 25 | This library should not be used for consensus code because its validation checks are incomplete. 26 | 27 | # License 28 | 29 | rust-sv is licensed under the MIT license. 30 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sv" 3 | version = "0.2.2" 4 | description = "A Rust library for working with Bitcoin SV" 5 | repository = "https://github.com/brentongunning/rust-sv" 6 | authors = ["Brenton Gunning "] 7 | keywords = ["bitcoin", "sv", "cash", "crypto"] 8 | license = "MIT" 9 | edition = "2018" 10 | 11 | [dependencies] 12 | byteorder = "1.2" 13 | digest = "0.7" 14 | dns-lookup = "0.9" 15 | hex = "0.3" 16 | linked-hash-map = "0.5" 17 | log = { version = "0.4", features = ["max_level_trace", "release_max_level_warn"] } 18 | murmur3 = "0.4" 19 | num-bigint = "0.2" 20 | num-traits = "0.2" 21 | rand = "0.5" 22 | ring = "0.14" 23 | ripemd160 = "0.7" 24 | rust-base58 = "0.0" 25 | rust-crypto = "0.2" 26 | secp256k1 = "0.12" 27 | snowflake = "1.3" 28 | 29 | [profile.release] 30 | opt-level = "s" # Optimize for size over speed 31 | lto = true # Enable link-time optimizations to shrink binary 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Brenton Gunning 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/util/serdes.rs: -------------------------------------------------------------------------------- 1 | use crate::util::Result; 2 | use std::io; 3 | use std::io::{Read, Write}; 4 | 5 | /// An object that may be serialized and deserialized 6 | pub trait Serializable { 7 | /// Reads the object from serialized form 8 | fn read(reader: &mut dyn Read) -> Result 9 | where 10 | Self: Sized; 11 | 12 | /// Writes the object to serialized form 13 | fn write(&self, writer: &mut dyn Write) -> io::Result<()>; 14 | } 15 | 16 | impl Serializable<[u8; 16]> for [u8; 16] { 17 | fn read(reader: &mut dyn Read) -> Result<[u8; 16]> { 18 | let mut d = [0; 16]; 19 | reader.read(&mut d)?; 20 | Ok(d) 21 | } 22 | 23 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 24 | writer.write(self)?; 25 | Ok(()) 26 | } 27 | } 28 | 29 | impl Serializable<[u8; 32]> for [u8; 32] { 30 | fn read(reader: &mut dyn Read) -> Result<[u8; 32]> { 31 | let mut d = [0; 32]; 32 | reader.read(&mut d)?; 33 | Ok(d) 34 | } 35 | 36 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 37 | writer.write(self)?; 38 | Ok(()) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/util/hash160.rs: -------------------------------------------------------------------------------- 1 | use digest::{FixedOutput, Input}; 2 | use hex; 3 | use ring::digest::{digest, SHA256}; 4 | use ripemd160::{Digest, Ripemd160}; 5 | use std::fmt; 6 | 7 | /// 160-bit hash for public key addresses 8 | #[derive(Default, Clone, Copy, PartialEq, Eq, Hash)] 9 | pub struct Hash160(pub [u8; 20]); 10 | 11 | /// Hashes a data array once with SHA256 and again with RIPEMD160 12 | pub fn hash160(data: &[u8]) -> Hash160 { 13 | let sha256 = digest(&SHA256, data); 14 | let mut ripemd160 = Ripemd160::new(); 15 | ripemd160.process(sha256.as_ref()); 16 | let mut hash160 = [0; 20]; 17 | hash160.clone_from_slice(&ripemd160.fixed_result()); 18 | Hash160(hash160) 19 | } 20 | 21 | impl fmt::Debug for Hash160 { 22 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 23 | write!(f, "{}", hex::encode(self.0)) 24 | } 25 | } 26 | 27 | #[cfg(test)] 28 | mod tests { 29 | use super::*; 30 | use hex; 31 | 32 | #[test] 33 | fn tohash160() { 34 | let pubkey = "126999eabe3f84a3a9f5c09e87faab27484818a0ec1d67b94c9a02e40268499d98538cf770198550adfb9d1d473e5e926bb00e4c58baec1fb42ffa6069781003e4"; 35 | let pubkey = hex::decode(pubkey).unwrap(); 36 | assert!(hex::encode(hash160(&pubkey).0) == "3c231b5e624a42e99a87160c6e4231718a6d77c0"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/util/mod.rs: -------------------------------------------------------------------------------- 1 | //! Miscellaneous helpers 2 | 3 | use std::time::SystemTime; 4 | 5 | #[allow(dead_code)] 6 | mod bits; 7 | mod bloom_filter; 8 | #[allow(dead_code)] 9 | mod future; 10 | #[allow(dead_code)] 11 | mod hash160; 12 | mod hash256; 13 | #[allow(dead_code)] 14 | mod latch; 15 | mod result; 16 | pub mod rx; 17 | mod serdes; 18 | pub(crate) mod var_int; 19 | 20 | pub(crate) use self::bits::{lshift, rshift, Bits}; 21 | #[allow(dead_code)] 22 | pub use self::bloom_filter::{ 23 | BloomFilter, BLOOM_FILTER_MAX_FILTER_SIZE, BLOOM_FILTER_MAX_HASH_FUNCS, 24 | }; 25 | pub use self::hash160::{hash160, Hash160}; 26 | pub use self::hash256::{sha256d, Hash256}; 27 | pub use self::result::{Error, Result}; 28 | #[allow(unused_imports)] 29 | pub use self::serdes::Serializable; 30 | 31 | /// Gets the time in seconds since a time in the past 32 | pub fn secs_since(time: SystemTime) -> u32 { 33 | SystemTime::now().duration_since(time).unwrap().as_secs() as u32 34 | } 35 | 36 | /// Block height that BCH and BTC forked on mainnet 37 | pub const BITCOIN_CASH_FORK_HEIGHT_MAINNET: i32 = 478558; 38 | 39 | /// Block height that BCH and BTC forked on testnet 40 | pub const BITCOIN_CASH_FORK_HEIGHT_TESTNET: i32 = 1155875; 41 | 42 | /// Block height that activated the genesis upgrade on mainnet 43 | pub const GENESIS_UPGRADE_HEIGHT_MAINNET: i32 = 620538; 44 | 45 | /// Block height that activated the genesis upgrade on testnet 46 | pub const GENESIS_UPGRADE_HEIGHT_TESTNET: i32 = 1344302; 47 | -------------------------------------------------------------------------------- /src/messages/ping.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::util::{Result, Serializable}; 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Ping or pong payload 8 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 9 | pub struct Ping { 10 | /// Unique identifier nonce 11 | pub nonce: u64, 12 | } 13 | 14 | impl Ping { 15 | /// Size of the ping or pong payload in bytes 16 | pub const SIZE: usize = 8; 17 | } 18 | 19 | impl Serializable for Ping { 20 | fn read(reader: &mut dyn Read) -> Result { 21 | let nonce = reader.read_u64::()?; 22 | Ok(Ping { nonce }) 23 | } 24 | 25 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 26 | writer.write_u64::(self.nonce) 27 | } 28 | } 29 | 30 | impl Payload for Ping { 31 | fn size(&self) -> usize { 32 | Ping::SIZE 33 | } 34 | } 35 | 36 | #[cfg(test)] 37 | mod tests { 38 | use super::*; 39 | use hex; 40 | use std::io::Cursor; 41 | 42 | #[test] 43 | fn read_bytes() { 44 | let b = hex::decode("86b19332b96c657d".as_bytes()).unwrap(); 45 | let f = Ping::read(&mut Cursor::new(&b)).unwrap(); 46 | assert!(f.nonce == 9035747770062057862); 47 | } 48 | 49 | #[test] 50 | fn write_read() { 51 | let mut v = Vec::new(); 52 | let p = Ping { nonce: 13579 }; 53 | p.write(&mut v).unwrap(); 54 | assert!(v.len() == p.size()); 55 | assert!(Ping::read(&mut Cursor::new(&v)).unwrap() == p); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/messages/fee_filter.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::util::{Result, Serializable}; 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Specifies the minimum transaction fee this node accepts 8 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 9 | pub struct FeeFilter { 10 | /// Minimum fee accepted by the node in sats/1000 bytes 11 | pub minfee: u64, 12 | } 13 | 14 | impl FeeFilter { 15 | /// Size of the fee filter payload in bytes 16 | pub const SIZE: usize = 8; 17 | } 18 | 19 | impl Serializable for FeeFilter { 20 | fn read(reader: &mut dyn Read) -> Result { 21 | let minfee = reader.read_u64::()?; 22 | Ok(FeeFilter { minfee }) 23 | } 24 | 25 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 26 | writer.write_u64::(self.minfee) 27 | } 28 | } 29 | 30 | impl Payload for FeeFilter { 31 | fn size(&self) -> usize { 32 | FeeFilter::SIZE 33 | } 34 | } 35 | 36 | #[cfg(test)] 37 | mod tests { 38 | use super::*; 39 | use hex; 40 | use std::io::Cursor; 41 | 42 | #[test] 43 | fn read_bytes() { 44 | let b = hex::decode("e803000000000000".as_bytes()).unwrap(); 45 | let f = FeeFilter::read(&mut Cursor::new(&b)).unwrap(); 46 | assert!(f.minfee == 1000); 47 | } 48 | 49 | #[test] 50 | fn write_read() { 51 | let mut v = Vec::new(); 52 | let f = FeeFilter { minfee: 1234 }; 53 | f.write(&mut v).unwrap(); 54 | assert!(v.len() == f.size()); 55 | assert!(FeeFilter::read(&mut Cursor::new(&v)).unwrap() == f); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/transaction/mod.rs: -------------------------------------------------------------------------------- 1 | //! Build and sign transactions 2 | //! 3 | //! # Examples 4 | //! 5 | //! Sign a transaction: 6 | //! 7 | //! ```rust 8 | //! use sv::messages::{Tx, TxIn}; 9 | //! use sv::transaction::generate_signature; 10 | //! use sv::transaction::p2pkh::{create_lock_script, create_unlock_script}; 11 | //! use sv::transaction::sighash::{sighash, SigHashCache, SIGHASH_FORKID, SIGHASH_NONE}; 12 | //! use sv::util::{hash160}; 13 | //! 14 | //! // Use real values here 15 | //! let mut tx = Tx { 16 | //! inputs: vec![TxIn { 17 | //! ..Default::default() 18 | //! }], 19 | //! ..Default::default() 20 | //! }; 21 | //! let private_key = [1; 32]; 22 | //! let public_key = [1; 33]; 23 | //! 24 | //! let lock_script = create_lock_script(&hash160(&public_key)); 25 | //! let mut cache = SigHashCache::new(); 26 | //! let sighash_type = SIGHASH_NONE | SIGHASH_FORKID; 27 | //! let sighash = sighash(&tx, 0, &lock_script.0, 0, sighash_type, &mut cache).unwrap(); 28 | //! let signature = generate_signature(&private_key, &sighash, sighash_type).unwrap(); 29 | //! tx.inputs[0].unlock_script = create_unlock_script(&signature, &public_key); 30 | //! ``` 31 | 32 | use crate::util::{Hash256, Result}; 33 | use secp256k1::{Message, Secp256k1, SecretKey}; 34 | 35 | pub mod p2pkh; 36 | pub mod sighash; 37 | 38 | /// Generates a signature for a transaction sighash 39 | pub fn generate_signature( 40 | private_key: &[u8; 32], 41 | sighash: &Hash256, 42 | sighash_type: u8, 43 | ) -> Result> { 44 | let secp = Secp256k1::signing_only(); 45 | let message = Message::from_slice(&sighash.0)?; 46 | let secret_key = SecretKey::from_slice(private_key)?; 47 | let mut signature = secp.sign(&message, &secret_key); 48 | signature.normalize_s(); 49 | let mut sig = signature.serialize_der(); 50 | sig.push(sighash_type); 51 | Ok(sig) 52 | } 53 | -------------------------------------------------------------------------------- /src/messages/tx_out.rs: -------------------------------------------------------------------------------- 1 | use crate::script::Script; 2 | use crate::util::{var_int, Result, Serializable}; 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Transaction output 8 | #[derive(Debug, PartialEq, Eq, Hash, Clone)] 9 | pub struct TxOut { 10 | /// Number of satoshis to spend 11 | pub satoshis: i64, 12 | /// Public key script to claim the output 13 | pub lock_script: Script, 14 | } 15 | 16 | impl TxOut { 17 | /// Returns the size of the transaction output in bytes 18 | pub fn size(&self) -> usize { 19 | 8 + var_int::size(self.lock_script.0.len() as u64) + self.lock_script.0.len() 20 | } 21 | } 22 | 23 | impl Serializable for TxOut { 24 | fn read(reader: &mut dyn Read) -> Result { 25 | let satoshis = reader.read_i64::()?; 26 | let script_len = var_int::read(reader)?; 27 | let mut lock_script = Script(vec![0; script_len as usize]); 28 | reader.read(&mut lock_script.0)?; 29 | Ok(TxOut { 30 | satoshis, 31 | lock_script, 32 | }) 33 | } 34 | 35 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 36 | writer.write_i64::(self.satoshis)?; 37 | var_int::write(self.lock_script.0.len() as u64, writer)?; 38 | writer.write(&self.lock_script.0)?; 39 | Ok(()) 40 | } 41 | } 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | use super::*; 46 | use std::io::Cursor; 47 | 48 | #[test] 49 | fn write_read() { 50 | let mut v = Vec::new(); 51 | let t = TxOut { 52 | satoshis: 4400044000, 53 | lock_script: Script(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 99, 98, 97, 96]), 54 | }; 55 | t.write(&mut v).unwrap(); 56 | assert!(v.len() == t.size()); 57 | assert!(TxOut::read(&mut Cursor::new(&v)).unwrap() == t); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/messages/node_addr_ex.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::node_addr::NodeAddr; 2 | use crate::util::{Result, Serializable}; 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Node network address extended with a last connected time 8 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 9 | pub struct NodeAddrEx { 10 | /// Last connected time in seconds since the unix epoch 11 | pub last_connected_time: u32, 12 | /// Node address 13 | pub addr: NodeAddr, 14 | } 15 | 16 | impl NodeAddrEx { 17 | /// Size of the NodeAddrEx in bytes 18 | pub const SIZE: usize = NodeAddr::SIZE + 4; 19 | 20 | /// Returns the size of the address in bytes 21 | pub fn size(&self) -> usize { 22 | NodeAddrEx::SIZE 23 | } 24 | } 25 | 26 | impl Serializable for NodeAddrEx { 27 | fn read(reader: &mut dyn Read) -> Result { 28 | Ok(NodeAddrEx { 29 | last_connected_time: reader.read_u32::()?, 30 | addr: NodeAddr::read(reader)?, 31 | }) 32 | } 33 | 34 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 35 | writer.write_u32::(self.last_connected_time)?; 36 | self.addr.write(writer)?; 37 | Ok(()) 38 | } 39 | } 40 | 41 | #[cfg(test)] 42 | mod tests { 43 | use super::*; 44 | use std::io::Cursor; 45 | use std::net::Ipv6Addr; 46 | 47 | #[test] 48 | fn write_read() { 49 | let mut v = Vec::new(); 50 | let a = NodeAddrEx { 51 | last_connected_time: 12345, 52 | addr: NodeAddr { 53 | services: 1, 54 | ip: Ipv6Addr::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), 55 | port: 123, 56 | }, 57 | }; 58 | a.write(&mut v).unwrap(); 59 | assert!(v.len() == a.size()); 60 | assert!(NodeAddrEx::read(&mut Cursor::new(&v)).unwrap() == a); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/messages/out_point.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Hash256, Result, Serializable}; 2 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 3 | use std::io; 4 | use std::io::{Read, Write}; 5 | 6 | /// The coinbase transaction input will have this hash 7 | pub const COINBASE_OUTPOINT_HASH: Hash256 = Hash256([0; 32]); 8 | /// The coinbase transaction input will have this index 9 | pub const COINBASE_OUTPOINT_INDEX: u32 = 0xffffffff; 10 | 11 | /// Reference to a transaction output 12 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 13 | pub struct OutPoint { 14 | /// Hash of the referenced transaction 15 | pub hash: Hash256, 16 | /// Index of the output in the transaction, zero-indexed 17 | pub index: u32, 18 | } 19 | 20 | impl OutPoint { 21 | /// Size of the out point in bytes 22 | pub const SIZE: usize = 36; 23 | 24 | /// Returns the size of the out point in bytes 25 | pub fn size(&self) -> usize { 26 | OutPoint::SIZE 27 | } 28 | } 29 | 30 | impl Serializable for OutPoint { 31 | fn read(reader: &mut dyn Read) -> Result { 32 | let hash = Hash256::read(reader)?; 33 | let index = reader.read_u32::()?; 34 | Ok(OutPoint { hash, index }) 35 | } 36 | 37 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 38 | self.hash.write(writer)?; 39 | writer.write_u32::(self.index)?; 40 | Ok(()) 41 | } 42 | } 43 | 44 | #[cfg(test)] 45 | mod tests { 46 | use super::*; 47 | use std::io::Cursor; 48 | 49 | #[test] 50 | fn write_read() { 51 | let mut v = Vec::new(); 52 | let t = OutPoint { 53 | hash: Hash256::decode( 54 | "123412345678567890ab90abcdefcdef123412345678567890ab90abcdefcdef", 55 | ) 56 | .unwrap(), 57 | index: 0, 58 | }; 59 | t.write(&mut v).unwrap(); 60 | assert!(v.len() == t.size()); 61 | assert!(OutPoint::read(&mut Cursor::new(&v)).unwrap() == t); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/messages/send_cmpct.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::util::{Result, Serializable}; 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Specifies whether compact blocks are supported 8 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 9 | pub struct SendCmpct { 10 | /// Whether compact blocks may be sent 11 | pub enable: u8, 12 | /// Should always be 1 13 | pub version: u64, 14 | } 15 | 16 | impl SendCmpct { 17 | /// Size of the SendCmpct payload in bytes 18 | pub const SIZE: usize = 9; 19 | 20 | /// Returns whether compact blocks should be used 21 | pub fn use_cmpctblock(&self) -> bool { 22 | self.enable == 1 && self.version == 1 23 | } 24 | } 25 | 26 | impl Serializable for SendCmpct { 27 | fn read(reader: &mut dyn Read) -> Result { 28 | let enable = reader.read_u8()?; 29 | let version = reader.read_u64::()?; 30 | Ok(SendCmpct { enable, version }) 31 | } 32 | 33 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 34 | writer.write_u8(self.enable)?; 35 | writer.write_u64::(self.version) 36 | } 37 | } 38 | 39 | impl Payload for SendCmpct { 40 | fn size(&self) -> usize { 41 | SendCmpct::SIZE 42 | } 43 | } 44 | 45 | #[cfg(test)] 46 | mod tests { 47 | use super::*; 48 | use hex; 49 | use std::io::Cursor; 50 | 51 | #[test] 52 | fn read_bytes() { 53 | let b = hex::decode("000100000000000000".as_bytes()).unwrap(); 54 | let f = SendCmpct::read(&mut Cursor::new(&b)).unwrap(); 55 | assert!(f.enable == 0); 56 | assert!(f.version == 1); 57 | } 58 | 59 | #[test] 60 | fn write_read() { 61 | let mut v = Vec::new(); 62 | let s = SendCmpct { 63 | enable: 1, 64 | version: 1, 65 | }; 66 | s.write(&mut v).unwrap(); 67 | assert!(v.len() == s.size()); 68 | assert!(SendCmpct::read(&mut Cursor::new(&v)).unwrap() == s); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/network/seed_iter.rs: -------------------------------------------------------------------------------- 1 | use dns_lookup::lookup_host; 2 | use rand::{thread_rng, Rng}; 3 | use std::net::IpAddr; 4 | 5 | /// Iterates through DNS seeds semi-randomly 6 | #[derive(Clone)] 7 | pub struct SeedIter { 8 | /// Port that is common to all IPs 9 | pub port: u16, 10 | seeds: Vec, 11 | nodes: Vec, 12 | seed_index: usize, 13 | node_index: usize, 14 | random_offset: usize, 15 | } 16 | 17 | impl SeedIter { 18 | /// Creates a new seed iterator from a list of DNS seeds 19 | pub fn new(seeds: &Vec, port: u16) -> SeedIter { 20 | SeedIter { 21 | seeds: seeds.clone(), 22 | port, 23 | nodes: Vec::new(), 24 | seed_index: 0, 25 | node_index: 0, 26 | random_offset: thread_rng().gen_range::(0, 100), 27 | } 28 | } 29 | } 30 | 31 | impl Iterator for SeedIter { 32 | type Item = (IpAddr, u16); 33 | fn next(&mut self) -> Option<(IpAddr, u16)> { 34 | loop { 35 | if self.seed_index == self.seeds.len() { 36 | return None; 37 | } 38 | 39 | if self.nodes.len() == 0 { 40 | let i = (self.seed_index + self.random_offset) % self.seeds.len(); 41 | info!("Looking up DNS {:?}", self.seeds[i]); 42 | match lookup_host(&self.seeds[i]) { 43 | Ok(ip_list) => self.nodes = ip_list, 44 | Err(e) => { 45 | error!("Failed to look up DNS {:?}: {}", self.seeds[i], e); 46 | self.seed_index += 1; 47 | continue; 48 | } 49 | } 50 | } 51 | 52 | if self.node_index == self.nodes.len() { 53 | self.node_index = 0; 54 | self.seed_index += 1; 55 | self.nodes.clear(); 56 | } else { 57 | let i = (self.node_index + self.random_offset) % self.nodes.len(); 58 | self.node_index += 1; 59 | return Some((self.nodes[i], self.port)); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/messages/inv_vect.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Hash256, Result, Serializable}; 2 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 3 | use std::io; 4 | use std::io::{Read, Write}; 5 | 6 | // Inventory vector types 7 | 8 | /// May be ignored 9 | pub const INV_VECT_ERROR: u32 = 0; 10 | /// Hash of a transaction 11 | pub const INV_VECT_TX: u32 = 1; 12 | /// Hash of a block header. 13 | pub const INV_VECT_BLOCK: u32 = 2; 14 | /// Hash of a block header. Indicates the reply should be a merkleblock message. 15 | pub const INV_VECT_FILTERED_BLOCK: u32 = 3; 16 | /// Hash of a block header. Indicates the reply should be a cmpctblock message. 17 | pub const INV_VECT_COMPACT_BLOCK: u32 = 4; 18 | 19 | /// Inventory vector describing an object being requested or announced 20 | #[derive(Debug, PartialEq, Eq, Hash, Clone)] 21 | pub struct InvVect { 22 | // Object type linked to this inventory 23 | pub obj_type: u32, 24 | /// Hash of the object 25 | pub hash: Hash256, 26 | } 27 | 28 | impl InvVect { 29 | /// Size of the inventory vector in bytes 30 | pub const SIZE: usize = 36; 31 | 32 | /// Returns the size of the inventory vector in bytes 33 | pub fn size(&self) -> usize { 34 | InvVect::SIZE 35 | } 36 | } 37 | 38 | impl Serializable for InvVect { 39 | fn read(reader: &mut dyn Read) -> Result { 40 | let inv_vect = InvVect { 41 | obj_type: reader.read_u32::()?, 42 | hash: Hash256::read(reader)?, 43 | }; 44 | Ok(inv_vect) 45 | } 46 | 47 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 48 | writer.write_u32::(self.obj_type as u32)?; 49 | self.hash.write(writer) 50 | } 51 | } 52 | 53 | #[cfg(test)] 54 | mod tests { 55 | use super::*; 56 | use std::io::Cursor; 57 | 58 | #[test] 59 | fn write_read() { 60 | let mut v = Vec::new(); 61 | let iv = InvVect { 62 | obj_type: INV_VECT_TX, 63 | hash: Hash256([8; 32]), 64 | }; 65 | iv.write(&mut v).unwrap(); 66 | assert!(v.len() == iv.size()); 67 | assert!(InvVect::read(&mut Cursor::new(&v)).unwrap() == iv); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/util/var_int.rs: -------------------------------------------------------------------------------- 1 | //! Functions to read and write variable length integers 2 | 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Returns the number of bytes required 8 | pub fn size(n: u64) -> usize { 9 | return if n <= 252 { 10 | 1 11 | } else if n <= 0xffff { 12 | 3 13 | } else if n <= 0xffffffff { 14 | 5 15 | } else { 16 | 9 17 | }; 18 | } 19 | 20 | /// Writes the var int to bytes 21 | pub fn write(n: u64, writer: &mut dyn Write) -> io::Result<()> { 22 | if n <= 252 { 23 | writer.write_u8(n as u8)?; 24 | } else if n <= 0xffff { 25 | writer.write_u8(0xfd)?; 26 | writer.write_u16::(n as u16)?; 27 | } else if n <= 0xffffffff { 28 | writer.write_u8(0xfe)?; 29 | writer.write_u32::(n as u32)?; 30 | } else { 31 | writer.write_u8(0xff)?; 32 | writer.write_u64::(n)?; 33 | } 34 | Ok(()) 35 | } 36 | 37 | /// Reads a var int from bytes 38 | pub fn read(reader: &mut dyn Read) -> io::Result { 39 | let n0 = reader.read_u8()?; 40 | Ok(match n0 { 41 | 0xff => reader.read_u64::()?, 42 | 0xfe => reader.read_u32::()? as u64, 43 | 0xfd => reader.read_u16::()? as u64, 44 | _ => n0 as u64, 45 | }) 46 | } 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | use std::io::Cursor; 51 | 52 | #[test] 53 | fn size() { 54 | assert!(super::size(0) == 1); 55 | assert!(super::size(253) == 3); 56 | assert!(super::size(u16::max_value() as u64) == 3); 57 | assert!(super::size(u32::max_value() as u64) == 5); 58 | assert!(super::size(u64::max_value()) == 9); 59 | } 60 | 61 | #[test] 62 | fn write_read() { 63 | write_read_value(0); 64 | write_read_value(253); 65 | write_read_value(u16::max_value() as u64); 66 | write_read_value(u32::max_value() as u64); 67 | write_read_value(u64::max_value()); 68 | } 69 | 70 | fn write_read_value(n: u64) { 71 | let mut v = Vec::new(); 72 | super::write(n, &mut v).unwrap(); 73 | assert!(super::read(&mut Cursor::new(&v)).unwrap() == n); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/messages/tx_in.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::OutPoint; 2 | use crate::script::Script; 3 | use crate::util::{var_int, Result, Serializable}; 4 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 5 | use std::io; 6 | use std::io::{Read, Write}; 7 | 8 | /// Transaction input 9 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 10 | pub struct TxIn { 11 | /// The previous output transaction reference 12 | pub prev_output: OutPoint, 13 | /// Signature script for confirming authorization 14 | pub unlock_script: Script, 15 | /// Transaction version as defined by the sender for replacement or negotiation 16 | pub sequence: u32, 17 | } 18 | 19 | impl TxIn { 20 | /// Returns the size of the transaction input in bytes 21 | pub fn size(&self) -> usize { 22 | OutPoint::SIZE 23 | + var_int::size(self.unlock_script.0.len() as u64) 24 | + self.unlock_script.0.len() 25 | + 4 26 | } 27 | } 28 | 29 | impl Serializable for TxIn { 30 | fn read(reader: &mut dyn Read) -> Result { 31 | let prev_output = OutPoint::read(reader)?; 32 | let script_len = var_int::read(reader)?; 33 | let mut unlock_script = Script(vec![0; script_len as usize]); 34 | reader.read(&mut unlock_script.0)?; 35 | let sequence = reader.read_u32::()?; 36 | Ok(TxIn { 37 | prev_output, 38 | unlock_script, 39 | sequence, 40 | }) 41 | } 42 | 43 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 44 | self.prev_output.write(writer)?; 45 | var_int::write(self.unlock_script.0.len() as u64, writer)?; 46 | writer.write(&self.unlock_script.0)?; 47 | writer.write_u32::(self.sequence)?; 48 | Ok(()) 49 | } 50 | } 51 | 52 | #[cfg(test)] 53 | mod tests { 54 | use super::*; 55 | use crate::util::Hash256; 56 | use std::io::Cursor; 57 | 58 | #[test] 59 | fn write_read() { 60 | let mut v = Vec::new(); 61 | let t = TxIn { 62 | prev_output: OutPoint { 63 | hash: Hash256([6; 32]), 64 | index: 8, 65 | }, 66 | unlock_script: Script(vec![255; 254]), 67 | sequence: 100, 68 | }; 69 | t.write(&mut v).unwrap(); 70 | assert!(v.len() == t.size()); 71 | assert!(TxIn::read(&mut Cursor::new(&v)).unwrap() == t); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/messages/filter_add.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::util::{var_int, Error, Result, Serializable}; 3 | use hex; 4 | use std::fmt; 5 | use std::io; 6 | use std::io::{Read, Write}; 7 | 8 | /// Maximum size of a data element in the FilterAdd message 9 | pub const MAX_FILTER_ADD_DATA_SIZE: usize = 520; 10 | 11 | /// Adds a data element to the bloom filter 12 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 13 | pub struct FilterAdd { 14 | /// Data element to be added 15 | pub data: Vec, 16 | } 17 | 18 | impl FilterAdd { 19 | /// Returns whether the FilterAdd message is valid 20 | pub fn validate(&self) -> Result<()> { 21 | if self.data.len() > MAX_FILTER_ADD_DATA_SIZE { 22 | return Err(Error::BadData("Data too long".to_string())); 23 | } 24 | Ok(()) 25 | } 26 | } 27 | 28 | impl Serializable for FilterAdd { 29 | fn read(reader: &mut dyn Read) -> Result { 30 | let data_len = var_int::read(reader)?; 31 | let mut data = vec![0; data_len as usize]; 32 | reader.read(&mut data)?; 33 | Ok(FilterAdd { data }) 34 | } 35 | 36 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 37 | var_int::write(self.data.len() as u64, writer)?; 38 | writer.write(&self.data)?; 39 | Ok(()) 40 | } 41 | } 42 | 43 | impl Payload for FilterAdd { 44 | fn size(&self) -> usize { 45 | var_int::size(self.data.len() as u64) + self.data.len() 46 | } 47 | } 48 | 49 | impl fmt::Debug for FilterAdd { 50 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 51 | f.debug_struct("FilterAdd") 52 | .field("data", &hex::encode(&self.data)) 53 | .finish() 54 | } 55 | } 56 | 57 | #[cfg(test)] 58 | mod tests { 59 | use super::*; 60 | use std::io::Cursor; 61 | 62 | #[test] 63 | fn read_bytes() { 64 | let b = hex::decode( 65 | "20fdacf9b3eb077412e7a968d2e4f11b9a9dee312d666187ed77ee7d26af16cb0b".as_bytes(), 66 | ) 67 | .unwrap(); 68 | let f = FilterAdd::read(&mut Cursor::new(&b)).unwrap(); 69 | assert!(f.data.len() == 32); 70 | } 71 | 72 | #[test] 73 | fn write_read() { 74 | let mut v = Vec::new(); 75 | let p = FilterAdd { data: vec![20; 20] }; 76 | p.write(&mut v).unwrap(); 77 | assert!(v.len() == p.size()); 78 | assert!(FilterAdd::read(&mut Cursor::new(&v)).unwrap() == p); 79 | } 80 | 81 | #[test] 82 | fn validate() { 83 | let p = FilterAdd { data: vec![21; 21] }; 84 | assert!(p.validate().is_ok()); 85 | 86 | let p = FilterAdd { 87 | data: vec![21; MAX_FILTER_ADD_DATA_SIZE + 1], 88 | }; 89 | assert!(p.validate().is_err()); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/peer/mod.rs: -------------------------------------------------------------------------------- 1 | //! Node connection and message handling 2 | //! 3 | //! # Examples 4 | //! 5 | //! Send and receive a message to a node syncronously: 6 | //! 7 | //! ```no_run, rust 8 | //! use sv::messages::{Message, Ping, Version, NODE_BITCOIN_CASH, PROTOCOL_VERSION}; 9 | //! use sv::network::Network; 10 | //! use sv::peer::{Peer, SVPeerFilter}; 11 | //! use sv::util::rx::Observable; 12 | //! use sv::util::secs_since; 13 | //! use std::time::UNIX_EPOCH; 14 | //! 15 | //! let (ip, port) = Network::Mainnet.seed_iter().next().unwrap(); 16 | //! let version = Version { 17 | //! version: PROTOCOL_VERSION, 18 | //! services: NODE_BITCOIN_CASH, 19 | //! timestamp: secs_since(UNIX_EPOCH) as i64, 20 | //! user_agent: "rust-sv".to_string(), 21 | //! ..Default::default() 22 | //! }; 23 | //! 24 | //! let peer = Peer::connect(ip, port, Network::Mainnet, version, SVPeerFilter::new(0)); 25 | //! peer.connected_event().poll(); 26 | //! 27 | //! let ping = Message::Ping(Ping { nonce: 0 }); 28 | //! peer.send(&ping).unwrap(); 29 | //! 30 | //! let response = peer.messages().poll(); 31 | //! ``` 32 | //! 33 | //! Handle node events asynronously: 34 | //! 35 | //! ```no_run, rust 36 | //! use sv::messages::{Version, NODE_BITCOIN_CASH, PROTOCOL_VERSION}; 37 | //! use sv::network::Network; 38 | //! use sv::peer::{Peer, PeerConnected, PeerDisconnected, PeerMessage, SVPeerFilter}; 39 | //! use sv::util::rx::{Observable, Observer}; 40 | //! use sv::util::secs_since; 41 | //! use std::sync::Arc; 42 | //! use std::time::UNIX_EPOCH; 43 | //! 44 | //! let (ip, port) = Network::Mainnet.seed_iter().next().unwrap(); 45 | //! let version = Version { 46 | //! version: PROTOCOL_VERSION, 47 | //! services: NODE_BITCOIN_CASH, 48 | //! timestamp: secs_since(UNIX_EPOCH) as i64, 49 | //! user_agent: "rust-sv".to_string(), 50 | //! ..Default::default() 51 | //! }; 52 | //! 53 | //! let peer = Peer::connect(ip, port, Network::Mainnet, version, SVPeerFilter::new(0)); 54 | //! 55 | //! struct EventHandler {} 56 | //! 57 | //! impl Observer for EventHandler { 58 | //! fn next(&self, event: &PeerConnected) { 59 | //! // Handle node connected 60 | //! } 61 | //! } 62 | //! 63 | //! impl Observer for EventHandler { 64 | //! fn next(&self, event: &PeerDisconnected) { 65 | //! // Handle node disconnected 66 | //! } 67 | //! } 68 | //! 69 | //! impl Observer for EventHandler { 70 | //! fn next(&self, event: &PeerMessage) { 71 | //! // Handle message from node 72 | //! } 73 | //! } 74 | //! 75 | //! let event_handler = Arc::new(EventHandler {}); 76 | //! 77 | //! peer.connected_event().subscribe(&event_handler); 78 | //! peer.disconnected_event().subscribe(&event_handler); 79 | //! peer.messages().subscribe(&event_handler); 80 | //! ``` 81 | 82 | pub(crate) mod atomic_reader; 83 | mod peer; 84 | 85 | pub use self::peer::{ 86 | Peer, PeerConnected, PeerDisconnected, PeerFilter, PeerMessage, SVPeerFilter, 87 | }; 88 | -------------------------------------------------------------------------------- /src/messages/node_addr.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Result, Serializable}; 2 | use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; 3 | use std::io; 4 | use std::io::{Read, Write}; 5 | use std::net::{IpAddr, Ipv6Addr}; 6 | 7 | /// Network address for a node on the network 8 | #[derive(Debug, PartialEq, Eq, Hash, Clone)] 9 | pub struct NodeAddr { 10 | /// Services flags for the node 11 | pub services: u64, 12 | /// IPV6 address for the node. IPV4 addresses may be used as IPV4-mapped IPV6 addresses. 13 | pub ip: Ipv6Addr, 14 | /// Port for Bitcoin P2P communication 15 | pub port: u16, 16 | } 17 | 18 | impl NodeAddr { 19 | /// Size of the NodeAddr in bytes 20 | pub const SIZE: usize = 26; 21 | 22 | /// Creates a NodeAddr from an IP address and port 23 | pub fn new(ip: IpAddr, port: u16) -> NodeAddr { 24 | NodeAddr { 25 | services: 0, 26 | ip: match ip { 27 | IpAddr::V4(ipv4) => ipv4.to_ipv6_mapped(), 28 | IpAddr::V6(ipv6) => ipv6, 29 | }, 30 | port, 31 | } 32 | } 33 | 34 | /// Returns the size of the address in bytes 35 | pub fn size(&self) -> usize { 36 | NodeAddr::SIZE 37 | } 38 | } 39 | 40 | impl Serializable for NodeAddr { 41 | fn read(reader: &mut dyn Read) -> Result { 42 | let services = reader.read_u64::()?; 43 | let mut ip = [0; 16]; 44 | reader.read(&mut ip)?; 45 | let ip = Ipv6Addr::from(ip); 46 | let port = reader.read_u16::()?; 47 | Ok(NodeAddr { services, ip, port }) 48 | } 49 | 50 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 51 | writer.write_u64::(self.services)?; 52 | writer.write(&self.ip.octets())?; 53 | writer.write_u16::(self.port)?; 54 | Ok(()) 55 | } 56 | } 57 | 58 | impl Default for NodeAddr { 59 | fn default() -> NodeAddr { 60 | NodeAddr { 61 | services: 0, 62 | ip: Ipv6Addr::from([0; 16]), 63 | port: 0, 64 | } 65 | } 66 | } 67 | 68 | #[cfg(test)] 69 | mod tests { 70 | use super::*; 71 | use hex; 72 | use std::io::Cursor; 73 | 74 | #[test] 75 | fn read_bytes() { 76 | let b = 77 | hex::decode("250000000000000000000000000000000000ffff2d32bffbddd3".as_bytes()).unwrap(); 78 | let a = NodeAddr::read(&mut Cursor::new(&b)).unwrap(); 79 | assert!(a.services == 37); 80 | assert!(a.ip.octets() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 45, 50, 191, 251]); 81 | assert!(a.port == 56787); 82 | } 83 | 84 | #[test] 85 | fn write_read() { 86 | let mut v = Vec::new(); 87 | let a = NodeAddr { 88 | services: 1, 89 | ip: Ipv6Addr::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), 90 | port: 123, 91 | }; 92 | a.write(&mut v).unwrap(); 93 | assert!(v.len() == a.size()); 94 | assert!(NodeAddr::read(&mut Cursor::new(&v)).unwrap() == a); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/util/latch.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Error, Result}; 2 | use std::fmt; 3 | use std::sync::{Arc, Condvar, Mutex}; 4 | use std::time::Duration; 5 | 6 | /// A one-way latch for thread synchronization 7 | /// 8 | /// It is similar to Java's CountdownLatch when counter is 1. 9 | pub struct Latch { 10 | open: Mutex, 11 | condvar: Condvar, 12 | } 13 | 14 | impl Latch { 15 | /// Creates a new latch in an unopened state 16 | pub fn new() -> Arc { 17 | Arc::new(Latch { 18 | open: Mutex::new(false), 19 | condvar: Condvar::new(), 20 | }) 21 | } 22 | 23 | /// Opens the latch unblocking all wait and wait_timeout calls forever 24 | pub fn open(&self) { 25 | let mut open = self.open.lock().unwrap(); 26 | *open = true; 27 | self.condvar.notify_one(); 28 | } 29 | 30 | /// Waits until open is called 31 | pub fn wait(&self) { 32 | let mut open = self.open.lock().unwrap(); 33 | while !*open { 34 | open = self.condvar.wait(open).unwrap(); 35 | } 36 | } 37 | 38 | /// Waits until open is called, with a timeout. The result will return Error::Timeout if a timeout occurred. 39 | pub fn wait_timeout(&self, duration: Duration) -> Result<()> { 40 | let mut open = self.open.lock().unwrap(); 41 | while !*open { 42 | let result = self.condvar.wait_timeout(open, duration).unwrap(); 43 | if result.1.timed_out() { 44 | return Err(Error::Timeout); 45 | } 46 | open = result.0; 47 | } 48 | Ok(()) 49 | } 50 | 51 | /// Returns whether the latch has been opened or not 52 | pub fn opened(&self) -> bool { 53 | *self.open.lock().unwrap() 54 | } 55 | } 56 | 57 | impl fmt::Debug for Latch { 58 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 59 | let state = if self.opened() { "opened" } else { "closed" }; 60 | f.write_str(&format!("Latch({})", state)) 61 | } 62 | } 63 | 64 | #[cfg(test)] 65 | mod tests { 66 | use super::*; 67 | use std::thread; 68 | 69 | #[test] 70 | fn one_thread() { 71 | let latch = Latch::new(); 72 | assert!(!latch.opened()); 73 | latch.open(); 74 | assert!(latch.opened()); 75 | latch.wait(); 76 | } 77 | 78 | #[test] 79 | fn two_threads() { 80 | let latch = Latch::new(); 81 | let thread_latch = latch.clone(); 82 | thread::spawn(move || { 83 | assert!(!thread_latch.opened()); 84 | thread_latch.open(); 85 | }); 86 | latch.wait(); 87 | assert!(latch.opened()); 88 | } 89 | 90 | #[test] 91 | fn opens_and_waits() { 92 | let latch = Latch::new(); 93 | latch.open(); 94 | latch.wait(); 95 | latch.wait(); 96 | latch.open(); 97 | latch.wait(); 98 | assert!(latch.opened()); 99 | } 100 | 101 | #[test] 102 | fn timeout() { 103 | let latch = Latch::new(); 104 | assert!(latch.wait_timeout(Duration::from_millis(1)).is_err()); 105 | latch.open(); 106 | assert!(latch.wait_timeout(Duration::from_secs(1)).is_ok()); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/util/future.rs: -------------------------------------------------------------------------------- 1 | use crate::util::latch::Latch; 2 | use std::fmt; 3 | use std::mem::swap; 4 | use std::sync::{Arc, Mutex}; 5 | use std::time::Duration; 6 | 7 | /// A promise for a value in the future 8 | pub struct Future { 9 | latch: Arc, 10 | result: Arc>>, 11 | } 12 | 13 | /// A provider for a Future's value 14 | pub struct FutureProvider { 15 | latch: Arc, 16 | result: Arc>>, 17 | } 18 | 19 | impl Future { 20 | /// Creates a new future and its provider 21 | pub fn new() -> (Future, FutureProvider) { 22 | let future = Future { 23 | latch: Latch::new(), 24 | result: Arc::new(Mutex::new(None)), 25 | }; 26 | 27 | let provider = FutureProvider { 28 | latch: future.latch.clone(), 29 | result: future.result.clone(), 30 | }; 31 | 32 | (future, provider) 33 | } 34 | 35 | /// Creates a future that returns a specific value 36 | pub fn single(value: T) -> Future { 37 | let latch = Latch::new(); 38 | latch.open(); 39 | Future { 40 | latch, 41 | result: Arc::new(Mutex::new(Some(value))), 42 | } 43 | } 44 | 45 | /// Waits for a value and consumes the future 46 | pub fn get(self) -> T { 47 | self.latch.wait(); 48 | let mut lock = self.result.lock().unwrap(); 49 | let mut ret = None; 50 | swap(&mut ret, &mut *lock); 51 | ret.unwrap() 52 | } 53 | 54 | /// Waits up to a certain duration for a value and consumes the future 55 | pub fn get_timeout(self, duration: Duration) -> Result> { 56 | if let Err(_) = self.latch.wait_timeout(duration) { 57 | return Err(self); 58 | } 59 | let mut lock = self.result.lock().unwrap(); 60 | let mut ret = None; 61 | swap(&mut ret, &mut *lock); 62 | Ok(ret.unwrap()) 63 | } 64 | } 65 | 66 | impl FutureProvider { 67 | /// Sets a value and unblocks the Future 68 | pub fn put(&self, value: T) { 69 | let mut result = self.result.lock().unwrap(); 70 | *result = Some(value); 71 | self.latch.open(); 72 | } 73 | } 74 | 75 | impl fmt::Debug for Future { 76 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 77 | let state = if self.latch.opened() { "done" } else { "none" }; 78 | f.write_str(&format!("Future({})", state)) 79 | } 80 | } 81 | 82 | impl fmt::Debug for FutureProvider { 83 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 84 | let state = if self.latch.opened() { "done" } else { "none" }; 85 | f.write_str(&format!("FutureProvider({})", state)) 86 | } 87 | } 88 | 89 | #[cfg(test)] 90 | mod tests { 91 | use super::*; 92 | use std::thread; 93 | 94 | #[test] 95 | fn across_threads() { 96 | let (future, provider) = Future::::new(); 97 | thread::spawn(move || provider.put(3)); 98 | assert!(future.get() == 3); 99 | } 100 | 101 | #[test] 102 | fn timeout() { 103 | let (future, _provider) = Future::::new(); 104 | assert!(future.get_timeout(Duration::from_millis(10)).is_err()); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/messages/block_locator.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::messages::version::MIN_SUPPORTED_PROTOCOL_VERSION; 3 | use crate::util::{var_int, Error, Hash256, Result, Serializable}; 4 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 5 | use std::io; 6 | use std::io::{Read, Write}; 7 | 8 | /// Return results until either there are 2000 for getheaders or 500 or getblocks, or no more left 9 | pub const NO_HASH_STOP: Hash256 = Hash256([0; 32]); 10 | 11 | /// Specifies which blocks to return 12 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 13 | pub struct BlockLocator { 14 | /// Protocol version of this node 15 | pub version: u32, 16 | /// Block hash to start after. First found will be used. 17 | pub block_locator_hashes: Vec, 18 | /// Block hash to stop at, or none if NO_HASH_STOP. 19 | pub hash_stop: Hash256, 20 | } 21 | 22 | impl BlockLocator { 23 | /// Checks if the message is valid 24 | pub fn validate(&self) -> Result<()> { 25 | if self.version < MIN_SUPPORTED_PROTOCOL_VERSION as u32 { 26 | let msg = format!("Unsupported protocol version: {}", self.version); 27 | return Err(Error::BadData(msg)); 28 | } 29 | Ok(()) 30 | } 31 | } 32 | 33 | impl Serializable for BlockLocator { 34 | fn read(reader: &mut dyn Read) -> Result { 35 | let version = reader.read_u32::()?; 36 | let num_hashes = var_int::read(reader)?; 37 | let mut block_locator_hashes = Vec::new(); 38 | for _i in 0..num_hashes { 39 | block_locator_hashes.push(Hash256::read(reader)?); 40 | } 41 | let hash_stop = Hash256::read(reader)?; 42 | Ok(BlockLocator { 43 | version, 44 | block_locator_hashes, 45 | hash_stop, 46 | }) 47 | } 48 | 49 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 50 | writer.write_u32::(self.version)?; 51 | var_int::write(self.block_locator_hashes.len() as u64, writer)?; 52 | for hash in self.block_locator_hashes.iter() { 53 | hash.write(writer)?; 54 | } 55 | self.hash_stop.write(writer)?; 56 | Ok(()) 57 | } 58 | } 59 | 60 | impl Payload for BlockLocator { 61 | fn size(&self) -> usize { 62 | 4 + var_int::size(self.block_locator_hashes.len() as u64) 63 | + self.block_locator_hashes.len() * 32 64 | + 32 65 | } 66 | } 67 | 68 | #[cfg(test)] 69 | mod tests { 70 | use super::*; 71 | use std::io::Cursor; 72 | 73 | #[test] 74 | fn write_read() { 75 | let mut v = Vec::new(); 76 | let p = BlockLocator { 77 | version: 12345, 78 | block_locator_hashes: vec![ 79 | NO_HASH_STOP, 80 | Hash256::decode("6677889900667788990066778899006677889900667788990066778899006677") 81 | .unwrap(), 82 | ], 83 | hash_stop: Hash256::decode( 84 | "1122334455112233445511223344551122334455112233445511223344551122", 85 | ) 86 | .unwrap(), 87 | }; 88 | p.write(&mut v).unwrap(); 89 | assert!(v.len() == p.size()); 90 | assert!(BlockLocator::read(&mut Cursor::new(&v)).unwrap() == p); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/messages/filter_load.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::util::{var_int, BloomFilter, Result, Serializable}; 3 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Filter is not adjusted when a match is found 8 | pub const BLOOM_UPDATE_NONE: u8 = 0; 9 | /// Filter is updated to include the serialized outpoint if any data elements matched in its script pubkey 10 | pub const BLOOM_UPDATE_ALL: u8 = 1; 11 | /// Filter is updated simialr to BLOOM_UPDATE_ALL but only for P2PK or multisig transactions 12 | pub const BLOOM_UPDATE_P2PUBKEY_ONLY: u8 = 2; 13 | 14 | /// Loads a bloom filter using the specified parameters 15 | #[derive(Default, Debug, PartialEq, Eq, Hash, Clone)] 16 | pub struct FilterLoad { 17 | /// Bloom filter 18 | pub bloom_filter: BloomFilter, 19 | /// Flags that control how matched items are added to the filter 20 | pub flags: u8, 21 | } 22 | 23 | impl FilterLoad { 24 | /// Returns whether the FilterLoad message is valid 25 | pub fn validate(&self) -> Result<()> { 26 | self.bloom_filter.validate() 27 | } 28 | } 29 | 30 | impl Serializable for FilterLoad { 31 | fn read(reader: &mut dyn Read) -> Result { 32 | let num_filters = var_int::read(reader)?; 33 | let mut filter = vec![0; num_filters as usize]; 34 | reader.read(&mut filter)?; 35 | let num_hash_funcs = reader.read_u32::()? as usize; 36 | let tweak = reader.read_u32::()?; 37 | let flags = reader.read_u8()?; 38 | Ok(FilterLoad { 39 | bloom_filter: BloomFilter { 40 | filter, 41 | num_hash_funcs, 42 | tweak, 43 | }, 44 | flags, 45 | }) 46 | } 47 | 48 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 49 | var_int::write(self.bloom_filter.filter.len() as u64, writer)?; 50 | writer.write(&self.bloom_filter.filter)?; 51 | writer.write_u32::(self.bloom_filter.num_hash_funcs as u32)?; 52 | writer.write_u32::(self.bloom_filter.tweak)?; 53 | writer.write_u8(self.flags)?; 54 | Ok(()) 55 | } 56 | } 57 | 58 | impl Payload for FilterLoad { 59 | fn size(&self) -> usize { 60 | var_int::size(self.bloom_filter.filter.len() as u64) + self.bloom_filter.filter.len() + 9 61 | } 62 | } 63 | 64 | #[cfg(test)] 65 | mod tests { 66 | use super::*; 67 | use hex; 68 | use std::io::Cursor; 69 | 70 | #[test] 71 | fn read_bytes() { 72 | let b = hex::decode("02b50f0b0000000000000001".as_bytes()).unwrap(); 73 | let f = FilterLoad::read(&mut Cursor::new(&b)).unwrap(); 74 | assert!(f.bloom_filter.filter == vec![0xb5, 0x0f]); 75 | assert!(f.bloom_filter.num_hash_funcs == 11); 76 | assert!(f.bloom_filter.tweak == 0); 77 | assert!(f.flags == BLOOM_UPDATE_ALL); 78 | } 79 | 80 | #[test] 81 | fn write_read() { 82 | let mut v = Vec::new(); 83 | let p = FilterLoad { 84 | bloom_filter: BloomFilter { 85 | filter: vec![0, 1, 2, 3, 4, 5], 86 | num_hash_funcs: 3, 87 | tweak: 100, 88 | }, 89 | flags: 1, 90 | }; 91 | p.write(&mut v).unwrap(); 92 | assert!(v.len() == p.size()); 93 | assert!(FilterLoad::read(&mut Cursor::new(&v)).unwrap() == p); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/messages/inv.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::inv_vect::InvVect; 2 | use crate::messages::message::Payload; 3 | use crate::util::{var_int, Error, Result, Serializable}; 4 | use std::fmt; 5 | use std::io; 6 | use std::io::{Read, Write}; 7 | 8 | /// Maximum number of objects in an inv message 9 | pub const MAX_INV_ENTRIES: usize = 50000; 10 | 11 | /// Inventory payload describing objects a node knows about 12 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 13 | pub struct Inv { 14 | /// List of objects announced 15 | pub objects: Vec, 16 | } 17 | 18 | impl Serializable for Inv { 19 | fn read(reader: &mut dyn Read) -> Result { 20 | let num_objects = var_int::read(reader)? as usize; 21 | if num_objects > MAX_INV_ENTRIES { 22 | let msg = format!("Num objects exceeded maximum: {}", num_objects); 23 | return Err(Error::BadData(msg)); 24 | } 25 | let mut objects = Vec::with_capacity(num_objects); 26 | for _ in 0..num_objects { 27 | objects.push(InvVect::read(reader)?); 28 | } 29 | Ok(Inv { objects }) 30 | } 31 | 32 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 33 | var_int::write(self.objects.len() as u64, writer)?; 34 | for object in self.objects.iter() { 35 | object.write(writer)?; 36 | } 37 | Ok(()) 38 | } 39 | } 40 | 41 | impl Payload for Inv { 42 | fn size(&self) -> usize { 43 | var_int::size(self.objects.len() as u64) + InvVect::SIZE * self.objects.len() 44 | } 45 | } 46 | 47 | impl fmt::Debug for Inv { 48 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 49 | if self.objects.len() <= 3 { 50 | f.debug_struct("Inv") 51 | .field("objects", &self.objects) 52 | .finish() 53 | } else { 54 | let s = format!("[<{} inventory vectors>]", self.objects.len()); 55 | f.debug_struct("Inv").field("objects", &s).finish() 56 | } 57 | } 58 | } 59 | 60 | #[cfg(test)] 61 | mod tests { 62 | use super::*; 63 | use crate::messages::inv_vect::{INV_VECT_BLOCK, INV_VECT_TX}; 64 | use crate::util::Hash256; 65 | use std::io::Cursor; 66 | 67 | #[test] 68 | fn write_read() { 69 | let iv1 = InvVect { 70 | obj_type: INV_VECT_TX, 71 | hash: Hash256([8; 32]), 72 | }; 73 | let iv2 = InvVect { 74 | obj_type: INV_VECT_BLOCK, 75 | hash: Hash256([9; 32]), 76 | }; 77 | let mut inv = Inv { 78 | objects: Vec::new(), 79 | }; 80 | inv.objects.push(iv1); 81 | inv.objects.push(iv2); 82 | let mut v = Vec::new(); 83 | inv.write(&mut v).unwrap(); 84 | assert!(v.len() == inv.size()); 85 | assert!(Inv::read(&mut Cursor::new(&v)).unwrap() == inv); 86 | } 87 | 88 | #[test] 89 | fn too_many_objects() { 90 | let mut inv = Inv { 91 | objects: Vec::new(), 92 | }; 93 | for _i in 0..MAX_INV_ENTRIES + 1 { 94 | let inv_vect = InvVect { 95 | obj_type: INV_VECT_TX, 96 | hash: Hash256([8; 32]), 97 | }; 98 | inv.objects.push(inv_vect); 99 | } 100 | let mut v = Vec::new(); 101 | inv.write(&mut v).unwrap(); 102 | assert!(Inv::read(&mut Cursor::new(&v)).is_err()); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/messages/mod.rs: -------------------------------------------------------------------------------- 1 | //! Peer-to-peer network protocol messages 2 | //! 3 | //! # Examples 4 | //! 5 | //! Decode a network message 6 | //! 7 | //! ```rust 8 | //! use sv::messages::Message; 9 | //! use sv::network::Network; 10 | //! use std::io::Cursor; 11 | //! 12 | //! let bytes = [ 13 | //! 227, 225, 243, 232, 104, 101, 97, 100, 101, 114, 115, 14 | //! 0, 0, 0, 0, 0, 1, 0, 0, 0, 20, 6, 224, 88, 0, 15 | //! ]; 16 | //! let magic = Network::Mainnet.magic(); 17 | //! let message = Message::read(&mut Cursor::new(&bytes), magic).unwrap(); 18 | //! 19 | //! match message { 20 | //! Message::Headers(headers) => { /* Handle headers message */ }, 21 | //! _ => { /* All other messages */ } 22 | //! } 23 | //! ``` 24 | //! 25 | //! Construct a transaction: 26 | //! 27 | //! ```rust 28 | //! use sv::messages::{OutPoint, Tx, TxIn, TxOut}; 29 | //! use sv::transaction::p2pkh::{create_lock_script, create_unlock_script}; 30 | //! use sv::util::{hash160, Hash256}; 31 | //! 32 | //! // Use real values here 33 | //! let signature = [0; 72]; 34 | //! let public_key = [0; 33]; 35 | //! let prev_output = OutPoint { 36 | //! hash: Hash256([0; 32]), 37 | //! index: 0, 38 | //! }; 39 | //! 40 | //! let inputs = vec![TxIn { 41 | //! prev_output, 42 | //! unlock_script: create_unlock_script(&signature, &public_key), 43 | //! sequence: 0, 44 | //! }]; 45 | //! 46 | //! let outputs = vec![TxOut { 47 | //! satoshis: 1000, 48 | //! lock_script: create_lock_script(&hash160(&public_key)), 49 | //! }]; 50 | //! 51 | //! let tx = Tx { 52 | //! version: 2, 53 | //! inputs, 54 | //! outputs, 55 | //! lock_time: 0, 56 | //! }; 57 | //! ``` 58 | 59 | mod addr; 60 | mod block; 61 | mod block_header; 62 | mod block_locator; 63 | mod fee_filter; 64 | mod filter_add; 65 | mod filter_load; 66 | mod headers; 67 | mod inv; 68 | mod inv_vect; 69 | mod merkle_block; 70 | mod message; 71 | mod message_header; 72 | mod node_addr; 73 | mod node_addr_ex; 74 | mod out_point; 75 | mod ping; 76 | mod reject; 77 | mod send_cmpct; 78 | mod tx; 79 | mod tx_in; 80 | mod tx_out; 81 | mod version; 82 | 83 | pub use self::addr::Addr; 84 | pub use self::block::Block; 85 | pub use self::block_header::BlockHeader; 86 | pub use self::block_locator::{BlockLocator, NO_HASH_STOP}; 87 | pub use self::fee_filter::FeeFilter; 88 | pub use self::filter_add::{FilterAdd, MAX_FILTER_ADD_DATA_SIZE}; 89 | pub use self::filter_load::{ 90 | FilterLoad, BLOOM_UPDATE_ALL, BLOOM_UPDATE_NONE, BLOOM_UPDATE_P2PUBKEY_ONLY, 91 | }; 92 | pub use self::headers::{header_hash, Headers}; 93 | pub use self::inv::{Inv, MAX_INV_ENTRIES}; 94 | pub use self::inv_vect::{ 95 | InvVect, INV_VECT_BLOCK, INV_VECT_COMPACT_BLOCK, INV_VECT_ERROR, INV_VECT_FILTERED_BLOCK, 96 | INV_VECT_TX, 97 | }; 98 | pub use self::merkle_block::MerkleBlock; 99 | pub use self::message::{commands, Message, Payload, MAX_PAYLOAD_SIZE, NO_CHECKSUM}; 100 | pub use self::message_header::MessageHeader; 101 | pub use self::node_addr::NodeAddr; 102 | pub use self::node_addr_ex::NodeAddrEx; 103 | pub use self::out_point::{OutPoint, COINBASE_OUTPOINT_HASH, COINBASE_OUTPOINT_INDEX}; 104 | pub use self::ping::Ping; 105 | pub use self::reject::{ 106 | Reject, REJECT_CHECKPOINT, REJECT_DUPLICATE, REJECT_DUST, REJECT_INSUFFICIENT_FEE, 107 | REJECT_INVALID, REJECT_MALFORMED, REJECT_NONSTANDARD, REJECT_OBSOLETE, 108 | }; 109 | pub use self::send_cmpct::SendCmpct; 110 | pub use self::tx::{Tx, MAX_SATOSHIS}; 111 | pub use self::tx_in::TxIn; 112 | pub use self::tx_out::TxOut; 113 | pub use self::version::{ 114 | Version, MIN_SUPPORTED_PROTOCOL_VERSION, NODE_BITCOIN_CASH, NODE_NETWORK, NODE_NONE, 115 | PROTOCOL_VERSION, UNKNOWN_IP, 116 | }; 117 | -------------------------------------------------------------------------------- /src/messages/addr.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::messages::node_addr_ex::NodeAddrEx; 3 | use crate::util::{var_int, Error, Result, Serializable}; 4 | use std::fmt; 5 | use std::io; 6 | use std::io::{Read, Write}; 7 | 8 | /// Maximum number of addresses allowed in an Addr message 9 | const MAX_ADDR_COUNT: u64 = 1000; 10 | 11 | /// Known node addresses 12 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 13 | pub struct Addr { 14 | /// List of addresses of known nodes 15 | pub addrs: Vec, 16 | } 17 | 18 | impl Serializable for Addr { 19 | fn read(reader: &mut dyn Read) -> Result { 20 | let mut ret = Addr { addrs: Vec::new() }; 21 | let count = var_int::read(reader)?; 22 | if count > MAX_ADDR_COUNT { 23 | let msg = format!("Too many addrs: {}", count); 24 | return Err(Error::BadData(msg)); 25 | } 26 | for _i in 0..count { 27 | ret.addrs.push(NodeAddrEx::read(reader)?); 28 | } 29 | Ok(ret) 30 | } 31 | 32 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 33 | var_int::write(self.addrs.len() as u64, writer)?; 34 | for item in self.addrs.iter() { 35 | item.write(writer)?; 36 | } 37 | Ok(()) 38 | } 39 | } 40 | 41 | impl Payload for Addr { 42 | fn size(&self) -> usize { 43 | var_int::size(self.addrs.len() as u64) + self.addrs.len() * NodeAddrEx::SIZE 44 | } 45 | } 46 | 47 | impl fmt::Debug for Addr { 48 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 49 | if self.addrs.len() <= 3 { 50 | f.debug_struct("Addr").field("addrs", &self.addrs).finish() 51 | } else { 52 | let s = format!("[<{} addrs>]", self.addrs.len()); 53 | f.debug_struct("Addr").field("addrs", &s).finish() 54 | } 55 | } 56 | } 57 | 58 | #[cfg(test)] 59 | mod tests { 60 | use super::*; 61 | use crate::messages::NodeAddr; 62 | use hex; 63 | use std::io::Cursor; 64 | use std::net::Ipv6Addr; 65 | 66 | #[test] 67 | fn read_bytes() { 68 | let b = hex::decode( 69 | "013c93dd5a250000000000000000000000000000000000ffff43cdb3a1479d".as_bytes(), 70 | ) 71 | .unwrap(); 72 | let a = Addr::read(&mut Cursor::new(&b)).unwrap(); 73 | assert!(a.addrs.len() == 1); 74 | assert!(a.addrs[0].last_connected_time == 1524470588); 75 | assert!(a.addrs[0].addr.services == 37); 76 | let ip = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 67, 205, 179, 161]; 77 | assert!(a.addrs[0].addr.ip.octets() == ip); 78 | assert!(a.addrs[0].addr.port == 18333); 79 | } 80 | 81 | #[test] 82 | fn write_read() { 83 | let mut v = Vec::new(); 84 | let addr1 = NodeAddrEx { 85 | last_connected_time: 100, 86 | addr: NodeAddr { 87 | services: 900, 88 | ip: Ipv6Addr::from([1; 16]), 89 | port: 2000, 90 | }, 91 | }; 92 | let addr2 = NodeAddrEx { 93 | last_connected_time: 200, 94 | addr: NodeAddr { 95 | services: 800, 96 | ip: Ipv6Addr::from([2; 16]), 97 | port: 3000, 98 | }, 99 | }; 100 | let addr3 = NodeAddrEx { 101 | last_connected_time: 700, 102 | addr: NodeAddr { 103 | services: 900, 104 | ip: Ipv6Addr::from([3; 16]), 105 | port: 4000, 106 | }, 107 | }; 108 | let f = Addr { 109 | addrs: vec![addr1, addr2, addr3], 110 | }; 111 | f.write(&mut v).unwrap(); 112 | assert!(v.len() == f.size()); 113 | assert!(Addr::read(&mut Cursor::new(&v)).unwrap() == f); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/peer/atomic_reader.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::io::Read; 3 | 4 | /// Wraps a reader so reads become all-or-nothing 5 | pub struct AtomicReader<'a> { 6 | buf: Vec, 7 | reader: &'a mut dyn Read, 8 | } 9 | 10 | impl<'a> AtomicReader<'a> { 11 | pub fn new(reader: &mut dyn Read) -> AtomicReader { 12 | let buf = Vec::new(); 13 | AtomicReader { buf, reader } 14 | } 15 | } 16 | 17 | impl<'a> Read for AtomicReader<'a> { 18 | fn read(&mut self, out: &mut [u8]) -> io::Result { 19 | let buf_len = self.buf.len(); 20 | let out_len = out.len(); 21 | if buf_len >= out_len { 22 | // If we have enough in the buffer already, use it 23 | out.clone_from_slice(&self.buf[0..out_len]); 24 | self.buf = self.buf[out_len..].to_vec(); 25 | Ok(out_len) 26 | } else if buf_len > 0 { 27 | // Copy what we have and try to read the rest 28 | out[0..buf_len].clone_from_slice(&self.buf[0..]); 29 | let size = self.reader.read(&mut out[buf_len..])?; 30 | if size == 0 { 31 | Err(io::Error::new(io::ErrorKind::NotConnected, "Disconnected")) 32 | } else if buf_len + size < out_len { 33 | // Didn't read enough. Put what we read into the buffer. 34 | self.buf.extend_from_slice(&out[buf_len..buf_len + size]); 35 | Err(io::Error::new(io::ErrorKind::TimedOut, "Incomplete read")) 36 | } else { 37 | // Read enough. Clear the buffer and return. 38 | self.buf = Vec::new(); 39 | Ok(out_len) 40 | } 41 | } else { 42 | let size = self.reader.read(&mut out[0..])?; 43 | if size == 0 { 44 | Err(io::Error::new(io::ErrorKind::NotConnected, "Disconnected")) 45 | } else if size < out_len { 46 | // Didn't read enough. Put what we read into the buffer. 47 | self.buf.extend_from_slice(&out[0..size]); 48 | Err(io::Error::new(io::ErrorKind::TimedOut, "Incomplete read")) 49 | } else { 50 | // Read enough. Return. 51 | Ok(out_len) 52 | } 53 | } 54 | } 55 | } 56 | 57 | #[cfg(test)] 58 | mod test { 59 | use super::*; 60 | use std::io::Cursor; 61 | 62 | #[test] 63 | fn read() { 64 | let mut o = [0; 10]; 65 | 66 | // Success: Read expected 67 | let v = vec![0; 10]; 68 | let mut c = Cursor::new(&v); 69 | let mut r = AtomicReader::new(&mut c); 70 | assert!(r.read(&mut o).is_ok()); 71 | 72 | // Success: Read less than expected 73 | let v = vec![0; 12]; 74 | let mut c = Cursor::new(&v); 75 | let mut r = AtomicReader::new(&mut c); 76 | assert!(r.read(&mut o).is_ok()); 77 | 78 | // Success: Read buffered 79 | let v = vec![0; 0]; 80 | let mut c = Cursor::new(&v); 81 | let mut r = AtomicReader::new(&mut c); 82 | r.buf = vec![1; 10]; 83 | assert!(r.read(&mut o).is_ok()); 84 | assert!(r.buf.len() == 0); 85 | 86 | // Success: Read partially buffered 87 | let v = vec![0; 6]; 88 | let mut c = Cursor::new(&v); 89 | let mut r = AtomicReader::new(&mut c); 90 | r.buf = vec![1; 4]; 91 | assert!(r.read(&mut o).is_ok()); 92 | assert!(o == [1, 1, 1, 1, 0, 0, 0, 0, 0, 0]); 93 | 94 | // Error: Read empty 95 | let v = vec![0; 0]; 96 | let mut c = Cursor::new(&v); 97 | let mut r = AtomicReader::new(&mut c); 98 | assert!(r.read(&mut o).is_err()); 99 | 100 | // Error: Read incomplete 101 | let v = vec![0; 9]; 102 | let mut c = Cursor::new(&v); 103 | let mut r = AtomicReader::new(&mut c); 104 | assert!(r.read(&mut o).is_err()); 105 | assert!(r.buf.len() == 9); 106 | 107 | // Error: Read buffered and incomplete 108 | let v = vec![0; 0]; 109 | let mut c = Cursor::new(&v); 110 | let mut r = AtomicReader::new(&mut c); 111 | r.buf = vec![1; 9]; 112 | assert!(r.read(&mut o).is_err()); 113 | assert!(r.buf.len() == 9); 114 | 115 | // Error: Read partially buffered and incomplete 116 | let v = vec![0; 6]; 117 | let mut c = Cursor::new(&v); 118 | let mut r = AtomicReader::new(&mut c); 119 | r.buf = vec![1; 3]; 120 | assert!(r.read(&mut o).is_err()); 121 | assert!(r.buf.len() == 9); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/address/mod.rs: -------------------------------------------------------------------------------- 1 | //! Address encoding and decoding 2 | //! 3 | //! # Examples 4 | //! 5 | //! Extract the public key hash and address type from a base-58 address: 6 | //! 7 | //! ```rust 8 | //! use sv::address::addr_decode; 9 | //! use sv::network::Network; 10 | //! 11 | //! let addr = "15wpV72HRpAFPMmosR3jvGq7axU7t6ghX5"; 12 | //! let (pubkeyhash, addr_type) = addr_decode(&addr, Network::Mainnet).unwrap(); 13 | //! ``` 14 | //! 15 | //! Encode a public key hash into a base-58 address: 16 | //! 17 | //! ```rust 18 | //! use sv::address::{addr_encode, AddressType}; 19 | //! use sv::network::Network; 20 | //! use sv::util::hash160; 21 | //! 22 | //! let pubkeyhash = hash160(&[0; 33]); 23 | //! let addr = addr_encode(&pubkeyhash, AddressType::P2PKH, Network::Mainnet); 24 | //! ``` 25 | //! 26 | use crate::network::Network; 27 | use crate::util::{sha256d, Error, Hash160, Result}; 28 | use rust_base58::base58::{FromBase58, ToBase58}; 29 | 30 | /// Address type which is either P2PKH or P2SH 31 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 32 | pub enum AddressType { 33 | /// Pay-to-public-key-hash address 34 | P2PKH, 35 | /// Pay-to-script-hash address 36 | P2SH, 37 | } 38 | 39 | /// Converts a public key hash to its base-58 address 40 | pub fn addr_encode(hash160: &Hash160, addr_type: AddressType, network: Network) -> String { 41 | let mut v = Vec::with_capacity(1 + hash160.0.len() + 2); 42 | v.push(match addr_type { 43 | AddressType::P2PKH => network.addr_pubkeyhash_flag(), 44 | AddressType::P2SH => network.addr_script_flag(), 45 | }); 46 | v.extend_from_slice(&hash160.0); 47 | let checksum = sha256d(&v).0; 48 | v.push(checksum[0]); 49 | v.push(checksum[1]); 50 | v.push(checksum[2]); 51 | v.push(checksum[3]); 52 | let b: &[u8] = v.as_ref(); 53 | b.to_base58() 54 | } 55 | 56 | /// Decodes a base-58 address to a public key hash 57 | pub fn addr_decode(input: &str, network: Network) -> Result<(Hash160, AddressType)> { 58 | // Make sure addr is at least some minimum to verify checksum and addr type 59 | // We will check the private key size later. 60 | let v = input.from_base58()?; 61 | if v.len() < 6 { 62 | let msg = format!("Base58 address not long enough: {}", v.len()); 63 | return Err(Error::BadData(msg)); 64 | } 65 | 66 | // Verify checksum 67 | let v0 = &v[0..v.len() - 4]; 68 | let v1 = &v[v.len() - 4..v.len()]; 69 | let cs = sha256d(v0).0; 70 | if v1[0] != cs[0] || v1[1] != cs[1] || v1[2] != cs[2] || v1[3] != cs[3] { 71 | let msg = format!("Bad checksum: {:?} != {:?}", &cs[..4], v1); 72 | return Err(Error::BadData(msg)); 73 | } 74 | 75 | // Extract address type 76 | let addr_type_byte = v0[0]; 77 | let addr_type = if addr_type_byte == network.addr_pubkeyhash_flag() { 78 | AddressType::P2PKH 79 | } else if addr_type_byte == network.addr_script_flag() { 80 | AddressType::P2SH 81 | } else { 82 | let msg = format!("Unknown address type {}", addr_type_byte); 83 | return Err(Error::BadData(msg)); 84 | }; 85 | 86 | // Extract hash160 address and return 87 | if v0.len() != 21 { 88 | let msg = format!("Hash160 address not long enough: {}", v0.len() - 1); 89 | return Err(Error::BadData(msg)); 90 | } 91 | let mut hash160addr = [0; 20]; 92 | hash160addr.clone_from_slice(&v0[1..]); 93 | Ok((Hash160(hash160addr), addr_type)) 94 | } 95 | 96 | #[cfg(test)] 97 | mod tests { 98 | use super::*; 99 | use crate::util::hash160; 100 | use hex; 101 | 102 | #[test] 103 | fn to_addr() { 104 | let pubkey_hex = "04005937fd439b3c19014d5f328df8c7ed514eaaf41c1980b8aeab461dffb23fbf3317e42395db24a52ce9fc947d9c22f54dc3217c8b11dfc7a09c59e0dca591d3"; 105 | let pubkeyhash = hash160(&hex::decode(pubkey_hex).unwrap()); 106 | let addr = addr_encode(&pubkeyhash, AddressType::P2PKH, Network::Mainnet); 107 | assert!(addr == "1NM2HFXin4cEQRBLjkNZAS98qLX9JKzjKn"); 108 | } 109 | 110 | #[test] 111 | fn from_addr() { 112 | let addr = "1NM2HFXin4cEQRBLjkNZAS98qLX9JKzjKn"; 113 | let result = addr_decode(&addr, Network::Mainnet).unwrap(); 114 | let hash160 = result.0; 115 | let addr_type = result.1; 116 | assert!(addr_type == AddressType::P2PKH); 117 | assert!(hex::encode(hash160.0) == "ea2407829a5055466b27784cde8cf463167946bf"); 118 | } 119 | 120 | #[test] 121 | fn from_addr_errors() { 122 | assert!(addr_decode("0", Network::Mainnet).is_err()); 123 | assert!(addr_decode("1000000000000000000000000000000000", Network::Mainnet).is_err()); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/util/result.rs: -------------------------------------------------------------------------------- 1 | use hex::FromHexError; 2 | use ring; 3 | use rust_base58::base58::FromBase58Error; 4 | use secp256k1; 5 | use std; 6 | use std::io; 7 | use std::string::FromUtf8Error; 8 | 9 | /// Standard error type used in the library 10 | #[derive(Debug)] 11 | pub enum Error { 12 | /// An argument provided is invalid 13 | BadArgument(String), 14 | /// The data given is not valid 15 | BadData(String), 16 | /// Base58 string could not be decoded 17 | FromBase58Error(FromBase58Error), 18 | /// Hex string could not be decoded 19 | FromHexError(FromHexError), 20 | /// UTF8 parsing error 21 | FromUtf8Error(FromUtf8Error), 22 | /// The state is not valid 23 | IllegalState(String), 24 | /// The operation is not valid on this object 25 | InvalidOperation(String), 26 | /// Standard library IO error 27 | IOError(io::Error), 28 | /// Error parsing an integer 29 | ParseIntError(std::num::ParseIntError), 30 | /// Error evaluating the script 31 | ScriptError(String), 32 | /// Error in the Secp256k1 library 33 | Secp256k1Error(secp256k1::Error), 34 | /// The operation timed out 35 | Timeout, 36 | /// An unknown error in the Ring library 37 | UnspecifiedRingError, 38 | /// The data or functionality is not supported by this library 39 | Unsupported(String), 40 | } 41 | 42 | impl std::fmt::Display for Error { 43 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 44 | match self { 45 | Error::BadArgument(s) => f.write_str(&format!("Bad argument: {}", s)), 46 | Error::BadData(s) => f.write_str(&format!("Bad data: {}", s)), 47 | Error::FromBase58Error(e) => f.write_str(&format!("Base58 decoding error: {}", e)), 48 | Error::FromHexError(e) => f.write_str(&format!("Hex decoding error: {}", e)), 49 | Error::FromUtf8Error(e) => f.write_str(&format!("Utf8 parsing error: {}", e)), 50 | Error::IllegalState(s) => f.write_str(&format!("Illegal state: {}", s)), 51 | Error::InvalidOperation(s) => f.write_str(&format!("Invalid operation: {}", s)), 52 | Error::IOError(e) => f.write_str(&format!("IO error: {}", e)), 53 | Error::ParseIntError(e) => f.write_str(&format!("ParseIntError: {}", e)), 54 | Error::ScriptError(s) => f.write_str(&format!("Script error: {}", s)), 55 | Error::Secp256k1Error(e) => f.write_str(&format!("Secp256k1 error: {}", e)), 56 | Error::Timeout => f.write_str("Timeout"), 57 | Error::UnspecifiedRingError => f.write_str("Unspecified ring error"), 58 | Error::Unsupported(s) => f.write_str(&format!("Unsuppored: {}", s)), 59 | } 60 | } 61 | } 62 | 63 | impl std::error::Error for Error { 64 | fn description(&self) -> &str { 65 | match self { 66 | Error::BadArgument(_) => "Bad argument", 67 | Error::BadData(_) => "Bad data", 68 | Error::FromBase58Error(_) => "Base58 decoding error", 69 | Error::FromHexError(_) => "Hex decoding error", 70 | Error::FromUtf8Error(_) => "Utf8 parsing error", 71 | Error::IllegalState(_) => "Illegal state", 72 | Error::InvalidOperation(_) => "Invalid operation", 73 | Error::IOError(_) => "IO error", 74 | Error::ParseIntError(_) => "Parse int error", 75 | Error::ScriptError(_) => "Script error", 76 | Error::Secp256k1Error(_) => "Secp256k1 error", 77 | Error::Timeout => "Timeout", 78 | Error::UnspecifiedRingError => "Unspecified ring error", 79 | Error::Unsupported(_) => "Unsupported", 80 | } 81 | } 82 | 83 | fn cause(&self) -> Option<&dyn std::error::Error> { 84 | match self { 85 | Error::FromHexError(e) => Some(e), 86 | Error::FromUtf8Error(e) => Some(e), 87 | Error::IOError(e) => Some(e), 88 | Error::ParseIntError(e) => Some(e), 89 | Error::Secp256k1Error(e) => Some(e), 90 | _ => None, 91 | } 92 | } 93 | } 94 | 95 | impl From for Error { 96 | fn from(e: FromBase58Error) -> Self { 97 | Error::FromBase58Error(e) 98 | } 99 | } 100 | 101 | impl From for Error { 102 | fn from(e: FromHexError) -> Self { 103 | Error::FromHexError(e) 104 | } 105 | } 106 | 107 | impl From for Error { 108 | fn from(e: FromUtf8Error) -> Self { 109 | Error::FromUtf8Error(e) 110 | } 111 | } 112 | 113 | impl From for Error { 114 | fn from(e: io::Error) -> Self { 115 | Error::IOError(e) 116 | } 117 | } 118 | 119 | impl From for Error { 120 | fn from(e: std::num::ParseIntError) -> Self { 121 | Error::ParseIntError(e) 122 | } 123 | } 124 | 125 | impl From for Error { 126 | fn from(e: secp256k1::Error) -> Self { 127 | Error::Secp256k1Error(e) 128 | } 129 | } 130 | 131 | impl From for Error { 132 | fn from(_: ring::error::Unspecified) -> Self { 133 | Error::UnspecifiedRingError 134 | } 135 | } 136 | 137 | /// Standard Result used in the library 138 | pub type Result = std::result::Result; 139 | -------------------------------------------------------------------------------- /src/transaction/p2pkh.rs: -------------------------------------------------------------------------------- 1 | //! Pay-to-public-key-hash transaction scripts 2 | 3 | use crate::script::op_codes::{OP_CHECKSIG, OP_DUP, OP_EQUALVERIFY, OP_HASH160, OP_PUSH}; 4 | use crate::script::{next_op, Script}; 5 | use crate::util::{Error, Hash160, Result}; 6 | 7 | /// Creates the pubkey script to send to an address 8 | pub fn create_lock_script(address: &Hash160) -> Script { 9 | let mut script = Script::new(); 10 | script.append(OP_DUP); 11 | script.append(OP_HASH160); 12 | script.append_data(&address.0); 13 | script.append(OP_EQUALVERIFY); 14 | script.append(OP_CHECKSIG); 15 | script 16 | } 17 | 18 | /// Creates a sigscript to sign a p2pkh transaction 19 | pub fn create_unlock_script(sig: &[u8], public_key: &[u8; 33]) -> Script { 20 | let mut unlock_script = Script::new(); 21 | unlock_script.append_data(sig); 22 | unlock_script.append_data(public_key); 23 | unlock_script 24 | } 25 | 26 | /// Returns whether the lock_script is p2pkh 27 | pub fn check_lock_script(lock_script: &[u8]) -> bool { 28 | lock_script.len() == 25 29 | && lock_script[0] == OP_DUP 30 | && lock_script[1] == OP_HASH160 31 | && lock_script[2] == OP_PUSH + 20 32 | && lock_script[23] == OP_EQUALVERIFY 33 | && lock_script[24] == OP_CHECKSIG 34 | } 35 | 36 | /// Returns whether the unlock_script is p2pkh 37 | pub fn check_unlock_script(unlock_script: &[u8]) -> bool { 38 | if unlock_script.len() == 0 39 | || unlock_script[0] < OP_PUSH + 71 40 | || unlock_script[0] > OP_PUSH + 73 41 | { 42 | return false; 43 | } 44 | let i = next_op(0, &unlock_script); 45 | if i >= unlock_script.len() 46 | || unlock_script[i] != OP_PUSH + 33 && unlock_script[i] != OP_PUSH + 65 47 | { 48 | return false; 49 | } 50 | next_op(i, &unlock_script) >= unlock_script.len() 51 | } 52 | 53 | /// Returns whether the lock_script is a P2PKH send to the provided address 54 | pub fn check_lock_script_addr(hash160: &Hash160, lock_script: &[u8]) -> bool { 55 | check_lock_script(lock_script) && lock_script[3..23] == hash160.0 56 | } 57 | 58 | /// Returns whether the unlock_script contains our public key 59 | pub fn check_unlock_script_addr(pubkey: &[u8], unlock_script: &[u8]) -> bool { 60 | if !check_unlock_script(unlock_script) { 61 | return false; 62 | } 63 | let i = next_op(0, &unlock_script); 64 | unlock_script[i + 1..] == *pubkey 65 | } 66 | 67 | /// Returns the public key this unlock_script was sent from 68 | pub fn extract_pubkey(unlock_script: &[u8]) -> Result> { 69 | if !check_unlock_script(unlock_script) { 70 | let msg = "Script is not a sigscript for P2PKH".to_string(); 71 | return Err(Error::BadData(msg)); 72 | } 73 | let i = next_op(0, &unlock_script); 74 | Ok(unlock_script[i + 1..].to_vec()) 75 | } 76 | 77 | /// Returns the address this lock_script sends to 78 | pub fn extract_pubkeyhash(lock_script: &[u8]) -> Result { 79 | if check_lock_script(lock_script) { 80 | let mut hash160 = Hash160([0; 20]); 81 | hash160.0.clone_from_slice(&lock_script[3..23]); 82 | return Ok(hash160); 83 | } else { 84 | return Err(Error::BadData("Script is not a standard P2PKH".to_string())); 85 | } 86 | } 87 | 88 | #[cfg(test)] 89 | mod tests { 90 | use super::*; 91 | use crate::script::op_codes::OP_1; 92 | 93 | #[test] 94 | fn check_lock_script_test() { 95 | let mut s = Script::new(); 96 | assert!(!check_lock_script(&s.0)); 97 | s.append(OP_DUP); 98 | s.append(OP_HASH160); 99 | s.append_data(&Hash160([1; 20]).0); 100 | s.append(OP_EQUALVERIFY); 101 | s.append(OP_CHECKSIG); 102 | assert!(check_lock_script(&s.0)); 103 | s.append(OP_1); 104 | assert!(!check_lock_script(&s.0)); 105 | } 106 | 107 | #[test] 108 | fn check_unlock_script_test() { 109 | assert!(!check_unlock_script(&Script::new().0)); 110 | 111 | let mut sig71pkh33 = Script::new(); 112 | sig71pkh33.append_data(&[0; 71]); 113 | assert!(!check_unlock_script(&sig71pkh33.0)); 114 | sig71pkh33.append_data(&[0; 33]); 115 | assert!(check_unlock_script(&sig71pkh33.0)); 116 | sig71pkh33.append(OP_1); 117 | assert!(!check_unlock_script(&sig71pkh33.0)); 118 | 119 | let mut sig73pkh65 = Script::new(); 120 | sig73pkh65.append_data(&[0; 73]); 121 | sig73pkh65.append_data(&[0; 65]); 122 | assert!(check_unlock_script(&sig73pkh65.0)); 123 | 124 | let mut sig72pkh30 = Script::new(); 125 | sig72pkh30.append_data(&[0; 72]); 126 | sig72pkh30.append_data(&[0; 30]); 127 | assert!(!check_unlock_script(&sig72pkh30.0)); 128 | } 129 | 130 | #[test] 131 | fn check_lock_script_addr_test() { 132 | let s = create_lock_script(&Hash160([5; 20])); 133 | assert!(check_lock_script_addr(&Hash160([5; 20]), &s.0)); 134 | } 135 | 136 | #[test] 137 | fn check_unlock_script_addr_test() { 138 | let mut s = Script::new(); 139 | s.append_data(&[5; 71]); 140 | s.append_data(&[6; 65]); 141 | assert!(check_unlock_script_addr(&[6; 65], &s.0)); 142 | assert!(!check_unlock_script_addr(&[7; 65], &s.0)); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/messages/headers.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::block_header::BlockHeader; 2 | use crate::messages::message::Payload; 3 | use crate::util::{var_int, Error, Hash256, Result, Serializable}; 4 | use byteorder::{ReadBytesExt, WriteBytesExt}; 5 | use std::fmt; 6 | use std::io; 7 | use std::io::{Read, Write}; 8 | 9 | /// Collection of block headers 10 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 11 | pub struct Headers { 12 | /// List of sequential block headers 13 | pub headers: Vec, 14 | } 15 | 16 | impl Serializable for Headers { 17 | fn read(reader: &mut dyn Read) -> Result { 18 | let n = var_int::read(reader)?; 19 | let mut headers = Vec::new(); 20 | for _i in 0..n { 21 | headers.push(BlockHeader::read(reader)?); 22 | let _txn_count = reader.read_u8(); 23 | } 24 | Ok(Headers { headers }) 25 | } 26 | 27 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 28 | var_int::write(self.headers.len() as u64, writer)?; 29 | for header in self.headers.iter() { 30 | header.write(writer)?; 31 | writer.write_u8(0)?; 32 | } 33 | Ok(()) 34 | } 35 | } 36 | 37 | impl Payload for Headers { 38 | fn size(&self) -> usize { 39 | var_int::size(self.headers.len() as u64) + (BlockHeader::SIZE + 1) * self.headers.len() 40 | } 41 | } 42 | 43 | impl fmt::Debug for Headers { 44 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 45 | let h = format!("[<{} block headers>]", self.headers.len()); 46 | f.debug_struct("Headers").field("headers", &h).finish() 47 | } 48 | } 49 | 50 | /// Returns the hash for a header at a particular index utilizing prev_hash if possible 51 | pub fn header_hash(i: usize, headers: &Vec) -> Result { 52 | if i + 1 < headers.len() { 53 | return Ok(headers[i + 1].prev_hash); 54 | } else if i + 1 == headers.len() { 55 | return Ok(headers[i].hash()); 56 | } else { 57 | return Err(Error::BadArgument("Index out of range".to_string())); 58 | } 59 | } 60 | 61 | #[cfg(test)] 62 | mod tests { 63 | use super::*; 64 | use crate::util::Hash256; 65 | use std::io::Cursor; 66 | 67 | #[test] 68 | fn write_read() { 69 | let mut v = Vec::new(); 70 | let p = Headers { 71 | headers: vec![ 72 | BlockHeader { 73 | version: 12345, 74 | prev_hash: Hash256::decode( 75 | "7766009988776600998877660099887766009988776600998877660099887766", 76 | ) 77 | .unwrap(), 78 | merkle_root: Hash256::decode( 79 | "2211554433221155443322115544332211554433221155443322115544332211", 80 | ) 81 | .unwrap(), 82 | timestamp: 66, 83 | bits: 4488, 84 | nonce: 9999, 85 | }, 86 | BlockHeader { 87 | version: 67890, 88 | prev_hash: Hash256::decode( 89 | "1122334455112233445511223344551122334455112233445511223344551122", 90 | ) 91 | .unwrap(), 92 | merkle_root: Hash256::decode( 93 | "6677889900667788990066778899006677889900667788990066778899006677", 94 | ) 95 | .unwrap(), 96 | timestamp: 77, 97 | bits: 5599, 98 | nonce: 1111, 99 | }, 100 | ], 101 | }; 102 | p.write(&mut v).unwrap(); 103 | assert!(v.len() == p.size()); 104 | assert!(Headers::read(&mut Cursor::new(&v)).unwrap() == p); 105 | } 106 | 107 | #[test] 108 | fn header_hash_test() { 109 | let header1 = BlockHeader { 110 | version: 12345, 111 | prev_hash: Hash256::decode( 112 | "7766009988776600998877660099887766009988776600998877660099887766", 113 | ) 114 | .unwrap(), 115 | merkle_root: Hash256::decode( 116 | "2211554433221155443322115544332211554433221155443322115544332211", 117 | ) 118 | .unwrap(), 119 | timestamp: 66, 120 | bits: 4488, 121 | nonce: 9999, 122 | }; 123 | 124 | let header2 = BlockHeader { 125 | version: 67890, 126 | prev_hash: header1.hash(), 127 | merkle_root: Hash256::decode( 128 | "6677889900667788990066778899006677889900667788990066778899006677", 129 | ) 130 | .unwrap(), 131 | timestamp: 77, 132 | bits: 5599, 133 | nonce: 1111, 134 | }; 135 | 136 | assert!(header_hash(0, &vec![]).is_err()); 137 | 138 | let headers = vec![header1.clone()]; 139 | assert!(header_hash(0, &headers).unwrap() == header1.hash()); 140 | assert!(header_hash(1, &headers).is_err()); 141 | 142 | let headers = vec![header1.clone(), header2.clone()]; 143 | assert!(header_hash(0, &headers).unwrap() == header1.hash()); 144 | assert!(header_hash(1, &headers).unwrap() == header2.hash()); 145 | assert!(header_hash(2, &headers).is_err()); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/messages/reject.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::util::{var_int, Error, Hash256, Result, Serializable}; 3 | use byteorder::{ReadBytesExt, WriteBytesExt}; 4 | use std::fmt; 5 | use std::io; 6 | use std::io::{Cursor, Read, Write}; 7 | 8 | // Message rejection error codes 9 | pub const REJECT_MALFORMED: u8 = 0x01; 10 | pub const REJECT_INVALID: u8 = 0x10; 11 | pub const REJECT_OBSOLETE: u8 = 0x11; 12 | pub const REJECT_DUPLICATE: u8 = 0x12; 13 | pub const REJECT_NONSTANDARD: u8 = 0x40; 14 | pub const REJECT_DUST: u8 = 0x41; 15 | pub const REJECT_INSUFFICIENT_FEE: u8 = 0x42; 16 | pub const REJECT_CHECKPOINT: u8 = 0x43; 17 | 18 | /// Rejected message 19 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 20 | pub struct Reject { 21 | /// Type of message rejected 22 | pub message: String, 23 | /// Error code 24 | pub code: u8, 25 | /// Reason for rejection 26 | pub reason: String, 27 | /// Optional extra data that may be present for some rejections 28 | /// 29 | /// Currently this is only a 32-byte hash of the block or transaction if applicable. 30 | pub data: Vec, 31 | } 32 | 33 | impl Reject { 34 | /// Returns the transaction ID for this message 35 | pub fn txid(&self) -> Result { 36 | if self.data.len() != 32 { 37 | return Err(Error::InvalidOperation("No transaction hash".to_string())); 38 | } 39 | let mut txid = Hash256([0; 32]); 40 | txid.0.clone_from_slice(&self.data); 41 | Ok(txid) 42 | } 43 | } 44 | 45 | impl Serializable for Reject { 46 | fn read(reader: &mut dyn Read) -> Result { 47 | let message_size = var_int::read(reader)? as usize; 48 | let mut message_bytes = vec![0; message_size]; 49 | reader.read(&mut message_bytes)?; 50 | let message = String::from_utf8(message_bytes)?; 51 | let code = reader.read_u8()?; 52 | let reason_size = var_int::read(reader)? as usize; 53 | let mut reason_bytes = vec![0; reason_size]; 54 | reader.read(&mut reason_bytes)?; 55 | let reason = String::from_utf8(reason_bytes)?; 56 | let mut data = vec![]; 57 | if message == "block".to_string() || message == "tx".to_string() { 58 | data = vec![0_u8; 32]; 59 | reader.read(&mut data)?; 60 | } 61 | Ok(Reject { 62 | message, 63 | code, 64 | reason, 65 | data, 66 | }) 67 | } 68 | 69 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 70 | var_int::write(self.message.as_bytes().len() as u64, writer)?; 71 | writer.write(&self.message.as_bytes())?; 72 | writer.write_u8(self.code)?; 73 | var_int::write(self.reason.as_bytes().len() as u64, writer)?; 74 | writer.write(&self.reason.as_bytes())?; 75 | writer.write(&self.data)?; 76 | Ok(()) 77 | } 78 | } 79 | 80 | impl Payload for Reject { 81 | fn size(&self) -> usize { 82 | var_int::size(self.message.as_bytes().len() as u64) 83 | + self.message.as_bytes().len() 84 | + 1 85 | + var_int::size(self.reason.as_bytes().len() as u64) 86 | + self.reason.as_bytes().len() 87 | + self.data.len() 88 | } 89 | } 90 | 91 | impl fmt::Debug for Reject { 92 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 93 | let mut data_str = "".to_string(); 94 | if self.message == "block".to_string() || self.message == "tx".to_string() { 95 | let mut data = Cursor::new(&self.data); 96 | data_str = Hash256::read(&mut data).unwrap().encode(); 97 | } 98 | f.debug_struct("Reject") 99 | .field("message", &self.message) 100 | .field("code", &self.code) 101 | .field("reason", &self.reason) 102 | .field("data", &data_str) 103 | .finish() 104 | } 105 | } 106 | 107 | #[cfg(test)] 108 | mod tests { 109 | use super::*; 110 | use hex; 111 | use std::io::Cursor; 112 | 113 | #[test] 114 | fn txid() { 115 | let mut reject = Reject { 116 | data: vec![5; 32], 117 | ..Default::default() 118 | }; 119 | assert!(reject.txid().is_ok()); 120 | reject.data = vec![3; 33]; 121 | assert!(reject.txid().is_err()); 122 | } 123 | 124 | #[test] 125 | fn read_bytes() { 126 | let b = hex::decode("027478104f6d616e6461746f72792d7363726970742d7665726966792d666c61672d6661696c65642028536372697074206661696c656420616e204f505f455155414c564552494659206f7065726174696f6e292f174bfe9e5b6e32ef2fabd164df5469f44977d93e0625238465ded771083993".as_bytes()).unwrap(); 127 | let m = Reject::read(&mut Cursor::new(&b)).unwrap(); 128 | assert!(m.message == "tx".to_string()); 129 | assert!(m.code == REJECT_INVALID); 130 | assert!(m.reason == "mandatory-script-verify-flag-failed (Script failed an OP_EQUALVERIFY operation)".to_string()); 131 | let data = "2f174bfe9e5b6e32ef2fabd164df5469f44977d93e0625238465ded771083993"; 132 | assert!(m.data == hex::decode(data).unwrap()); 133 | } 134 | 135 | #[test] 136 | fn write_read() { 137 | let mut v = Vec::new(); 138 | let p = Reject { 139 | message: "block".to_string(), 140 | code: REJECT_INVALID, 141 | reason: "Block too small".to_string(), 142 | data: vec![5; 32], 143 | }; 144 | p.write(&mut v).unwrap(); 145 | assert!(v.len() == p.size()); 146 | assert!(Reject::read(&mut Cursor::new(&v)).unwrap() == p); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/util/hash256.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Error, Result, Serializable}; 2 | use hex; 3 | use ring::digest::{digest, SHA256}; 4 | use std::cmp::Ordering; 5 | use std::fmt; 6 | use std::io; 7 | use std::io::{Read, Write}; 8 | 9 | /// 256-bit hash for blocks and transactions 10 | /// 11 | /// It is interpreted as a single little-endian number for display. 12 | #[derive(Default, Clone, Copy, PartialEq, Eq, Hash)] 13 | pub struct Hash256(pub [u8; 32]); 14 | 15 | impl Hash256 { 16 | /// Converts the hash into a hex string 17 | pub fn encode(&self) -> String { 18 | let mut r = self.0.clone(); 19 | r.reverse(); 20 | hex::encode(r) 21 | } 22 | 23 | /// Converts a string of 64 hex characters into a hash 24 | pub fn decode(s: &str) -> Result { 25 | let decoded_bytes = hex::decode(s)?; 26 | let mut hash_bytes = [0; 32]; 27 | if decoded_bytes.len() != 32 { 28 | let msg = format!("Length {} of {:?}", decoded_bytes.len(), decoded_bytes); 29 | return Err(Error::BadArgument(msg)); 30 | } 31 | hash_bytes.clone_from_slice(&decoded_bytes); 32 | hash_bytes.reverse(); 33 | Ok(Hash256(hash_bytes)) 34 | } 35 | } 36 | 37 | impl Serializable for Hash256 { 38 | fn read(reader: &mut dyn Read) -> Result { 39 | let mut bytes = [0; 32]; 40 | reader.read(&mut bytes)?; 41 | Ok(Hash256(bytes)) 42 | } 43 | 44 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 45 | match writer.write(&self.0) { 46 | Ok(_size) => Ok(()), 47 | Err(e) => Err(e), 48 | } 49 | } 50 | } 51 | 52 | /// Hashes a data array twice using SHA256 53 | pub fn sha256d(data: &[u8]) -> Hash256 { 54 | let sha256 = digest(&SHA256, &data); 55 | let sha256d = digest(&SHA256, sha256.as_ref()); 56 | let mut hash256 = [0; 32]; 57 | hash256.clone_from_slice(sha256d.as_ref()); 58 | Hash256(hash256) 59 | } 60 | 61 | impl Ord for Hash256 { 62 | fn cmp(&self, other: &Hash256) -> Ordering { 63 | for i in (0..32).rev() { 64 | if self.0[i] < other.0[i] { 65 | return Ordering::Less; 66 | } else if self.0[i] > other.0[i] { 67 | return Ordering::Greater; 68 | } 69 | } 70 | Ordering::Equal 71 | } 72 | } 73 | 74 | impl PartialOrd for Hash256 { 75 | fn partial_cmp(&self, other: &Hash256) -> Option { 76 | Some(self.cmp(other)) 77 | } 78 | } 79 | 80 | impl fmt::Debug for Hash256 { 81 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 82 | write!(f, "{}", self.encode()) 83 | } 84 | } 85 | 86 | #[cfg(test)] 87 | mod tests { 88 | use super::*; 89 | use hex; 90 | use std::io::Cursor; 91 | 92 | #[test] 93 | fn sha256d_test() { 94 | let x = hex::decode("0123456789abcdef").unwrap(); 95 | let e = hex::encode(sha256d(&x).0); 96 | assert!(e == "137ad663f79da06e282ed0abbec4d70523ced5ff8e39d5c2e5641d978c5925aa"); 97 | } 98 | 99 | #[test] 100 | fn hash_decode() { 101 | // Valid 102 | let s1 = "0000000000000000000000000000000000000000000000000000000000000000"; 103 | let s2 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; 104 | let s3 = "abcdef0000112233445566778899abcdef000011223344556677889912345678"; 105 | assert!(Hash256::decode(s1).is_ok()); 106 | assert!(Hash256::decode(s2).is_ok()); 107 | assert!(Hash256::decode(s3).is_ok()); 108 | 109 | // Invalid 110 | let s1 = "000000000000000000000000000000000000000000000000000000000000000"; 111 | let s2 = "00000000000000000000000000000000000000000000000000000000000000000"; 112 | let s3 = "000000000000000000000000000000000000000000000000000000000000000g"; 113 | assert!(Hash256::decode(s1).is_err()); 114 | assert!(Hash256::decode(s2).is_err()); 115 | assert!(Hash256::decode(s3).is_err()); 116 | } 117 | 118 | #[test] 119 | fn hash_decode_write_read_encode() { 120 | let s1 = "abcdef0000112233445566778899abcdef000011223344556677889912345678"; 121 | let h1 = Hash256::decode(s1).unwrap(); 122 | let mut v = Vec::new(); 123 | h1.write(&mut v).unwrap(); 124 | let h2 = Hash256::read(&mut Cursor::new(v)).unwrap(); 125 | let s2 = h2.encode(); 126 | assert!(s1 == s2); 127 | } 128 | 129 | #[test] 130 | fn hash_compare() { 131 | let s1 = "5555555555555555555555555555555555555555555555555555555555555555"; 132 | let s2 = "5555555555555555555555555555555555555555555555555555555555555555"; 133 | assert!(Hash256::decode(s1).unwrap() == Hash256::decode(s2).unwrap()); 134 | 135 | let s1 = "0555555555555555555555555555555555555555555555555555555555555555"; 136 | let s2 = "5555555555555555555555555555555555555555555555555555555555555555"; 137 | assert!(Hash256::decode(s1).unwrap() < Hash256::decode(s2).unwrap()); 138 | 139 | let s1 = "5555555555555555555555555555555555555555555555555555555555555550"; 140 | let s2 = "5555555555555555555555555555555555555555555555555555555555555555"; 141 | assert!(Hash256::decode(s1).unwrap() < Hash256::decode(s2).unwrap()); 142 | 143 | let s1 = "6555555555555555555555555555555555555555555555555555555555555555"; 144 | let s2 = "5555555555555555555555555555555555555555555555555555555555555555"; 145 | assert!(Hash256::decode(s1).unwrap() > Hash256::decode(s2).unwrap()); 146 | 147 | let s1 = "5555555555555555555555555555555555555555555555555555555555555556"; 148 | let s2 = "5555555555555555555555555555555555555555555555555555555555555555"; 149 | assert!(Hash256::decode(s1).unwrap() > Hash256::decode(s2).unwrap()); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/messages/message_header.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Error, Result, Serializable}; 2 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 3 | use ring::digest; 4 | use std::fmt; 5 | use std::io; 6 | use std::io::{Cursor, Read, Write}; 7 | use std::str; 8 | 9 | /// Header that begins all messages 10 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 11 | pub struct MessageHeader { 12 | /// Magic bytes indicating the network type 13 | pub magic: [u8; 4], 14 | /// Command name 15 | pub command: [u8; 12], 16 | /// Payload size 17 | pub payload_size: u32, 18 | /// First 4 bytes of SHA256(SHA256(payload)) 19 | pub checksum: [u8; 4], 20 | } 21 | 22 | impl MessageHeader { 23 | /// Size of the message header in bytes 24 | pub const SIZE: usize = 24; 25 | 26 | /// Returns the size of the header in bytes 27 | pub fn size(&self) -> usize { 28 | MessageHeader::SIZE 29 | } 30 | 31 | /// Checks if the header is valid 32 | /// 33 | /// `magic` - Expected magic bytes for the network 34 | /// `max_size` - Max size in bytes for the payload 35 | pub fn validate(&self, magic: [u8; 4], max_size: u32) -> Result<()> { 36 | if self.magic != magic { 37 | let msg = format!("Bad magic: {:?}", self.magic); 38 | return Err(Error::BadData(msg)); 39 | } 40 | if self.payload_size > max_size { 41 | let msg = format!("Bad size: {:?}", self.payload_size); 42 | return Err(Error::BadData(msg)); 43 | } 44 | Ok(()) 45 | } 46 | 47 | /// Reads the payload and verifies its checksum 48 | pub fn payload(&self, reader: &mut dyn Read) -> Result> { 49 | let mut p = vec![0; self.payload_size as usize]; 50 | reader.read_exact(p.as_mut())?; 51 | let hash = digest::digest(&digest::SHA256, p.as_ref()); 52 | let hash = digest::digest(&digest::SHA256, &hash.as_ref()); 53 | let h = &hash.as_ref(); 54 | let j = &self.checksum; 55 | if h[0] != j[0] || h[1] != j[1] || h[2] != j[2] || h[3] != j[3] { 56 | let msg = format!("Bad checksum: {:?} != {:?}", &h[..4], j); 57 | return Err(Error::BadData(msg)); 58 | } 59 | Ok(p) 60 | } 61 | } 62 | 63 | impl Serializable for MessageHeader { 64 | fn read(reader: &mut dyn Read) -> Result { 65 | // Read all the bytes at once so that the stream doesn't get in a partially-read state 66 | let mut p = vec![0; MessageHeader::SIZE]; 67 | reader.read_exact(p.as_mut())?; 68 | let mut c = Cursor::new(p); 69 | 70 | // Now parse the results from the stream 71 | let mut ret = MessageHeader { 72 | ..Default::default() 73 | }; 74 | c.read(&mut ret.magic)?; 75 | c.read(&mut ret.command)?; 76 | ret.payload_size = c.read_u32::()?; 77 | c.read(&mut ret.checksum)?; 78 | 79 | Ok(ret) 80 | } 81 | 82 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 83 | writer.write(&self.magic)?; 84 | writer.write(&self.command)?; 85 | writer.write_u32::(self.payload_size)?; 86 | writer.write(&self.checksum)?; 87 | Ok(()) 88 | } 89 | } 90 | 91 | // Prints so the command is easier to read 92 | impl fmt::Debug for MessageHeader { 93 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 94 | let command = match str::from_utf8(&self.command) { 95 | Ok(s) => s.to_string(), 96 | Err(_) => format!("Not Ascii ({:?})", self.command), 97 | }; 98 | write!( 99 | f, 100 | "Header {{ magic: {:?}, command: {:?}, payload_size: {}, checksum: {:?} }}", 101 | self.magic, command, self.payload_size, self.checksum 102 | ) 103 | } 104 | } 105 | 106 | #[cfg(test)] 107 | mod tests { 108 | use super::*; 109 | use hex; 110 | use std::io::Cursor; 111 | 112 | #[test] 113 | fn read_bytes() { 114 | let b = hex::decode("f9beb4d976657273696f6e00000000007a0000002a1957bb".as_bytes()).unwrap(); 115 | let h = MessageHeader::read(&mut Cursor::new(&b)).unwrap(); 116 | assert!(h.magic == [0xf9, 0xbe, 0xb4, 0xd9]); 117 | assert!(h.command == *b"version\0\0\0\0\0"); 118 | assert!(h.payload_size == 122); 119 | assert!(h.checksum == [0x2a, 0x19, 0x57, 0xbb]); 120 | } 121 | 122 | #[test] 123 | fn write_read() { 124 | let mut v = Vec::new(); 125 | let h = MessageHeader { 126 | magic: [0x00, 0x01, 0x02, 0x03], 127 | command: *b"command\0\0\0\0\0", 128 | payload_size: 42, 129 | checksum: [0xa0, 0xa1, 0xa2, 0xa3], 130 | }; 131 | h.write(&mut v).unwrap(); 132 | assert!(v.len() == h.size()); 133 | assert!(MessageHeader::read(&mut Cursor::new(&v)).unwrap() == h); 134 | } 135 | 136 | #[test] 137 | fn validate() { 138 | let magic = [0xa0, 0xa1, 0xa2, 0xa3]; 139 | let h = MessageHeader { 140 | magic, 141 | command: *b"verack\0\0\0\0\0\0", 142 | payload_size: 88, 143 | checksum: [0x12, 0x34, 0x56, 0x78], 144 | }; 145 | // Valid 146 | assert!(h.validate(magic, 100).is_ok()); 147 | // Bad magic 148 | let bad_magic = [0xb0, 0xb1, 0xb2, 0xb3]; 149 | assert!(h.validate(bad_magic, 100).is_err()); 150 | // Bad size 151 | assert!(h.validate(magic, 50).is_err()); 152 | } 153 | 154 | #[test] 155 | fn payload() { 156 | let p = [0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x45, 0x67, 0x89]; 157 | let hash = digest::digest(&digest::SHA256, &p); 158 | let hash = digest::digest(&digest::SHA256, hash.as_ref()); 159 | let hash = hash.as_ref(); 160 | let checksum = [hash[0], hash[1], hash[2], hash[3]]; 161 | let header = MessageHeader { 162 | magic: [0x00, 0x00, 0x00, 0x00], 163 | command: *b"version\0\0\0\0\0", 164 | payload_size: p.len() as u32, 165 | checksum, 166 | }; 167 | // Valid 168 | let v = header.payload(&mut Cursor::new(&p)).unwrap(); 169 | assert!(v.as_ref() == p); 170 | // Bad checksum 171 | let p2 = [0xf2, 0xf3, 0xf4, 0xf0, 0xf1, 0xf2, 0xf5, 0xf7, 0xf9]; 172 | assert!(header.payload(&mut Cursor::new(&p2)).is_err()); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/util/bits.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::min; 2 | 3 | const LSHIFT_MASK: [u8; 8] = [0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01]; 4 | const RSHIFT_MASK: [u8; 8] = [0xff, 0xfE, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80]; 5 | 6 | /// Manages an array of bits 7 | #[derive(Debug, Default, Clone)] 8 | pub struct Bits { 9 | pub data: Vec, 10 | pub len: usize, 11 | } 12 | 13 | impl Bits { 14 | /// Creates an empty bit array 15 | pub fn new() -> Bits { 16 | Bits { 17 | data: vec![], 18 | len: 0, 19 | } 20 | } 21 | 22 | /// Creates a bits array with default capacity for a certain size 23 | pub fn with_capacity(capacity: usize) -> Bits { 24 | Bits { 25 | data: Vec::with_capacity(capacity / 8), 26 | len: 0, 27 | } 28 | } 29 | 30 | /// Creates the bits from a slice 31 | pub fn from_slice(data: &[u8], len: usize) -> Bits { 32 | let mut vec = data.to_vec(); 33 | let len = min(data.len() * 8, len); 34 | if len > vec.len() * 8 { 35 | vec.truncate((len + 7) / 8); 36 | } 37 | let rem = (len % 8) as u8; 38 | if rem != 0 { 39 | let last = vec.len() - 1; 40 | vec[last] &= (!((1 << (8_u8 - rem)) - 1)) as u8; 41 | } 42 | Bits { data: vec, len } 43 | } 44 | 45 | /// Appends data to the bit array 46 | pub fn append(&mut self, other: &Bits) { 47 | let mut i = 0; 48 | while i < other.len / 8 { 49 | self.append_byte(other.data[i], 8); 50 | i += 1; 51 | } 52 | let rem = other.len % 8; 53 | if rem != 0 { 54 | self.append_byte(other.data[i], rem); 55 | } 56 | } 57 | 58 | /// Appends a byte or less to the bit array 59 | fn append_byte(&mut self, byte: u8, len: usize) { 60 | let end = self.len % 8; 61 | if end == 0 { 62 | self.data.push(byte); 63 | self.len += len; 64 | } else { 65 | let last = self.data.len() - 1; 66 | self.data[last] |= byte >> end; 67 | if len > 8 - end { 68 | self.data.push(byte << (8 - end)); 69 | } 70 | self.len += len; 71 | } 72 | } 73 | 74 | /// Gets a range out of the bit array, right-aligned 75 | pub fn extract(&self, i: usize, len: usize) -> u64 { 76 | let end = i + len; 77 | let mut curr: u64 = 0; 78 | let mut i = i; 79 | for j in i / 8..((i + len + 7) / 8) { 80 | let b_len = min(end - i, 8 - (i - j * 8)); 81 | curr = (curr << b_len) | self.extract_byte(i, b_len) as u64; 82 | i += b_len; 83 | } 84 | curr 85 | } 86 | 87 | /// Extracts a byte or less from the bit array, right-aligned 88 | pub fn extract_byte(&self, i: usize, len: usize) -> u8 { 89 | let b = (self.data[i / 8] >> (8 - (i % 8) - len)) as u16; 90 | (b & ((1_u16 << len) - 1)) as u8 91 | } 92 | } 93 | 94 | pub fn lshift(v: &[u8], n: usize) -> Vec { 95 | let bit_shift = n % 8; 96 | let byte_shift = (n / 8) as i32; 97 | 98 | let mask = LSHIFT_MASK[bit_shift]; 99 | let overflow_mask = !mask; 100 | 101 | let mut result = vec![0; v.len()]; 102 | for i in (0..v.len()).rev() { 103 | let k = i as i32 - byte_shift; 104 | if k >= 0 { 105 | let mut val = v[i] & mask; 106 | val <<= bit_shift; 107 | result[k as usize] |= val; 108 | } 109 | if k - 1 >= 0 { 110 | let mut carryval = v[i] & overflow_mask; 111 | carryval >>= (8 - bit_shift) % 8; 112 | result[(k - 1) as usize] |= carryval; 113 | } 114 | } 115 | result 116 | } 117 | 118 | pub fn rshift(v: &[u8], n: usize) -> Vec { 119 | let bit_shift = n % 8; 120 | let byte_shift = n / 8; 121 | 122 | let mask = RSHIFT_MASK[bit_shift]; 123 | let overflow_mask = !mask; 124 | 125 | let mut result = vec![0; v.len()]; 126 | for i in 0..v.len() { 127 | let k = i + byte_shift; 128 | if k < v.len() { 129 | let mut val = v[i] & mask; 130 | val >>= bit_shift; 131 | result[k] |= val; 132 | } 133 | if k + 1 < v.len() { 134 | let mut carryval = v[i] & overflow_mask; 135 | carryval <<= (8 - bit_shift) % 8; 136 | result[k + 1] |= carryval; 137 | } 138 | } 139 | result 140 | } 141 | 142 | #[cfg(test)] 143 | mod tests { 144 | use super::*; 145 | 146 | #[test] 147 | fn append() { 148 | let mut b = Bits::from_slice(&[255], 8); 149 | b.append(&Bits::from_slice(&[0], 4)); 150 | b.append(&Bits::from_slice(&[255], 2)); 151 | b.append(&Bits::from_slice(&[63], 4)); 152 | assert!(b.len == 18); 153 | assert!(b.data[0] == 255); 154 | assert!(b.data[1] == 12); 155 | assert!(b.data[2] == 192); 156 | } 157 | 158 | #[test] 159 | fn extract() { 160 | let b = Bits::from_slice(&[15, 23, 192], 24); 161 | let e = b.extract(4, 13); 162 | assert!(e == 7727); 163 | } 164 | 165 | #[test] 166 | fn lshift_test() { 167 | // Empty array 168 | assert!(lshift(&[], 0) == vec![]); 169 | assert!(lshift(&[], 1) == vec![]); 170 | assert!(lshift(&[], 999999) == vec![]); 171 | 172 | // No shifts 173 | assert!(lshift(&[0x80, 0x10, 0x30, 0x55], 0) == vec![0x80, 0x10, 0x30, 0x55]); 174 | assert!(lshift(&[0xff], 0) == vec![0xff]); 175 | 176 | // Shift one 177 | assert!(lshift(&[0x80, 0x00, 0x00, 0x01], 1) == vec![0x00, 0x00, 0x00, 0x02]); 178 | assert!(lshift(&[0x80, 0x00, 0x00, 0x00], 999999) == vec![0x00, 0x00, 0x00, 0x00]); 179 | 180 | // Shift four 181 | assert!(lshift(&[0x01, 0x23, 0x45, 0x67], 4) == vec![0x12, 0x34, 0x56, 0x70]); 182 | 183 | // Shift eight 184 | assert!(lshift(&[0x01, 0x23, 0x45, 0x67], 8) == vec![0x23, 0x45, 0x67, 0x00]); 185 | } 186 | 187 | #[test] 188 | fn rshift_test() { 189 | // Empty array 190 | assert!(rshift(&[], 0) == vec![]); 191 | assert!(rshift(&[], 1) == vec![]); 192 | assert!(rshift(&[], 999999) == vec![]); 193 | 194 | // No shifts 195 | assert!(rshift(&[0x80, 0x10, 0x30, 0x55], 0) == vec![0x80, 0x10, 0x30, 0x55]); 196 | assert!(rshift(&[0xff], 0) == vec![0xff]); 197 | 198 | // Shift one 199 | assert!(rshift(&[0x80, 0x00, 0x00, 0x02], 1) == vec![0x40, 0x00, 0x00, 0x01]); 200 | assert!(rshift(&[0x00, 0x00, 0x00, 0x01], 999999) == vec![0x00, 0x00, 0x00, 0x00]); 201 | 202 | // Shift four 203 | assert!(rshift(&[0x01, 0x23, 0x45, 0x67], 4) == vec![0x00, 0x12, 0x34, 0x56]); 204 | 205 | // Shift eight 206 | assert!(rshift(&[0x01, 0x23, 0x45, 0x67], 8) == vec![0x00, 0x01, 0x23, 0x45]); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/util/bloom_filter.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{var_int, Error, Result, Serializable}; 2 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 3 | use hex; 4 | use murmur3::murmur3_32; 5 | use rand::random; 6 | use std::fmt; 7 | use std::io; 8 | use std::io::{Cursor, Read, Write}; 9 | use std::num::Wrapping; 10 | 11 | /// Maximum number of bytes in the bloom filter bit field 12 | pub const BLOOM_FILTER_MAX_FILTER_SIZE: usize = 36000; 13 | 14 | /// Maximum number of hash functions for the bloom filter 15 | pub const BLOOM_FILTER_MAX_HASH_FUNCS: usize = 50; 16 | 17 | /// Bloom filter used by SPV nodes to limit transactions received 18 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 19 | pub struct BloomFilter { 20 | /// Filter bit field 21 | pub filter: Vec, 22 | /// Number of hash functions used 23 | pub num_hash_funcs: usize, 24 | /// Random tweak to generate the hash functions 25 | pub tweak: u32, 26 | } 27 | 28 | impl BloomFilter { 29 | /// Creates a new bloom filter 30 | /// 31 | /// * `insert` - Number of items expected to be inserted into the bloom filter 32 | /// * `pr_false_pos` - Desired probability of a false positive 33 | pub fn new(insert: f64, pr_false_pos: f64) -> Result { 34 | if !insert.is_normal() || insert < 0. { 35 | return Err(Error::BadArgument("insert not valid".to_string())); 36 | } 37 | if !pr_false_pos.is_normal() || pr_false_pos < 0. { 38 | return Err(Error::BadArgument("pr_false_po not valid".to_string())); 39 | } 40 | let ln2 = 2_f64.ln(); 41 | let size = (-1_f64 / ln2.powf(2_f64) * insert * pr_false_pos.ln()) / 8_f64; 42 | let size = size.min(BLOOM_FILTER_MAX_FILTER_SIZE as f64); 43 | let num_hash_funcs = (size as f64) * 8_f64 / insert * ln2; 44 | let num_hash_funcs = num_hash_funcs.min(BLOOM_FILTER_MAX_HASH_FUNCS as f64); 45 | let size = size.ceil() as usize; 46 | let num_hash_funcs = num_hash_funcs.ceil() as usize; 47 | let tweak = random(); 48 | debug!( 49 | "Creating bloom filter of size: {}, n_hash funcs: {}, tweak: {}", 50 | size, num_hash_funcs, tweak 51 | ); 52 | Ok(BloomFilter { 53 | filter: vec![0; size], 54 | num_hash_funcs, 55 | tweak, 56 | }) 57 | } 58 | 59 | /// Adds data to the bloom filter 60 | pub fn add(&mut self, data: &[u8]) { 61 | debug!("Adding to bloom filter: {:?}", hex::encode(&data)); 62 | for i in 0..self.num_hash_funcs { 63 | let seed = Wrapping(i as u32) * Wrapping(0xFBA4C795) + Wrapping(self.tweak); 64 | let c = murmur3_32(&mut Cursor::new(&data), seed.0) % (self.filter.len() as u32 * 8); 65 | self.filter[c as usize / 8] |= 1 << (c % 8); 66 | } 67 | } 68 | 69 | /// Probabilistically returns whether the bloom filter contains the given data 70 | /// 71 | /// There may be false positives, but there won't be false negatives. 72 | pub fn contains(&self, data: &[u8]) -> bool { 73 | for i in 0..self.num_hash_funcs { 74 | let seed = Wrapping(i as u32) * Wrapping(0xFBA4C795) + Wrapping(self.tweak); 75 | let c = murmur3_32(&mut Cursor::new(&data), seed.0) % (self.filter.len() as u32 * 8); 76 | if self.filter[c as usize / 8] & 1 << (c % 8) == 0 { 77 | return false; 78 | } 79 | } 80 | true 81 | } 82 | 83 | /// Returns whether the BloomFilter is valid 84 | pub fn validate(&self) -> Result<()> { 85 | if self.filter.len() > BLOOM_FILTER_MAX_FILTER_SIZE { 86 | return Err(Error::BadData("Filter too long".to_string())); 87 | } 88 | if self.num_hash_funcs > BLOOM_FILTER_MAX_HASH_FUNCS { 89 | return Err(Error::BadData("Too many hash funcs".to_string())); 90 | } 91 | Ok(()) 92 | } 93 | } 94 | 95 | impl Serializable for BloomFilter { 96 | fn read(reader: &mut dyn Read) -> Result { 97 | let filter_len = var_int::read(reader)? as usize; 98 | let mut bloom_filter = BloomFilter { 99 | filter: vec![0; filter_len], 100 | num_hash_funcs: 0, 101 | tweak: 0, 102 | }; 103 | reader.read(&mut bloom_filter.filter)?; 104 | bloom_filter.num_hash_funcs = reader.read_u64::()? as usize; 105 | bloom_filter.tweak = reader.read_u32::()?; 106 | Ok(bloom_filter) 107 | } 108 | 109 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 110 | var_int::write(self.filter.len() as u64, writer)?; 111 | writer.write(&self.filter)?; 112 | writer.write_u64::(self.num_hash_funcs as u64)?; 113 | writer.write_u32::(self.tweak)?; 114 | Ok(()) 115 | } 116 | } 117 | 118 | impl fmt::Debug for BloomFilter { 119 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 120 | f.debug_struct("BloomFilter") 121 | .field("filter", &hex::encode(&self.filter)) 122 | .field("num_hash_funcs", &self.num_hash_funcs) 123 | .field("tweak", &self.tweak) 124 | .finish() 125 | } 126 | } 127 | 128 | #[cfg(test)] 129 | mod tests { 130 | use super::*; 131 | use std; 132 | 133 | #[test] 134 | fn write_read() { 135 | let mut bf = BloomFilter::new(20000., 0.001).unwrap(); 136 | for i in 0..5 { 137 | bf.add(&vec![i; 32]); 138 | } 139 | let mut v = Vec::new(); 140 | bf.write(&mut v).unwrap(); 141 | assert!(BloomFilter::read(&mut Cursor::new(&v)).unwrap() == bf); 142 | } 143 | 144 | #[test] 145 | fn contains() { 146 | let mut bf = BloomFilter::new(20000., 0.001).unwrap(); 147 | bf.add(&vec![5; 32]); 148 | assert!(bf.contains(&vec![5; 32])); 149 | assert!(!bf.contains(&vec![6; 32])); 150 | } 151 | 152 | #[test] 153 | fn invalid() { 154 | assert!(BloomFilter::new(0., 0.5).is_err()); 155 | assert!(BloomFilter::new(1., 0.).is_err()); 156 | assert!(BloomFilter::new(-1., 0.5).is_err()); 157 | assert!(BloomFilter::new(1., -1.).is_err()); 158 | assert!(BloomFilter::new(1., std::f64::NAN).is_err()); 159 | assert!(BloomFilter::new(std::f64::NAN, 0.5).is_err()); 160 | } 161 | 162 | #[test] 163 | fn validate() { 164 | let bf = BloomFilter { 165 | filter: vec![0, 1, 2, 3, 4, 5], 166 | num_hash_funcs: 30, 167 | tweak: 100, 168 | }; 169 | assert!(bf.validate().is_ok()); 170 | 171 | let mut bf_clone = bf.clone(); 172 | bf_clone.filter = vec![0; BLOOM_FILTER_MAX_FILTER_SIZE + 1]; 173 | assert!(bf_clone.validate().is_err()); 174 | 175 | let mut bf_clone = bf.clone(); 176 | bf_clone.num_hash_funcs = BLOOM_FILTER_MAX_HASH_FUNCS + 1; 177 | assert!(bf_clone.validate().is_err()); 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/network/network.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::{Block, BlockHeader, OutPoint, Tx, TxIn, TxOut}; 2 | use crate::network::SeedIter; 3 | use crate::script::Script; 4 | use crate::util::{Error, Hash256, Result}; 5 | use hex; 6 | 7 | /// Network type 8 | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] 9 | pub enum Network { 10 | Mainnet = 0, 11 | Testnet = 1, 12 | STN = 2, 13 | } 14 | 15 | impl Network { 16 | /// Converts an integer to a network type 17 | pub fn from_u8(x: u8) -> Result { 18 | match x { 19 | x if x == Network::Mainnet as u8 => Ok(Network::Mainnet), 20 | x if x == Network::Testnet as u8 => Ok(Network::Testnet), 21 | x if x == Network::STN as u8 => Ok(Network::STN), 22 | _ => { 23 | let msg = format!("Unknown network type: {}", x); 24 | Err(Error::BadArgument(msg)) 25 | } 26 | } 27 | } 28 | 29 | /// Returns the default TCP port 30 | pub fn port(&self) -> u16 { 31 | match self { 32 | Network::Mainnet => 8333, 33 | Network::Testnet => 18333, 34 | Network::STN => 9333, 35 | } 36 | } 37 | 38 | /// Returns the magic bytes for the message headers 39 | pub fn magic(&self) -> [u8; 4] { 40 | match self { 41 | Network::Mainnet => [0xe3, 0xe1, 0xf3, 0xe8], 42 | Network::Testnet => [0xf4, 0xe5, 0xf3, 0xf4], 43 | Network::STN => [0xfb, 0xce, 0xc4, 0xf9], 44 | } 45 | } 46 | 47 | /// Returns the genesis block 48 | pub fn genesis_block(&self) -> Block { 49 | match self { 50 | Network::Mainnet => { 51 | let header = BlockHeader { 52 | version: 1, 53 | prev_hash: Hash256([0; 32]), 54 | merkle_root: Hash256::decode( 55 | "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", 56 | ) 57 | .unwrap(), 58 | timestamp: 1231006505, 59 | bits: 0x1d00ffff, 60 | nonce: 2083236893, 61 | }; 62 | 63 | let tx = Tx { 64 | version: 1, 65 | inputs: vec![TxIn { 66 | prev_output: OutPoint { 67 | hash: Hash256([0; 32]), 68 | index: 0xffffffff, 69 | }, 70 | unlock_script: Script(hex::decode("04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73").unwrap()), 71 | sequence: 0xffffffff, 72 | }], 73 | outputs: vec![TxOut { 74 | satoshis: 5000000000, 75 | lock_script: Script(hex::decode("4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac").unwrap()), 76 | }], 77 | lock_time: 0, 78 | }; 79 | 80 | Block { 81 | header, 82 | txns: vec![tx], 83 | } 84 | } 85 | Network::Testnet | Network::STN => { 86 | let header = BlockHeader { 87 | version: 1, 88 | prev_hash: Hash256([0; 32]), 89 | merkle_root: Hash256::decode( 90 | "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", 91 | ) 92 | .unwrap(), 93 | timestamp: 1296688602, 94 | bits: 0x1d00ffff, 95 | nonce: 414098458, 96 | }; 97 | 98 | let tx = Tx { 99 | version: 1, 100 | inputs: vec![TxIn { 101 | prev_output: OutPoint { 102 | hash: Hash256([0; 32]), 103 | index: 0xffffffff, 104 | }, 105 | unlock_script: Script(hex::decode("04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73").unwrap()), 106 | sequence: 0xffffffff, 107 | }], 108 | outputs: vec![TxOut { 109 | satoshis: 5000000000, 110 | lock_script: Script(hex::decode("4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac").unwrap()), 111 | }], 112 | lock_time: 0, 113 | }; 114 | 115 | Block { 116 | header, 117 | txns: vec![tx], 118 | } 119 | } 120 | } 121 | } 122 | 123 | /// Returns the genesis block hash 124 | pub fn genesis_hash(&self) -> Hash256 { 125 | match self { 126 | Network::Mainnet => { 127 | Hash256::decode("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") 128 | .unwrap() 129 | } 130 | Network::Testnet | Network::STN => { 131 | Hash256::decode("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943") 132 | .unwrap() 133 | } 134 | } 135 | } 136 | 137 | /// Returns the version byte flag for P2PKH-type addresses 138 | pub fn addr_pubkeyhash_flag(&self) -> u8 { 139 | match self { 140 | Network::Mainnet => 0x00, 141 | Network::Testnet => 0x6f, 142 | Network::STN => 0x6f, 143 | } 144 | } 145 | 146 | /// Returns the version byte flag for P2SH-type addresses 147 | pub fn addr_script_flag(&self) -> u8 { 148 | match self { 149 | Network::Mainnet => 0x05, 150 | Network::Testnet => 0xc4, 151 | Network::STN => 0xc4, 152 | } 153 | } 154 | 155 | /// Returns a list of DNS seeds for finding initial nodes 156 | pub fn seeds(&self) -> Vec { 157 | match self { 158 | Network::Mainnet => vec![ 159 | "seed.bitcoinsv.io".to_string(), 160 | "seed.cascharia.com".to_string(), 161 | "seed.satoshisvision.network".to_string(), 162 | ], 163 | Network::Testnet => vec![ 164 | "testnet-seed.bitcoinsv.io".to_string(), 165 | "testnet-seed.cascharia.com".to_string(), 166 | "testnet-seed.bitcoincloud.net".to_string(), 167 | ], 168 | Network::STN => vec!["stn-seed.bitcoinsv.io".to_string()], 169 | } 170 | } 171 | 172 | /// Creates a new DNS seed iterator for this network 173 | pub fn seed_iter(&self) -> SeedIter { 174 | SeedIter::new(&self.seeds(), self.port()) 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/messages/block_header.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{sha256d, Error, Hash256, Result, Serializable}; 2 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 3 | use std::cmp::min; 4 | use std::io; 5 | use std::io::{Read, Write}; 6 | 7 | /// Block header 8 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 9 | pub struct BlockHeader { 10 | /// Block version specifying which validation rules to use 11 | pub version: u32, 12 | /// Hash of the previous block 13 | pub prev_hash: Hash256, 14 | /// Root of the merkle tree of this block's transaction hashes 15 | pub merkle_root: Hash256, 16 | /// Timestamp when this block was created as recorded by the miner 17 | pub timestamp: u32, 18 | /// Target difficulty bits 19 | pub bits: u32, 20 | /// Nonce used to mine the block 21 | pub nonce: u32, 22 | } 23 | 24 | impl BlockHeader { 25 | /// Size of the BlockHeader in bytes 26 | pub const SIZE: usize = 80; 27 | 28 | /// Returns the size of the block header in bytes 29 | pub fn size(&self) -> usize { 30 | BlockHeader::SIZE 31 | } 32 | 33 | /// Calculates the hash for this block header 34 | pub fn hash(&self) -> Hash256 { 35 | let mut v = Vec::with_capacity(80); 36 | v.write_u32::(self.version).unwrap(); 37 | self.prev_hash.write(&mut v).unwrap(); 38 | self.merkle_root.write(&mut v).unwrap(); 39 | v.write_u32::(self.timestamp).unwrap(); 40 | v.write_u32::(self.bits).unwrap(); 41 | v.write_u32::(self.nonce).unwrap(); 42 | sha256d(&v) 43 | } 44 | 45 | /// Checks that the block header is valid 46 | pub fn validate(&self, hash: &Hash256, prev_headers: &[BlockHeader]) -> Result<()> { 47 | // Timestamp > median timestamp of last 11 blocks 48 | if prev_headers.len() > 0 { 49 | let h = &prev_headers[prev_headers.len() - min(prev_headers.len(), 11)..]; 50 | let mut timestamps: Vec = h.iter().map(|x| x.timestamp).collect(); 51 | timestamps.sort(); 52 | if self.timestamp < timestamps[timestamps.len() / 2] { 53 | let msg = format!("Timestamp is too old: {}", self.timestamp); 54 | return Err(Error::BadData(msg)); 55 | } 56 | } 57 | 58 | // POW 59 | let target = self.difficulty_target()?; 60 | if hash > &target { 61 | return Err(Error::BadData("Invalid POW".to_string())); 62 | } 63 | 64 | Ok(()) 65 | } 66 | 67 | /// Calculates the target difficulty hash 68 | fn difficulty_target(&self) -> Result { 69 | let exp = (self.bits >> 24) as usize; 70 | if exp < 3 || exp > 32 { 71 | let msg = format!("Difficulty exponent out of range: {:?}", self.bits); 72 | return Err(Error::BadArgument(msg)); 73 | } 74 | let mut difficulty = [0_u8; 32]; 75 | difficulty[exp - 1] = ((self.bits >> 16) & 0xff) as u8; 76 | difficulty[exp - 2] = ((self.bits >> 08) & 0xff) as u8; 77 | difficulty[exp - 3] = ((self.bits >> 00) & 0xff) as u8; 78 | Ok(Hash256(difficulty)) 79 | } 80 | } 81 | 82 | impl Serializable for BlockHeader { 83 | fn read(reader: &mut dyn Read) -> Result { 84 | let version = reader.read_u32::()?; 85 | let prev_hash = Hash256::read(reader)?; 86 | let merkle_root = Hash256::read(reader)?; 87 | let ts = reader.read_u32::()?; 88 | let bits = reader.read_u32::()?; 89 | let nonce = reader.read_u32::()?; 90 | Ok(BlockHeader { 91 | version, 92 | prev_hash, 93 | merkle_root, 94 | timestamp: ts, 95 | bits, 96 | nonce, 97 | }) 98 | } 99 | 100 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 101 | writer.write_u32::(self.version)?; 102 | self.prev_hash.write(writer)?; 103 | self.merkle_root.write(writer)?; 104 | writer.write_u32::(self.timestamp)?; 105 | writer.write_u32::(self.bits)?; 106 | writer.write_u32::(self.nonce)?; 107 | Ok(()) 108 | } 109 | } 110 | 111 | #[cfg(test)] 112 | mod tests { 113 | use super::*; 114 | use std::io::Cursor; 115 | 116 | #[test] 117 | fn write_read() { 118 | let mut v = Vec::new(); 119 | let block_header = BlockHeader { 120 | version: 12345, 121 | prev_hash: Hash256::decode( 122 | "7766009988776600998877660099887766009988776600998877660099887766", 123 | ) 124 | .unwrap(), 125 | merkle_root: Hash256::decode( 126 | "2211554433221155443322115544332211554433221155443322115544332211", 127 | ) 128 | .unwrap(), 129 | timestamp: 66, 130 | bits: 4488, 131 | nonce: 9999, 132 | }; 133 | block_header.write(&mut v).unwrap(); 134 | assert!(v.len() == block_header.size()); 135 | assert!(BlockHeader::read(&mut Cursor::new(&v)).unwrap() == block_header); 136 | } 137 | 138 | #[test] 139 | fn hash() { 140 | let block_header = BlockHeader { 141 | version: 0x00000001, 142 | prev_hash: Hash256::decode( 143 | "00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81", 144 | ) 145 | .unwrap(), 146 | merkle_root: Hash256::decode( 147 | "2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3", 148 | ) 149 | .unwrap(), 150 | timestamp: 0x4dd7f5c7, 151 | bits: 0x1a44b9f2, 152 | nonce: 0x9546a142, 153 | }; 154 | let str_hash = block_header.hash().encode(); 155 | let expected_hash = "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d"; 156 | assert!(str_hash == expected_hash); 157 | } 158 | 159 | #[test] 160 | fn validate() { 161 | let prev_hash = 162 | Hash256::decode("00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81") 163 | .unwrap(); 164 | 165 | let mut headers = Vec::new(); 166 | for i in 0..11 { 167 | headers.push(BlockHeader { 168 | timestamp: i * 10, 169 | ..Default::default() 170 | }); 171 | } 172 | 173 | let valid = BlockHeader { 174 | version: 0x00000001, 175 | prev_hash, 176 | merkle_root: Hash256::decode( 177 | "2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3", 178 | ) 179 | .unwrap(), 180 | timestamp: 0x4dd7f5c7, 181 | bits: 0x1a44b9f2, 182 | nonce: 0x9546a142, 183 | }; 184 | assert!(valid.validate(&valid.hash(), &headers).is_ok()); 185 | 186 | // Bad timestamp 187 | let h = valid.clone(); 188 | for header in headers.iter_mut() { 189 | header.timestamp = valid.timestamp + 1; 190 | } 191 | assert!(h.validate(&h.hash(), &headers).is_err()); 192 | 193 | // Bad POW 194 | let mut h = valid.clone(); 195 | h.nonce = 0; 196 | assert!(h.validate(&h.hash(), &headers).is_err()); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/messages/version.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::message::Payload; 2 | use crate::messages::node_addr::NodeAddr; 3 | use crate::util::{secs_since, var_int, Error, Result, Serializable}; 4 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 5 | use std::io; 6 | use std::io::{Read, Write}; 7 | use std::time::UNIX_EPOCH; 8 | 9 | /// Protocol version supported by this library 10 | pub const PROTOCOL_VERSION: u32 = 70015; 11 | 12 | /// Minimum protocol version supported by this library 13 | pub const MIN_SUPPORTED_PROTOCOL_VERSION: u32 = 70001; 14 | 15 | /// Unknown IP address to use as a default 16 | pub const UNKNOWN_IP: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1]; 17 | 18 | /// Service flag that node is not a full node. Used for SPV wallets. 19 | pub const NODE_NONE: u64 = 0; 20 | 21 | /// Service flag that node is a full node and implements all protocol features 22 | pub const NODE_NETWORK: u64 = 1; 23 | 24 | /// Service flag that node is a full node and implements all protocol features 25 | pub const NODE_BITCOIN_CASH: u64 = 1 << 5; 26 | 27 | /// Version payload defining a node's capabilities 28 | #[derive(Debug, Default, PartialEq, Eq, Hash, Clone)] 29 | pub struct Version { 30 | /// The protocol version being used by the node 31 | pub version: u32, 32 | /// Bitfield of features to be enabled for this connection 33 | pub services: u64, 34 | /// Time since the Unix epoch in seconds 35 | pub timestamp: i64, 36 | /// Network address of the node receiving this message 37 | pub recv_addr: NodeAddr, 38 | /// Network address of the node emitting this message 39 | pub tx_addr: NodeAddr, 40 | /// A random nonce which can help a node detect a connection to itself 41 | pub nonce: u64, 42 | /// User agent string 43 | pub user_agent: String, 44 | /// Height of the transmiting node's best block chain, or in the case of SPV wallets, block header chain 45 | pub start_height: i32, 46 | /// Whether the client wants to receive broadcast transactions before a filter is set 47 | pub relay: bool, 48 | } 49 | 50 | impl Version { 51 | /// Checks if the version message is valid 52 | pub fn validate(&self) -> Result<()> { 53 | if self.version < MIN_SUPPORTED_PROTOCOL_VERSION { 54 | let msg = format!("Unsupported protocol version: {}", self.version); 55 | return Err(Error::BadData(msg)); 56 | } 57 | let now = secs_since(UNIX_EPOCH) as i64; 58 | if (self.timestamp - now).abs() > 2 * 60 * 60 { 59 | let msg = format!("Timestamp too old: {}", self.timestamp); 60 | return Err(Error::BadData(msg)); 61 | } 62 | Ok(()) 63 | } 64 | } 65 | 66 | impl Serializable for Version { 67 | fn read(reader: &mut dyn Read) -> Result { 68 | let mut ret = Version { 69 | ..Default::default() 70 | }; 71 | ret.version = reader.read_u32::()?; 72 | ret.services = reader.read_u64::()?; 73 | ret.timestamp = reader.read_i64::()?; 74 | ret.recv_addr = NodeAddr::read(reader)?; 75 | ret.tx_addr = NodeAddr::read(reader)?; 76 | ret.nonce = reader.read_u64::()?; 77 | let user_agent_size = var_int::read(reader)? as usize; 78 | let mut user_agent_bytes = vec![0; user_agent_size]; 79 | reader.read(&mut user_agent_bytes)?; 80 | ret.user_agent = String::from_utf8(user_agent_bytes)?; 81 | ret.start_height = reader.read_i32::()?; 82 | ret.relay = reader.read_u8()? == 0x01; 83 | Ok(ret) 84 | } 85 | 86 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 87 | writer.write_u32::(self.version)?; 88 | writer.write_u64::(self.services)?; 89 | writer.write_i64::(self.timestamp)?; 90 | self.recv_addr.write(writer)?; 91 | self.tx_addr.write(writer)?; 92 | writer.write_u64::(self.nonce)?; 93 | var_int::write(self.user_agent.as_bytes().len() as u64, writer)?; 94 | writer.write(&self.user_agent.as_bytes())?; 95 | writer.write_i32::(self.start_height)?; 96 | writer.write_u8(if self.relay { 0x01 } else { 0x00 })?; 97 | Ok(()) 98 | } 99 | } 100 | 101 | impl Payload for Version { 102 | fn size(&self) -> usize { 103 | 33 + self.recv_addr.size() 104 | + self.tx_addr.size() 105 | + var_int::size(self.user_agent.as_bytes().len() as u64) 106 | + self.user_agent.as_bytes().len() 107 | } 108 | } 109 | 110 | #[cfg(test)] 111 | mod tests { 112 | use super::*; 113 | use hex; 114 | use std::io::Cursor; 115 | 116 | #[test] 117 | fn read_bytes() { 118 | let b = hex::decode("7f1101002500000000000000f2d2d25a00000000000000000000000000000000000000000000ffff2d32bffbdd1725000000000000000000000000000000000000000000000000008d501d3bb5369deb242f426974636f696e204142433a302e31362e30284542382e303b20626974636f7265292f6606080001".as_bytes()).unwrap(); 119 | let v = Version::read(&mut Cursor::new(&b)).unwrap(); 120 | assert!(v.version == 70015); 121 | assert!(v.services == 37); 122 | assert!(v.timestamp == 1523766002); 123 | assert!(v.recv_addr.services == 0); 124 | assert!( 125 | v.recv_addr.ip.octets() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 45, 50, 191, 251] 126 | ); 127 | assert!(v.recv_addr.port == 56599); 128 | assert!(v.tx_addr.services == 37); 129 | assert!(v.tx_addr.ip.octets() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); 130 | assert!(v.tx_addr.port == 0); 131 | assert!(v.nonce == 16977786322265395341); 132 | assert!(v.user_agent == "/Bitcoin ABC:0.16.0(EB8.0; bitcore)/"); 133 | assert!(v.start_height == 525926); 134 | assert!(v.relay == true); 135 | } 136 | 137 | #[test] 138 | fn write_read() { 139 | let mut v = Vec::new(); 140 | let m = Version { 141 | version: MIN_SUPPORTED_PROTOCOL_VERSION, 142 | services: 77, 143 | timestamp: 1234, 144 | recv_addr: NodeAddr { 145 | ..Default::default() 146 | }, 147 | tx_addr: NodeAddr { 148 | ..Default::default() 149 | }, 150 | nonce: 99, 151 | user_agent: "dummy".to_string(), 152 | start_height: 22, 153 | relay: true, 154 | }; 155 | m.write(&mut v).unwrap(); 156 | assert!(v.len() == m.size()); 157 | assert!(Version::read(&mut Cursor::new(&v)).unwrap() == m); 158 | } 159 | 160 | #[test] 161 | fn validate() { 162 | let m = Version { 163 | version: MIN_SUPPORTED_PROTOCOL_VERSION, 164 | services: 77, 165 | timestamp: secs_since(UNIX_EPOCH) as i64, 166 | recv_addr: NodeAddr { 167 | ..Default::default() 168 | }, 169 | tx_addr: NodeAddr { 170 | ..Default::default() 171 | }, 172 | nonce: 99, 173 | user_agent: "dummy".to_string(), 174 | start_height: 22, 175 | relay: true, 176 | }; 177 | // Valid 178 | assert!(m.validate().is_ok()); 179 | // Unsupported version 180 | let m2 = Version { 181 | version: 0, 182 | ..m.clone() 183 | }; 184 | assert!(m2.validate().is_err()); 185 | // Bad timestamp 186 | let m3 = Version { 187 | timestamp: 0, 188 | ..m.clone() 189 | }; 190 | assert!(m3.validate().is_err()); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/util/rx.rs: -------------------------------------------------------------------------------- 1 | //! Lightweight reactive library 2 | 3 | use crate::util::future::{Future, FutureProvider}; 4 | use crate::util::{Error, Result}; 5 | use std::sync::{Arc, RwLock, TryLockError, Weak}; 6 | use std::time::Duration; 7 | 8 | /// Observes an event of type T 9 | pub trait Observer: Sync + Send { 10 | /// Called when the event occurs 11 | fn next(&self, event: &T); 12 | } 13 | 14 | /// Event publisher that may be subscribed to 15 | pub trait Observable { 16 | /// Adds a weakly held observer 17 | fn subscribe + 'static>(&self, observer: &Arc); 18 | 19 | /// Waits indefinitely for an event to be emitted 20 | fn poll(&self) -> T { 21 | let (poller, future) = Poller::new(); 22 | self.subscribe(&poller); 23 | future.get() 24 | } 25 | 26 | /// Waits for an event to be emitted with a timeout 27 | fn poll_timeout(&self, duration: Duration) -> Result { 28 | let (poller, future) = Poller::new(); 29 | self.subscribe(&poller); 30 | match future.get_timeout(duration) { 31 | Ok(t) => Ok(t), 32 | Err(_future) => Err(Error::Timeout), 33 | } 34 | } 35 | } 36 | 37 | /// Stores the observers for a particular event 38 | pub struct Subject { 39 | observers: RwLock>>>, 40 | pending: RwLock>>>, 41 | } 42 | 43 | impl Subject { 44 | /// Creates a new empty set of observers 45 | pub fn new() -> Subject { 46 | Subject { 47 | observers: RwLock::new(Vec::new()), 48 | pending: RwLock::new(Vec::new()), 49 | } 50 | } 51 | } 52 | 53 | impl Observer for Subject { 54 | fn next(&self, event: &T) { 55 | let mut any_to_remove = false; 56 | 57 | { 58 | for observer in self.observers.read().unwrap().iter() { 59 | match observer.upgrade() { 60 | Some(observer) => observer.next(event), 61 | None => any_to_remove = true, 62 | } 63 | } 64 | } 65 | 66 | if any_to_remove { 67 | let mut observers = self.observers.write().unwrap(); 68 | observers.retain(|observer| observer.upgrade().is_some()); 69 | } 70 | 71 | let any_pending = { self.pending.read().unwrap().len() > 0 }; 72 | if any_pending { 73 | let mut observers = self.observers.write().unwrap(); 74 | let mut pending = self.pending.write().unwrap(); 75 | observers.append(&mut pending); 76 | } 77 | } 78 | } 79 | 80 | impl Observable for Subject { 81 | fn subscribe + 'static>(&self, observer: &Arc) { 82 | let weak_observer = Arc::downgrade(observer) as Weak>; 83 | 84 | match self.observers.try_write() { 85 | Ok(mut observers) => observers.push(weak_observer), 86 | 87 | // If we would block, add to a pending set 88 | Err(TryLockError::WouldBlock) => { 89 | self.pending.write().unwrap().push(weak_observer); 90 | } 91 | 92 | // If observer is poisoned, app will be killed soon 93 | Err(TryLockError::Poisoned(_)) => panic!("Observer lock poisoned"), 94 | } 95 | } 96 | } 97 | 98 | /// A subject that only emits a single value 99 | /// 100 | /// After a value is emmitted once, all future calls to next() will be ignored, 101 | /// and any future subscriptions will be called with the original value once. 102 | pub struct Single { 103 | subject: Subject, 104 | value: RwLock>, 105 | } 106 | 107 | impl Single { 108 | /// Creates a new single with an empty set of observers 109 | pub fn new() -> Single { 110 | Single { 111 | subject: Subject::new(), 112 | value: RwLock::new(None), 113 | } 114 | } 115 | } 116 | 117 | impl Observer for Single { 118 | fn next(&self, event: &T) { 119 | let mut value = self.value.write().unwrap(); 120 | if let None = *value { 121 | *value = Some(event.clone()); 122 | self.subject.next(event); 123 | } 124 | } 125 | } 126 | 127 | impl Observable for Single { 128 | fn subscribe + 'static>(&self, observer: &Arc) { 129 | match &*self.value.read().unwrap() { 130 | Some(value) => observer.next(&value), 131 | None => self.subject.subscribe(observer), 132 | } 133 | } 134 | } 135 | 136 | struct Poller { 137 | future_provider: FutureProvider, 138 | } 139 | 140 | impl Poller { 141 | pub fn new() -> (Arc>, Future) { 142 | let (future, future_provider) = Future::new(); 143 | (Arc::new(Poller { future_provider }), future) 144 | } 145 | } 146 | 147 | impl Observer for Poller { 148 | fn next(&self, event: &T) { 149 | self.future_provider.put(event.clone()); 150 | } 151 | } 152 | 153 | #[cfg(test)] 154 | mod tests { 155 | use super::*; 156 | use std::sync::atomic::{AtomicBool, Ordering}; 157 | 158 | #[test] 159 | fn publish_observe() { 160 | struct MyObserver { 161 | observed: AtomicBool, 162 | } 163 | 164 | impl<'a> Observer for MyObserver { 165 | fn next(&self, _event: &u32) { 166 | self.observed.store(true, Ordering::Relaxed); 167 | } 168 | } 169 | 170 | let subject = Subject::::new(); 171 | let observer = Arc::new(MyObserver { 172 | observed: AtomicBool::new(false), 173 | }); 174 | subject.subscribe(&observer); 175 | 176 | assert!(!observer.observed.load(Ordering::Relaxed)); 177 | subject.next(&1); 178 | assert!(observer.observed.load(Ordering::Relaxed)); 179 | } 180 | 181 | #[test] 182 | fn observe_during_next() { 183 | let subject = Arc::new(Subject::::new()); 184 | struct MyObserver { 185 | subject: Arc>, 186 | } 187 | impl<'a> Observer for MyObserver { 188 | fn next(&self, _event: &u32) { 189 | self.subject.subscribe(&Arc::new(MyObserver { 190 | subject: self.subject.clone(), 191 | })); 192 | } 193 | } 194 | subject.subscribe(&Arc::new(MyObserver { 195 | subject: subject.clone(), 196 | })); 197 | subject.next(&1); 198 | } 199 | 200 | #[test] 201 | fn single() { 202 | struct MyObserver { 203 | observed: AtomicBool, 204 | } 205 | 206 | impl<'a> Observer for MyObserver { 207 | fn next(&self, event: &u32) { 208 | assert!(event == &5); 209 | assert!(!self.observed.swap(true, Ordering::Relaxed)); 210 | } 211 | } 212 | 213 | let pre_emit_observer = Arc::new(MyObserver { 214 | observed: AtomicBool::new(false), 215 | }); 216 | 217 | let post_emit_observer = Arc::new(MyObserver { 218 | observed: AtomicBool::new(false), 219 | }); 220 | 221 | let single = Single::::new(); 222 | single.subscribe(&pre_emit_observer); 223 | single.next(&5); 224 | assert!(pre_emit_observer.observed.load(Ordering::Relaxed)); 225 | single.subscribe(&post_emit_observer); 226 | assert!(post_emit_observer.observed.load(Ordering::Relaxed)); 227 | single.next(&6); 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /src/script/stack.rs: -------------------------------------------------------------------------------- 1 | use crate::util::{Error, Result}; 2 | use num_bigint::{BigInt, Sign}; 3 | use num_traits::Zero; 4 | 5 | /// Pops a bool off the stack 6 | #[inline] 7 | pub fn pop_bool(stack: &mut Vec>) -> Result { 8 | if stack.len() == 0 { 9 | let msg = "Cannot pop bool, empty stack".to_string(); 10 | return Err(Error::ScriptError(msg)); 11 | } 12 | let top = stack.pop().unwrap(); 13 | // Bools cannot be popped having more than 32-bits, but may be used in other ways 14 | if top.len() > 4 { 15 | let msg = format!("Cannot pop bool, len too long {}", top.len()); 16 | return Err(Error::ScriptError(msg)); 17 | } 18 | Ok(decode_bool(&top)) 19 | } 20 | 21 | /// Pops a pre-genesis number off the stack 22 | #[inline] 23 | pub fn pop_num(stack: &mut Vec>) -> Result { 24 | if stack.len() == 0 { 25 | let msg = "Cannot pop num, empty stack".to_string(); 26 | return Err(Error::ScriptError(msg)); 27 | } 28 | let top = stack.pop().unwrap(); 29 | // Numbers cannot be popped having more than 4 bytes, but may overflow on the stack to 5 bytes 30 | // after certain operations and may be used as byte vectors. 31 | if top.len() > 4 { 32 | let msg = format!("Cannot pop num, len too long {}", top.len()); 33 | return Err(Error::ScriptError(msg)); 34 | } 35 | Ok(decode_num(&top)? as i32) 36 | } 37 | 38 | /// Pops a bigint number off the stack 39 | #[inline] 40 | pub fn pop_bigint(stack: &mut Vec>) -> Result { 41 | if stack.len() == 0 { 42 | let msg = "Cannot pop bigint, empty stack".to_string(); 43 | return Err(Error::ScriptError(msg)); 44 | } 45 | let mut top = stack.pop().unwrap(); 46 | Ok(decode_bigint(&mut top)) 47 | } 48 | 49 | /// Converts a stack item to a bool 50 | #[inline] 51 | pub fn decode_bool(s: &[u8]) -> bool { 52 | if s.len() == 0 { 53 | return false; 54 | } 55 | for i in 0..s.len() - 1 { 56 | if s[i] != 0 { 57 | return true; 58 | } 59 | } 60 | s[s.len() - 1] & 127 != 0 61 | } 62 | 63 | /// Converts a stack item to a number 64 | #[inline] 65 | pub fn decode_num(s: &[u8]) -> Result { 66 | let mut val = match s.len() { 67 | 0 => return Ok(0), 68 | 1 => (s[0] & 127) as i64, 69 | 2 => (((s[1] & 127) as i64) << 8) + ((s[0] as i64) << 0), 70 | 3 => (((s[2] & 127) as i64) << 16) + ((s[1] as i64) << 8) + ((s[0] as i64) << 0), 71 | 4 => { 72 | (((s[3] & 127) as i64) << 24) 73 | + ((s[2] as i64) << 16) 74 | + ((s[1] as i64) << 8) 75 | + ((s[0] as i64) << 0) 76 | } 77 | _ => { 78 | for i in 4..s.len() - 1 { 79 | if s[i] != 0 { 80 | return Err(Error::ScriptError("Number too big".to_string())); 81 | } 82 | } 83 | if s[s.len() - 1] & 127 != 0 { 84 | return Err(Error::ScriptError("Number too big".to_string())); 85 | } 86 | ((s[3] as i64) << 24) 87 | + ((s[2] as i64) << 16) 88 | + ((s[1] as i64) << 8) 89 | + ((s[0] as i64) << 0) 90 | } 91 | }; 92 | if s[s.len() - 1] & 128 != 0 { 93 | val = 0 - val; 94 | } 95 | Ok(val) 96 | } 97 | 98 | /// Converts a number to a 32-bit stack item 99 | #[inline] 100 | pub fn encode_num(val: i64) -> Result> { 101 | // Range: [-2^31+1, 2^31-1] 102 | if val > 2147483647 || val < -2147483647 { 103 | return Err(Error::ScriptError("Number out of range".to_string())); 104 | } 105 | let (posval, negmask) = if val < 0 { (-val, 128) } else { (val, 0) }; 106 | if posval == 0 { 107 | Ok(vec![]) 108 | } else if posval < 128 { 109 | Ok(vec![(posval as u8) | negmask]) 110 | } else if posval < 32768 { 111 | Ok(vec![(posval >> 0) as u8, ((posval >> 8) as u8) | negmask]) 112 | } else if posval < 8388608 { 113 | Ok(vec![ 114 | (posval >> 0) as u8, 115 | (posval >> 8) as u8, 116 | ((posval >> 16) as u8) | negmask, 117 | ]) 118 | } else { 119 | Ok(vec![ 120 | (posval >> 0) as u8, 121 | (posval >> 8) as u8, 122 | (posval >> 16) as u8, 123 | ((posval >> 24) as u8) | negmask, 124 | ]) 125 | } 126 | } 127 | 128 | /// Converts a stack item to a big int number 129 | #[inline] 130 | pub fn decode_bigint(s: &mut [u8]) -> BigInt { 131 | let len = s.len(); 132 | if s.len() == 0 { 133 | return BigInt::zero(); 134 | } 135 | let mut sign = Sign::Plus; 136 | if s[len - 1] & 0x80 == 0x80 { 137 | sign = Sign::Minus; 138 | } 139 | s[len - 1] &= !0x80; 140 | BigInt::from_bytes_le(sign, &s) 141 | } 142 | 143 | /// Converts a big int number to a stack item 144 | #[inline] 145 | pub fn encode_bigint(val: BigInt) -> Vec { 146 | let mut result = val.to_bytes_le(); 147 | if result.1[result.1.len() - 1] & 0x80 == 0x80 { 148 | result.1.push(match result.0 { 149 | Sign::Plus | Sign::NoSign => 0x00, 150 | Sign::Minus => 0x80, 151 | }); 152 | } else if result.0 == Sign::Minus { 153 | let len = result.1.len(); 154 | result.1[len - 1] |= 0x80; 155 | } 156 | if result.1.len() == 1 && result.1[0] == 0 { 157 | return vec![]; 158 | } 159 | result.1 160 | } 161 | 162 | #[cfg(test)] 163 | mod tests { 164 | use super::*; 165 | 166 | #[test] 167 | fn decode_bool_tests() { 168 | assert!(decode_bool(&[1]) == true); 169 | assert!(decode_bool(&[255, 0, 0, 0]) == true); 170 | assert!(decode_bool(&[0, 0, 0, 129]) == true); 171 | assert!(decode_bool(&[0]) == false); 172 | assert!(decode_bool(&[0, 0, 0, 0]) == false); 173 | assert!(decode_bool(&[0, 0, 0, 128]) == false); 174 | assert!(decode_bool(&[]) == false); 175 | } 176 | 177 | #[test] 178 | fn pop_bool_tests() { 179 | assert!(pop_bool(&mut vec![vec![1]]).unwrap() == true); 180 | assert!(pop_bool(&mut vec![vec![0, 0, 0, 127]]).unwrap() == true); 181 | assert!(pop_bool(&mut vec![vec![0, 0, 0, 127]]).unwrap() == true); 182 | assert!(pop_bool(&mut vec![]).is_err()); 183 | assert!(pop_bool(&mut vec![vec![0, 0, 0, 0, 0]]).is_err()); 184 | assert!(pop_bool(&mut vec![vec![]]).unwrap() == false); 185 | assert!(pop_bool(&mut vec![vec![0]]).unwrap() == false); 186 | assert!(pop_bool(&mut vec![vec![0, 0, 0, 0]]).unwrap() == false); 187 | assert!(pop_bool(&mut vec![vec![0, 0, 0, 128]]).unwrap() == false); 188 | } 189 | 190 | #[test] 191 | fn encode_decode_num_tests() { 192 | // Range checks 193 | assert!(encode_num(2147483647).is_ok()); 194 | assert!(encode_num(-2147483647).is_ok()); 195 | assert!(encode_num(2147483648).is_err()); 196 | assert!(encode_num(-2147483648).is_err()); 197 | // Encode decode 198 | assert!(decode_num(&encode_num(0).unwrap()).unwrap() == 0); 199 | assert!(decode_num(&encode_num(1).unwrap()).unwrap() == 1); 200 | assert!(decode_num(&encode_num(-1).unwrap()).unwrap() == -1); 201 | assert!(decode_num(&encode_num(1111).unwrap()).unwrap() == 1111); 202 | assert!(decode_num(&encode_num(-1111).unwrap()).unwrap() == -1111); 203 | assert!(decode_num(&encode_num(111111).unwrap()).unwrap() == 111111); 204 | assert!(decode_num(&encode_num(-111111).unwrap()).unwrap() == -111111); 205 | assert!(decode_num(&encode_num(2147483647).unwrap()).unwrap() == 2147483647); 206 | assert!(decode_num(&encode_num(-2147483647).unwrap()).unwrap() == -2147483647); 207 | } 208 | 209 | #[test] 210 | fn pop_num_tests() { 211 | assert!(pop_num(&mut vec![vec![]]).unwrap() == 0); 212 | assert!(pop_num(&mut vec![vec![1]]).unwrap() == 1); 213 | assert!(pop_num(&mut vec![vec![129]]).unwrap() == -1); 214 | assert!(pop_num(&mut vec![vec![0, 0, 0, 0]]).unwrap() == 0); 215 | assert!(pop_num(&mut vec![vec![0, 0, 0, 0, 0]]).is_err()); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /src/messages/block.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::{BlockHeader, OutPoint, Payload, Tx, TxOut}; 2 | use crate::network::Network; 3 | use crate::util::{ 4 | sha256d, var_int, Error, Hash256, Result, Serializable, BITCOIN_CASH_FORK_HEIGHT_MAINNET, 5 | BITCOIN_CASH_FORK_HEIGHT_TESTNET, GENESIS_UPGRADE_HEIGHT_MAINNET, 6 | GENESIS_UPGRADE_HEIGHT_TESTNET, 7 | }; 8 | use linked_hash_map::LinkedHashMap; 9 | use std::collections::{HashSet, VecDeque}; 10 | use std::fmt; 11 | use std::io; 12 | use std::io::{Read, Write}; 13 | 14 | /// Block of transactions 15 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 16 | pub struct Block { 17 | /// Block header 18 | pub header: BlockHeader, 19 | /// Block transactions 20 | pub txns: Vec, 21 | } 22 | 23 | impl Block { 24 | /// Returns a set of the inputs spent in this block 25 | pub fn inputs(&self) -> Result> { 26 | let mut inputs = HashSet::new(); 27 | for txn in self.txns.iter() { 28 | if !txn.coinbase() { 29 | for input in txn.inputs.iter() { 30 | if inputs.contains(&input.prev_output) { 31 | let msg = "Input double spent".to_string(); 32 | return Err(Error::BadData(msg)); 33 | } 34 | inputs.insert(input.prev_output.clone()); 35 | } 36 | } 37 | } 38 | Ok(inputs) 39 | } 40 | 41 | /// Returns a map of the new outputs generated from this block including those spent within the block 42 | pub fn outputs(&self) -> Result> { 43 | let mut outputs = LinkedHashMap::new(); 44 | for txn in self.txns.iter() { 45 | let hash = txn.hash(); 46 | for index in 0..txn.outputs.len() as u32 { 47 | outputs.insert( 48 | OutPoint { hash, index }, 49 | txn.outputs[index as usize].clone(), 50 | ); 51 | } 52 | } 53 | Ok(outputs) 54 | } 55 | 56 | /// Checks that the block is valid 57 | pub fn validate( 58 | &self, 59 | height: i32, 60 | network: Network, 61 | utxos: &LinkedHashMap, 62 | pregenesis_outputs: &HashSet, 63 | ) -> Result<()> { 64 | if self.txns.len() == 0 { 65 | return Err(Error::BadData("Txn count is zero".to_string())); 66 | } 67 | 68 | if self.merkle_root() != self.header.merkle_root { 69 | return Err(Error::BadData("Bad merkle root".to_string())); 70 | } 71 | 72 | let mut has_coinbase = false; 73 | let require_sighash_forkid = match network { 74 | Network::Mainnet => height >= BITCOIN_CASH_FORK_HEIGHT_MAINNET, 75 | Network::Testnet => height >= BITCOIN_CASH_FORK_HEIGHT_TESTNET, 76 | Network::STN => true, 77 | }; 78 | let use_genesis_rules = match network { 79 | Network::Mainnet => height >= GENESIS_UPGRADE_HEIGHT_MAINNET, 80 | Network::Testnet => height >= GENESIS_UPGRADE_HEIGHT_TESTNET, 81 | Network::STN => true, 82 | }; 83 | for txn in self.txns.iter() { 84 | if !txn.coinbase() { 85 | txn.validate( 86 | require_sighash_forkid, 87 | use_genesis_rules, 88 | utxos, 89 | pregenesis_outputs, 90 | )?; 91 | } else if has_coinbase { 92 | return Err(Error::BadData("Multiple coinbases".to_string())); 93 | } else { 94 | has_coinbase = true; 95 | } 96 | } 97 | if !has_coinbase { 98 | return Err(Error::BadData("No coinbase".to_string())); 99 | } 100 | 101 | Ok(()) 102 | } 103 | 104 | /// Calculates the merkle root from the transactions 105 | fn merkle_root(&self) -> Hash256 { 106 | let mut row = VecDeque::new(); 107 | for tx in self.txns.iter() { 108 | row.push_back(tx.hash()); 109 | } 110 | while row.len() > 1 { 111 | let mut n = row.len(); 112 | while n > 0 { 113 | n -= 1; 114 | let h1 = row.pop_front().unwrap(); 115 | let h2 = if n == 0 { 116 | h1.clone() 117 | } else { 118 | n -= 1; 119 | row.pop_front().unwrap() 120 | }; 121 | let mut h = Vec::with_capacity(64); 122 | h1.write(&mut h).unwrap(); 123 | h2.write(&mut h).unwrap(); 124 | row.push_back(sha256d(&h)); 125 | } 126 | } 127 | return row.pop_front().unwrap(); 128 | } 129 | } 130 | 131 | impl Serializable for Block { 132 | fn read(reader: &mut dyn Read) -> Result { 133 | let header = BlockHeader::read(reader)?; 134 | let txn_count = var_int::read(reader)?; 135 | let mut txns = Vec::with_capacity(txn_count as usize); 136 | for _i in 0..txn_count { 137 | txns.push(Tx::read(reader)?); 138 | } 139 | Ok(Block { header, txns }) 140 | } 141 | 142 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 143 | self.header.write(writer)?; 144 | var_int::write(self.txns.len() as u64, writer)?; 145 | for txn in self.txns.iter() { 146 | txn.write(writer)?; 147 | } 148 | Ok(()) 149 | } 150 | } 151 | 152 | impl Payload for Block { 153 | fn size(&self) -> usize { 154 | let mut size = BlockHeader::SIZE; 155 | size += var_int::size(self.txns.len() as u64); 156 | for txn in self.txns.iter() { 157 | size += txn.size(); 158 | } 159 | size 160 | } 161 | } 162 | 163 | impl fmt::Debug for Block { 164 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 165 | if self.txns.len() <= 3 { 166 | f.debug_struct("Block") 167 | .field("header", &self.header) 168 | .field("txns", &self.txns) 169 | .finish() 170 | } else { 171 | let txns = format!("[<{} transactions>]", self.txns.len()); 172 | f.debug_struct("Block") 173 | .field("header", &self.header) 174 | .field("txns", &txns) 175 | .finish() 176 | } 177 | } 178 | } 179 | 180 | #[cfg(test)] 181 | mod tests { 182 | use super::*; 183 | use crate::messages::{OutPoint, TxIn, TxOut}; 184 | use crate::script::Script; 185 | use crate::util::Hash256; 186 | use hex; 187 | use std::io::Cursor; 188 | 189 | #[test] 190 | fn read_bytes() { 191 | let b = hex::decode("010000004860eb18bf1b1620e37e9490fc8a427514416fd75159ab86688e9a8300000000d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9bb0bc6649ffff001d08d2bd610101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010bffffffff0100f2052a010000004341047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac00000000").unwrap(); 192 | let block = Block::read(&mut Cursor::new(&b)).unwrap(); 193 | assert!( 194 | block 195 | == Block { 196 | header: BlockHeader { 197 | version: 1, 198 | prev_hash: Hash256::decode( 199 | "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", 200 | ) 201 | .unwrap(), 202 | merkle_root: Hash256::decode( 203 | "9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5", 204 | ) 205 | .unwrap(), 206 | timestamp: 1231469744, 207 | bits: 486604799, 208 | nonce: 1639830024, 209 | }, 210 | txns: vec![Tx { 211 | version: 1, 212 | inputs: vec![TxIn { 213 | prev_output: OutPoint { 214 | hash: Hash256([0; 32]), 215 | index: 4294967295, 216 | }, 217 | unlock_script: Script(vec![4, 255, 255, 0, 29, 1, 11]), 218 | sequence: 4294967295, 219 | }], 220 | outputs: vec![TxOut { 221 | satoshis: 5000000000, 222 | lock_script: Script(vec![ 223 | 65, 4, 114, 17, 168, 36, 245, 91, 80, 82, 40, 228, 195, 213, 25, 224 | 76, 31, 207, 170, 21, 164, 86, 171, 223, 55, 249, 185, 217, 122, 225 | 64, 64, 175, 192, 115, 222, 230, 200, 144, 100, 152, 79, 3, 56, 82, 226 | 55, 217, 33, 103, 193, 62, 35, 100, 70, 180, 23, 171, 121, 160, 227 | 252, 174, 65, 42, 227, 49, 107, 119, 172, 228 | ]), 229 | }], 230 | lock_time: 0, 231 | }], 232 | } 233 | ); 234 | } 235 | 236 | #[test] 237 | fn write_read() { 238 | let mut v = Vec::new(); 239 | let block = Block { 240 | header: BlockHeader { 241 | version: 77, 242 | prev_hash: Hash256::decode( 243 | "abcdabcdabcdabcd1234123412341234abcdabcdabcdabcd1234123412341234", 244 | ) 245 | .unwrap(), 246 | merkle_root: Hash256::decode( 247 | "1234567809876543123456780987654312345678098765431234567809876543", 248 | ) 249 | .unwrap(), 250 | timestamp: 7, 251 | bits: 8, 252 | nonce: 9, 253 | }, 254 | txns: vec![Tx { 255 | version: 7, 256 | inputs: vec![TxIn { 257 | prev_output: OutPoint { 258 | hash: Hash256([7; 32]), 259 | index: 3, 260 | }, 261 | unlock_script: Script(vec![9, 8, 7]), 262 | sequence: 42, 263 | }], 264 | outputs: vec![TxOut { 265 | satoshis: 23, 266 | lock_script: Script(vec![1, 2, 3, 4, 5]), 267 | }], 268 | lock_time: 4, 269 | }], 270 | }; 271 | block.write(&mut v).unwrap(); 272 | assert!(v.len() == block.size()); 273 | assert!(Block::read(&mut Cursor::new(&v)).unwrap() == block); 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /src/transaction/sighash.rs: -------------------------------------------------------------------------------- 1 | //! Transaction sighash helpers 2 | 3 | use crate::messages::{OutPoint, Payload, Tx, TxOut}; 4 | use crate::script::{next_op, op_codes, Script}; 5 | use crate::util::{sha256d, var_int, Error, Hash256, Result, Serializable}; 6 | use byteorder::{LittleEndian, WriteBytesExt}; 7 | use std::io::Write; 8 | 9 | /// Signs all of the outputs 10 | pub const SIGHASH_ALL: u8 = 0x01; 11 | /// Sign none of the outputs so that they may be spent anywhere 12 | pub const SIGHASH_NONE: u8 = 0x02; 13 | /// Sign only the output paired with the the input 14 | pub const SIGHASH_SINGLE: u8 = 0x03; 15 | /// Sign only the input so others may inputs to the transaction 16 | pub const SIGHASH_ANYONECANPAY: u8 = 0x80; 17 | /// Bitcoin Cash / SV sighash flag for use on outputs after the fork 18 | pub const SIGHASH_FORKID: u8 = 0x40; 19 | 20 | /// The 24-bit fork ID for Bitcoin Cash / SV 21 | const FORK_ID: u32 = 0; 22 | 23 | /// Generates a transaction digest for signing 24 | /// 25 | /// This will use either BIP-143 or the legacy algorithm depending on if SIGHASH_FORKID is set. 26 | /// 27 | /// # Arguments 28 | /// 29 | /// * `tx` - Spending transaction 30 | /// * `n_input` - Spending input index 31 | /// * `script_code` - The lock_script of the output being spent. This may be a subset of the 32 | /// lock_script if OP_CODESEPARATOR is used. 33 | /// * `satoshis` - The satoshi amount in the output being spent 34 | /// * `sighash_type` - Sighash flags 35 | /// * `cache` - Cache to store intermediate values for future sighash calls. 36 | pub fn sighash( 37 | tx: &Tx, 38 | n_input: usize, 39 | script_code: &[u8], 40 | satoshis: i64, 41 | sighash_type: u8, 42 | cache: &mut SigHashCache, 43 | ) -> Result { 44 | if sighash_type & SIGHASH_FORKID != 0 { 45 | bip143_sighash(tx, n_input, script_code, satoshis, sighash_type, cache) 46 | } else { 47 | legacy_sighash(tx, n_input, script_code, sighash_type) 48 | } 49 | } 50 | 51 | /// Cache for sighash intermediate values to avoid quadratic hashing 52 | /// 53 | /// This is only valid for one transaction, but may be used for multiple signatures. 54 | pub struct SigHashCache { 55 | hash_prevouts: Option, 56 | hash_sequence: Option, 57 | hash_outputs: Option, 58 | } 59 | 60 | impl SigHashCache { 61 | /// Creates a new cache 62 | pub fn new() -> SigHashCache { 63 | SigHashCache { 64 | hash_prevouts: None, 65 | hash_sequence: None, 66 | hash_outputs: None, 67 | } 68 | } 69 | } 70 | 71 | /// Generates a transaction digest for signing using BIP-143 72 | /// 73 | /// This is to be used for all tranasctions after the August 2017 fork. 74 | /// It fixing quadratic hashing and includes the satoshis spent in the hash. 75 | fn bip143_sighash( 76 | tx: &Tx, 77 | n_input: usize, 78 | script_code: &[u8], 79 | satoshis: i64, 80 | sighash_type: u8, 81 | cache: &mut SigHashCache, 82 | ) -> Result { 83 | if n_input >= tx.inputs.len() { 84 | return Err(Error::BadArgument("input out of tx_in range".to_string())); 85 | } 86 | 87 | let mut s = Vec::with_capacity(tx.size()); 88 | let base_type = sighash_type & 31; 89 | let anyone_can_pay = sighash_type & SIGHASH_ANYONECANPAY != 0; 90 | 91 | // 1. Serialize version 92 | s.write_u32::(tx.version)?; 93 | 94 | // 2. Serialize hash of prevouts 95 | if !anyone_can_pay { 96 | if cache.hash_prevouts.is_none() { 97 | let mut prev_outputs = Vec::with_capacity(OutPoint::SIZE * tx.inputs.len()); 98 | for input in tx.inputs.iter() { 99 | input.prev_output.write(&mut prev_outputs)?; 100 | } 101 | cache.hash_prevouts = Some(sha256d(&prev_outputs)); 102 | } 103 | s.write(&cache.hash_prevouts.unwrap().0)?; 104 | } else { 105 | s.write(&[0; 32])?; 106 | } 107 | 108 | // 3. Serialize hash of sequences 109 | if !anyone_can_pay && base_type != SIGHASH_SINGLE && base_type != SIGHASH_NONE { 110 | if cache.hash_sequence.is_none() { 111 | let mut sequences = Vec::with_capacity(4 * tx.inputs.len()); 112 | for tx_in in tx.inputs.iter() { 113 | sequences.write_u32::(tx_in.sequence)?; 114 | } 115 | cache.hash_sequence = Some(sha256d(&sequences)); 116 | } 117 | s.write(&cache.hash_sequence.unwrap().0)?; 118 | } else { 119 | s.write(&[0; 32])?; 120 | } 121 | 122 | // 4. Serialize prev output 123 | tx.inputs[n_input].prev_output.write(&mut s)?; 124 | 125 | // 5. Serialize input script 126 | var_int::write(script_code.len() as u64, &mut s)?; 127 | s.write(&script_code)?; 128 | 129 | // 6. Serialize satoshis 130 | s.write_i64::(satoshis)?; 131 | 132 | // 7. Serialize sequence 133 | s.write_u32::(tx.inputs[n_input].sequence)?; 134 | 135 | // 8. Serialize hash of outputs 136 | if base_type != SIGHASH_SINGLE && base_type != SIGHASH_NONE { 137 | if cache.hash_outputs.is_none() { 138 | let mut size = 0; 139 | for tx_out in tx.outputs.iter() { 140 | size += tx_out.size(); 141 | } 142 | let mut outputs = Vec::with_capacity(size); 143 | for tx_out in tx.outputs.iter() { 144 | tx_out.write(&mut outputs)?; 145 | } 146 | cache.hash_outputs = Some(sha256d(&outputs)); 147 | } 148 | s.write(&cache.hash_outputs.unwrap().0)?; 149 | } else if base_type == SIGHASH_SINGLE && n_input < tx.outputs.len() { 150 | let mut outputs = Vec::with_capacity(tx.outputs[n_input].size()); 151 | tx.outputs[n_input].write(&mut outputs)?; 152 | s.write(&sha256d(&outputs).0)?; 153 | } else { 154 | s.write(&[0; 32])?; 155 | } 156 | 157 | // 9. Serialize lock_time 158 | s.write_u32::(tx.lock_time)?; 159 | 160 | // 10. Serialize hash type 161 | s.write_u32::((FORK_ID << 8) | sighash_type as u32)?; 162 | 163 | Ok(sha256d(&s)) 164 | } 165 | 166 | /// Generates the transaction digest for signing using the legacy algorithm 167 | /// 168 | /// This is used for all transaction validation before the August 2017 fork. 169 | fn legacy_sighash( 170 | tx: &Tx, 171 | n_input: usize, 172 | script_code: &[u8], 173 | sighash_type: u8, 174 | ) -> Result { 175 | if n_input >= tx.inputs.len() { 176 | return Err(Error::BadArgument("input out of tx_in range".to_string())); 177 | } 178 | 179 | let mut s = Vec::with_capacity(tx.size()); 180 | let base_type = sighash_type & 31; 181 | let anyone_can_pay = sighash_type & SIGHASH_ANYONECANPAY != 0; 182 | 183 | // Remove all instances of OP_CODESEPARATOR from the script_code 184 | let mut sub_script = Vec::with_capacity(script_code.len()); 185 | let mut i = 0; 186 | while i < script_code.len() { 187 | let next = next_op(i, script_code); 188 | if script_code[i] != op_codes::OP_CODESEPARATOR { 189 | sub_script.extend_from_slice(&script_code[i..next]); 190 | } 191 | i = next; 192 | } 193 | 194 | // Serialize the version 195 | s.write_u32::(tx.version)?; 196 | 197 | // Serialize the inputs 198 | let n_inputs = if anyone_can_pay { 1 } else { tx.inputs.len() }; 199 | var_int::write(n_inputs as u64, &mut s)?; 200 | for i in 0..tx.inputs.len() { 201 | let i = if anyone_can_pay { n_input } else { i }; 202 | let mut tx_in = tx.inputs[i].clone(); 203 | if i == n_input { 204 | tx_in.unlock_script = Script(Vec::with_capacity(4 + sub_script.len())); 205 | tx_in.unlock_script.0.extend_from_slice(&sub_script); 206 | } else { 207 | tx_in.unlock_script = Script(vec![]); 208 | if base_type == SIGHASH_NONE || base_type == SIGHASH_SINGLE { 209 | tx_in.sequence = 0; 210 | } 211 | } 212 | tx_in.write(&mut s)?; 213 | if anyone_can_pay { 214 | break; 215 | } 216 | } 217 | 218 | // Serialize the outputs 219 | let tx_out_list = if base_type == SIGHASH_NONE { 220 | vec![] 221 | } else if base_type == SIGHASH_SINGLE { 222 | if n_input >= tx.outputs.len() { 223 | return Err(Error::BadArgument("input out of tx_out range".to_string())); 224 | } 225 | let mut truncated_out = tx.outputs.clone(); 226 | truncated_out.truncate(n_input + 1); 227 | truncated_out 228 | } else { 229 | tx.outputs.clone() 230 | }; 231 | var_int::write(tx_out_list.len() as u64, &mut s)?; 232 | for i in 0..tx_out_list.len() { 233 | if i == n_input && base_type == SIGHASH_SINGLE { 234 | let empty = TxOut { 235 | satoshis: -1, 236 | lock_script: Script(vec![]), 237 | }; 238 | empty.write(&mut s)?; 239 | } else { 240 | tx_out_list[i].write(&mut s)?; 241 | } 242 | } 243 | 244 | // Serialize the lock time 245 | s.write_u32::(tx.lock_time)?; 246 | 247 | // Append the sighash_type and finally double hash the result 248 | s.write_u32::(sighash_type as u32)?; 249 | Ok(sha256d(&s)) 250 | } 251 | 252 | #[cfg(test)] 253 | mod tests { 254 | use super::*; 255 | use crate::address::addr_decode; 256 | use crate::messages::{OutPoint, TxIn}; 257 | use crate::network::Network; 258 | use crate::transaction::p2pkh; 259 | use hex; 260 | 261 | #[test] 262 | fn bip143_sighash_test() { 263 | let lock_script = 264 | hex::decode("76a91402b74813b047606b4b3fbdfb1a6e8e053fdb8dab88ac").unwrap(); 265 | let addr = "mfmKD4cP6Na7T8D87XRSiR7shA1HNGSaec"; 266 | let hash160 = addr_decode(addr, Network::Testnet).unwrap().0; 267 | let tx = Tx { 268 | version: 2, 269 | inputs: vec![TxIn { 270 | prev_output: OutPoint { 271 | hash: Hash256::decode( 272 | "f671dc000ad12795e86b59b27e0c367d9b026bbd4141c227b9285867a53bb6f7", 273 | ) 274 | .unwrap(), 275 | index: 0, 276 | }, 277 | unlock_script: Script(vec![]), 278 | sequence: 0, 279 | }], 280 | outputs: vec![ 281 | TxOut { 282 | satoshis: 100, 283 | lock_script: p2pkh::create_lock_script(&hash160), 284 | }, 285 | TxOut { 286 | satoshis: 259899900, 287 | lock_script: p2pkh::create_lock_script(&hash160), 288 | }, 289 | ], 290 | lock_time: 0, 291 | }; 292 | let mut cache = SigHashCache::new(); 293 | let sighash_type = SIGHASH_ALL | SIGHASH_FORKID; 294 | let sighash = 295 | bip143_sighash(&tx, 0, &lock_script, 260000000, sighash_type, &mut cache).unwrap(); 296 | let expected = "1e2121837829018daf3aeadab76f1a542c49a3600ded7bd74323ee74ce0d840c"; 297 | assert!(sighash.0.to_vec() == hex::decode(expected).unwrap()); 298 | assert!(cache.hash_prevouts.is_some()); 299 | assert!(cache.hash_sequence.is_some()); 300 | assert!(cache.hash_outputs.is_some()); 301 | } 302 | 303 | #[test] 304 | fn legacy_sighash_test() { 305 | let lock_script = 306 | hex::decode("76a914d951eb562f1ff26b6cbe89f04eda365ea6bd95ce88ac").unwrap(); 307 | let tx = Tx { 308 | version: 1, 309 | inputs: vec![TxIn { 310 | prev_output: OutPoint { 311 | hash: Hash256::decode( 312 | "bf6c1139ea01ca054b8d00aa0a088daaeab4f3b8e111626c6be7d603a9dd8dff", 313 | ) 314 | .unwrap(), 315 | index: 0, 316 | }, 317 | unlock_script: Script(vec![]), 318 | sequence: 0xffffffff, 319 | }], 320 | outputs: vec![TxOut { 321 | satoshis: 49990000, 322 | lock_script: Script( 323 | hex::decode("76a9147865b0b301119fc3eadc7f3406ff1339908e46d488ac").unwrap(), 324 | ), 325 | }], 326 | lock_time: 0, 327 | }; 328 | let sighash = legacy_sighash(&tx, 0, &lock_script, SIGHASH_ALL).unwrap(); 329 | let expected = "ad16084eccf26464a84c5ee2f8b96b4daff9a3154ac3c1b320346aed042abe57"; 330 | assert!(sighash.0.to_vec() == hex::decode(expected).unwrap()); 331 | } 332 | } 333 | -------------------------------------------------------------------------------- /src/wallet/mnemonic.rs: -------------------------------------------------------------------------------- 1 | //! Functions to convert data to and from mnemonic words 2 | 3 | use crate::util::{Bits, Error, Result}; 4 | use ring::digest::{digest, SHA256}; 5 | use std::str; 6 | 7 | /// Wordlist language 8 | pub enum Wordlist { 9 | ChineseSimplified, 10 | ChineseTraditional, 11 | English, 12 | French, 13 | Italian, 14 | Japanese, 15 | Korean, 16 | Spanish, 17 | } 18 | 19 | /// Loads the word list for a given language 20 | pub fn load_wordlist(wordlist: Wordlist) -> Vec { 21 | match wordlist { 22 | Wordlist::ChineseSimplified => { 23 | load_wordlist_internal(include_bytes!("wordlists/chinese_simplified.txt")) 24 | } 25 | Wordlist::ChineseTraditional => { 26 | load_wordlist_internal(include_bytes!("wordlists/chinese_traditional.txt")) 27 | } 28 | Wordlist::English => load_wordlist_internal(include_bytes!("wordlists/english.txt")), 29 | Wordlist::French => load_wordlist_internal(include_bytes!("wordlists/french.txt")), 30 | Wordlist::Italian => load_wordlist_internal(include_bytes!("wordlists/italian.txt")), 31 | Wordlist::Japanese => load_wordlist_internal(include_bytes!("wordlists/japanese.txt")), 32 | Wordlist::Korean => load_wordlist_internal(include_bytes!("wordlists/korean.txt")), 33 | Wordlist::Spanish => load_wordlist_internal(include_bytes!("wordlists/spanish.txt")), 34 | } 35 | } 36 | 37 | fn load_wordlist_internal(bytes: &[u8]) -> Vec { 38 | let text: String = str::from_utf8(bytes).unwrap().to_string(); 39 | text.lines().map(|s| s.to_string()).collect() 40 | } 41 | 42 | /// Encodes data into a mnemonic using BIP-39 43 | pub fn mnemonic_encode(data: &[u8], word_list: &[String]) -> Vec { 44 | let hash = digest(&SHA256, &data); 45 | let mut words = Vec::with_capacity((data.len() * 8 + data.len() / 32 + 10) / 11); 46 | let mut bits = Bits::from_slice(data, data.len() * 8); 47 | bits.append(&Bits::from_slice(hash.as_ref(), data.len() / 4)); 48 | for i in 0..bits.len / 11 { 49 | words.push(word_list[bits.extract(i * 11, 11) as usize].clone()); 50 | } 51 | let rem = bits.len % 11; 52 | if rem != 0 { 53 | let n = bits.extract(bits.len / 11 * 11, rem) << (8 - rem); 54 | words.push(word_list[n as usize].clone()); 55 | } 56 | words 57 | } 58 | 59 | /// Decodes a neumonic into data using BIP-39 60 | pub fn mnemonic_decode(mnemonic: &[String], word_list: &[String]) -> Result> { 61 | let mut bits = Bits::with_capacity(mnemonic.len() * 11); 62 | for word in mnemonic { 63 | let value = match word_list.binary_search(word) { 64 | Ok(value) => value, 65 | Err(_) => return Err(Error::BadArgument(format!("Bad word: {}", word))), 66 | }; 67 | let word_bits = Bits::from_slice(&[(value >> 3) as u8, ((value & 7) as u8) << 5], 11); 68 | bits.append(&word_bits); 69 | } 70 | let data_len = bits.len * 32 / 33; 71 | let cs_len = bits.len / 33; 72 | let cs = digest(&SHA256, &bits.data[0..data_len / 8]); 73 | let cs_bits = Bits::from_slice(cs.as_ref(), cs_len); 74 | if cs_bits.extract(0, cs_len) != bits.extract(data_len, cs_len) { 75 | return Err(Error::BadArgument("Invalid checksum".to_string())); 76 | } 77 | Ok(bits.data[0..data_len / 8].to_vec()) 78 | } 79 | 80 | #[cfg(test)] 81 | mod tests { 82 | use super::*; 83 | use hex; 84 | 85 | #[test] 86 | fn wordlists() { 87 | assert!(load_wordlist(Wordlist::ChineseSimplified).len() == 2048); 88 | assert!(load_wordlist(Wordlist::ChineseTraditional).len() == 2048); 89 | assert!(load_wordlist(Wordlist::English).len() == 2048); 90 | assert!(load_wordlist(Wordlist::French).len() == 2048); 91 | assert!(load_wordlist(Wordlist::Italian).len() == 2048); 92 | assert!(load_wordlist(Wordlist::Japanese).len() == 2048); 93 | assert!(load_wordlist(Wordlist::Korean).len() == 2048); 94 | assert!(load_wordlist(Wordlist::Spanish).len() == 2048); 95 | } 96 | 97 | #[test] 98 | fn encode_decode() { 99 | let mut data = Vec::new(); 100 | for i in 0..16 { 101 | data.push(i); 102 | } 103 | let wordlist = load_wordlist(Wordlist::English); 104 | assert!(mnemonic_decode(&mnemonic_encode(&data, &wordlist), &wordlist).unwrap() == data); 105 | } 106 | 107 | #[test] 108 | fn invalid() { 109 | let wordlist = load_wordlist(Wordlist::English); 110 | assert!(mnemonic_encode(&[], &wordlist).len() == 0); 111 | assert!(mnemonic_decode(&[], &wordlist).unwrap().len() == 0); 112 | 113 | let mut data = Vec::new(); 114 | for i in 0..16 { 115 | data.push(i); 116 | } 117 | let mnemonic = mnemonic_encode(&data, &wordlist); 118 | 119 | let mut bad_checksum = mnemonic.clone(); 120 | bad_checksum[0] = "hello".to_string(); 121 | assert!(mnemonic_decode(&bad_checksum, &wordlist).is_err()); 122 | 123 | let mut bad_word = mnemonic.clone(); 124 | bad_word[0] = "123".to_string(); 125 | assert!(mnemonic_decode(&bad_word, &wordlist).is_err()); 126 | } 127 | 128 | #[test] 129 | fn test_vectors() { 130 | let wordlist = load_wordlist(Wordlist::English); 131 | 132 | let h = hex::decode("00000000000000000000000000000000").unwrap(); 133 | let n = mnemonic_encode(&h, &wordlist).join(" "); 134 | assert!(n == "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"); 135 | 136 | let h = hex::decode("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f").unwrap(); 137 | let n = mnemonic_encode(&h, &wordlist).join(" "); 138 | assert!(n == "legal winner thank year wave sausage worth useful legal winner thank yellow"); 139 | 140 | let h = hex::decode("80808080808080808080808080808080").unwrap(); 141 | let n = mnemonic_encode(&h, &wordlist).join(" "); 142 | assert!( 143 | n == "letter advice cage absurd amount doctor acoustic avoid letter advice cage above" 144 | ); 145 | 146 | let h = hex::decode("ffffffffffffffffffffffffffffffff").unwrap(); 147 | let n = mnemonic_encode(&h, &wordlist).join(" "); 148 | assert!(n == "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong"); 149 | 150 | let h = hex::decode("000000000000000000000000000000000000000000000000").unwrap(); 151 | let n = mnemonic_encode(&h, &wordlist).join(" "); 152 | assert!(n == "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent"); 153 | 154 | let h = hex::decode("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f").unwrap(); 155 | let n = mnemonic_encode(&h, &wordlist).join(" "); 156 | assert!(n == "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will"); 157 | 158 | let h = hex::decode("808080808080808080808080808080808080808080808080").unwrap(); 159 | let n = mnemonic_encode(&h, &wordlist).join(" "); 160 | assert!(n == "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always"); 161 | 162 | let h = hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(); 163 | let n = mnemonic_encode(&h, &wordlist).join(" "); 164 | assert!(n == "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when"); 165 | 166 | let h = hex::decode("0000000000000000000000000000000000000000000000000000000000000000") 167 | .unwrap(); 168 | let n = mnemonic_encode(&h, &wordlist).join(" "); 169 | assert!(n == "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art"); 170 | 171 | let h = hex::decode("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f") 172 | .unwrap(); 173 | let n = mnemonic_encode(&h, &wordlist).join(" "); 174 | assert!(n == "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title"); 175 | 176 | let h = hex::decode("8080808080808080808080808080808080808080808080808080808080808080") 177 | .unwrap(); 178 | let n = mnemonic_encode(&h, &wordlist).join(" "); 179 | assert!(n == "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless"); 180 | 181 | let h = hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 182 | .unwrap(); 183 | let n = mnemonic_encode(&h, &wordlist).join(" "); 184 | assert!(n == "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote"); 185 | 186 | let h = hex::decode("9e885d952ad362caeb4efe34a8e91bd2").unwrap(); 187 | let n = mnemonic_encode(&h, &wordlist).join(" "); 188 | assert!( 189 | n == "ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic" 190 | ); 191 | 192 | let h = hex::decode("6610b25967cdcca9d59875f5cb50b0ea75433311869e930b").unwrap(); 193 | let n = mnemonic_encode(&h, &wordlist).join(" "); 194 | assert!(n == "gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog"); 195 | 196 | let h = hex::decode("68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c") 197 | .unwrap(); 198 | let n = mnemonic_encode(&h, &wordlist).join(" "); 199 | assert!(n == "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length"); 200 | 201 | let h = hex::decode("c0ba5a8e914111210f2bd131f3d5e08d").unwrap(); 202 | let n = mnemonic_encode(&h, &wordlist).join(" "); 203 | assert!(n == "scheme spot photo card baby mountain device kick cradle pact join borrow"); 204 | 205 | let h = hex::decode("6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3").unwrap(); 206 | let n = mnemonic_encode(&h, &wordlist).join(" "); 207 | assert!(n == "horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave"); 208 | 209 | let h = hex::decode("9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863") 210 | .unwrap(); 211 | let n = mnemonic_encode(&h, &wordlist).join(" "); 212 | assert!(n == "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside"); 213 | 214 | let h = hex::decode("23db8160a31d3e0dca3688ed941adbf3").unwrap(); 215 | let n = mnemonic_encode(&h, &wordlist).join(" "); 216 | assert!(n == "cat swing flag economy stadium alone churn speed unique patch report train"); 217 | 218 | let h = hex::decode("8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0").unwrap(); 219 | let n = mnemonic_encode(&h, &wordlist).join(" "); 220 | assert!(n == "light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access"); 221 | 222 | let h = hex::decode("066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad") 223 | .unwrap(); 224 | let n = mnemonic_encode(&h, &wordlist).join(" "); 225 | assert!(n == "all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform"); 226 | 227 | let h = hex::decode("f30f8c1da665478f49b001d94c5fc452").unwrap(); 228 | let n = mnemonic_encode(&h, &wordlist).join(" "); 229 | assert!( 230 | n == "vessel ladder alter error federal sibling chat ability sun glass valve picture" 231 | ); 232 | 233 | let h = hex::decode("c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05").unwrap(); 234 | let n = mnemonic_encode(&h, &wordlist).join(" "); 235 | assert!(n == "scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump"); 236 | 237 | let h = hex::decode("f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f") 238 | .unwrap(); 239 | let n = mnemonic_encode(&h, &wordlist).join(" "); 240 | assert!(n == "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold"); 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /src/messages/merkle_block.rs: -------------------------------------------------------------------------------- 1 | use crate::messages::block_header::BlockHeader; 2 | use crate::messages::message::Payload; 3 | use crate::util::{sha256d, var_int, Error, Hash256, Result, Serializable}; 4 | use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; 5 | use hex; 6 | use std::fmt; 7 | use std::io; 8 | use std::io::{Read, Write}; 9 | 10 | /// A block header and partial merkle tree for SPV nodes to validate transactions 11 | #[derive(Default, PartialEq, Eq, Hash, Clone)] 12 | pub struct MerkleBlock { 13 | /// Block header 14 | pub header: BlockHeader, 15 | /// Number of transactions in the block 16 | pub total_transactions: u32, 17 | /// Hashes in depth-first order 18 | pub hashes: Vec, 19 | /// Bit vector used to assign hashes to nodes in the partial merkle tree 20 | pub flags: Vec, 21 | } 22 | 23 | impl MerkleBlock { 24 | /// Validates the merkle block and partial merkle tree and returns the set of matched transactions 25 | pub fn validate(&self) -> Result> { 26 | if self.total_transactions == 0 { 27 | return Err(Error::BadData("No transactions".to_string())); 28 | } 29 | 30 | let mut preorder_node = 0; 31 | let mut flag_bits_used = 0; 32 | let mut hashes_used = 0; 33 | let mut matches = Vec::new(); 34 | let tree_depth = (self.total_transactions as f32).log(2.).ceil() as usize; 35 | let mut row_len = self.total_transactions as usize; 36 | let mut total_nodes = row_len as usize; 37 | while row_len > 1 { 38 | row_len = (row_len + 1) / 2; 39 | total_nodes += row_len; 40 | } 41 | 42 | let merkle_root = self.traverse( 43 | &mut preorder_node, 44 | &mut flag_bits_used, 45 | &mut hashes_used, 46 | 0, 47 | tree_depth, 48 | total_nodes, 49 | &mut matches, 50 | )?; 51 | 52 | if merkle_root != self.header.merkle_root { 53 | return Err(Error::BadData("Merkle root doesn't match".to_string())); 54 | } 55 | 56 | if hashes_used < self.hashes.len() { 57 | return Err(Error::BadData("Not all hashes consumed".to_string())); 58 | } 59 | 60 | if preorder_node < total_nodes { 61 | return Err(Error::BadData("Not all nodes consumed".to_string())); 62 | } 63 | 64 | if (flag_bits_used + 7) / 8 < self.flags.len() { 65 | return Err(Error::BadData("Not all flag bits consumed".to_string())); 66 | } 67 | 68 | Ok(matches) 69 | } 70 | 71 | fn traverse( 72 | &self, 73 | preorder_node: &mut usize, 74 | flag_bits_used: &mut usize, 75 | hashes_used: &mut usize, 76 | depth: usize, 77 | tree_depth: usize, 78 | total_nodes: usize, 79 | matches: &mut Vec, 80 | ) -> Result { 81 | let flag = self.consume_flag(flag_bits_used)?; 82 | if flag == 0 { 83 | *preorder_node += (1 << (tree_depth - depth + 1)) - 1; 84 | let hash = self.consume_hash(hashes_used)?; 85 | Ok(hash) 86 | } else if depth == tree_depth { 87 | *preorder_node += 1; 88 | let hash = self.consume_hash(hashes_used)?; 89 | matches.push(hash.clone()); 90 | Ok(hash) 91 | } else { 92 | *preorder_node += 1; 93 | let left = self.traverse( 94 | preorder_node, 95 | flag_bits_used, 96 | hashes_used, 97 | depth + 1, 98 | tree_depth, 99 | total_nodes, 100 | matches, 101 | )?; 102 | if *preorder_node >= total_nodes { 103 | let mut concat = Vec::with_capacity(64); 104 | concat.extend_from_slice(&left.0); 105 | concat.extend_from_slice(&left.0); 106 | Ok(sha256d(&concat)) 107 | } else { 108 | let right = self.traverse( 109 | preorder_node, 110 | flag_bits_used, 111 | hashes_used, 112 | depth + 1, 113 | tree_depth, 114 | total_nodes, 115 | matches, 116 | )?; 117 | if left == right { 118 | return Err(Error::BadData("Duplicate transactions".to_string())); 119 | } else { 120 | let mut concat = Vec::with_capacity(64); 121 | concat.extend_from_slice(&left.0); 122 | concat.extend_from_slice(&right.0); 123 | Ok(sha256d(&concat)) 124 | } 125 | } 126 | } 127 | } 128 | 129 | fn consume_flag(&self, flag_bits_used: &mut usize) -> Result { 130 | if *flag_bits_used / 8 >= self.flags.len() { 131 | return Err(Error::BadData("Not enough flag bits".to_string())); 132 | } 133 | let flag = (self.flags[*flag_bits_used / 8] >> *flag_bits_used % 8) & 1; 134 | *flag_bits_used += 1; 135 | Ok(flag) 136 | } 137 | 138 | fn consume_hash(&self, hashes_used: &mut usize) -> Result { 139 | if *hashes_used >= self.hashes.len() { 140 | return Err(Error::BadData("Not enough hashes".to_string())); 141 | } 142 | let hash = self.hashes[*hashes_used]; 143 | *hashes_used += 1; 144 | Ok(hash) 145 | } 146 | } 147 | 148 | impl Serializable for MerkleBlock { 149 | fn read(reader: &mut dyn Read) -> Result { 150 | let header = BlockHeader::read(reader)?; 151 | let total_transactions = reader.read_u32::()?; 152 | let num_hashes = var_int::read(reader)?; 153 | let mut hashes = Vec::with_capacity(num_hashes as usize); 154 | for _i in 0..num_hashes { 155 | hashes.push(Hash256::read(reader)?); 156 | } 157 | let flags_len = var_int::read(reader)?; 158 | let mut flags = vec![0; flags_len as usize]; 159 | reader.read(&mut flags)?; 160 | Ok(MerkleBlock { 161 | header, 162 | total_transactions, 163 | hashes, 164 | flags, 165 | }) 166 | } 167 | 168 | fn write(&self, writer: &mut dyn Write) -> io::Result<()> { 169 | self.header.write(writer)?; 170 | writer.write_u32::(self.total_transactions)?; 171 | var_int::write(self.hashes.len() as u64, writer)?; 172 | for hash in self.hashes.iter() { 173 | hash.write(writer)?; 174 | } 175 | var_int::write(self.flags.len() as u64, writer)?; 176 | writer.write(&self.flags)?; 177 | Ok(()) 178 | } 179 | } 180 | 181 | impl Payload for MerkleBlock { 182 | fn size(&self) -> usize { 183 | self.header.size() 184 | + 4 185 | + var_int::size(self.hashes.len() as u64) 186 | + self.hashes.len() * 32 187 | + var_int::size(self.flags.len() as u64) 188 | + self.flags.len() 189 | } 190 | } 191 | 192 | impl fmt::Debug for MerkleBlock { 193 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 194 | f.debug_struct("MerkleBlock") 195 | .field("header", &self.header) 196 | .field("total_transactions", &self.total_transactions) 197 | .field("hashes", &self.hashes) 198 | .field("flags", &hex::encode(&self.flags)) 199 | .finish() 200 | } 201 | } 202 | 203 | #[cfg(test)] 204 | mod tests { 205 | use super::*; 206 | use hex; 207 | use std::io::Cursor; 208 | 209 | #[test] 210 | fn read_bytes() { 211 | let b = hex::decode("0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b852907000000043612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2019f5b01d4195ecbc9398fbf3c3b1fa9bb3183301d7a1fb3bd174fcfa40a2b6541ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d06820d2a7bc994987302e5b1ac80fc425fe25f8b63169ea78e68fbaaefa59379bbf011d".as_bytes()).unwrap(); 212 | let p = MerkleBlock::read(&mut Cursor::new(&b)).unwrap(); 213 | assert!(p.header.version == 1); 214 | let prev_hash = "82bb869cf3a793432a66e826e05a6fc37469f8efb7421dc88067010000000000"; 215 | assert!(p.header.prev_hash.0.to_vec() == hex::decode(prev_hash).unwrap()); 216 | let merkle_root = "7f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d97287"; 217 | assert!(p.header.merkle_root.0.to_vec() == hex::decode(merkle_root).unwrap()); 218 | assert!(p.header.timestamp == 1293629558); 219 | assert!(p.total_transactions == 7); 220 | assert!(p.hashes.len() == 4); 221 | let hash1 = "3612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2"; 222 | assert!(p.hashes[0].0.to_vec() == hex::decode(hash1).unwrap()); 223 | let hash2 = "019f5b01d4195ecbc9398fbf3c3b1fa9bb3183301d7a1fb3bd174fcfa40a2b65"; 224 | assert!(p.hashes[1].0.to_vec() == hex::decode(hash2).unwrap()); 225 | let hash3 = "41ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d068"; 226 | assert!(p.hashes[2].0.to_vec() == hex::decode(hash3).unwrap()); 227 | let hash4 = "20d2a7bc994987302e5b1ac80fc425fe25f8b63169ea78e68fbaaefa59379bbf"; 228 | assert!(p.hashes[3].0.to_vec() == hex::decode(hash4).unwrap()); 229 | assert!(p.flags.len() == 1 && p.flags[0] == 29); 230 | } 231 | 232 | #[test] 233 | fn write_read() { 234 | let mut v = Vec::new(); 235 | let p = MerkleBlock { 236 | header: BlockHeader { 237 | version: 12345, 238 | prev_hash: Hash256::decode( 239 | "7766009988776600998877660099887766009988776600998877660099887766", 240 | ) 241 | .unwrap(), 242 | merkle_root: Hash256::decode( 243 | "2211554433221155443322115544332211554433221155443322115544332211", 244 | ) 245 | .unwrap(), 246 | timestamp: 66, 247 | bits: 4488, 248 | nonce: 9999, 249 | }, 250 | total_transactions: 14, 251 | hashes: vec![Hash256([1; 32]), Hash256([3; 32]), Hash256([5; 32])], 252 | flags: vec![24, 125, 199], 253 | }; 254 | p.write(&mut v).unwrap(); 255 | assert!(v.len() == p.size()); 256 | assert!(MerkleBlock::read(&mut Cursor::new(&v)).unwrap() == p); 257 | } 258 | 259 | #[test] 260 | fn validate() { 261 | // Valid merkle block with 7 transactions 262 | let b = hex::decode("0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b852907000000043612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2019f5b01d4195ecbc9398fbf3c3b1fa9bb3183301d7a1fb3bd174fcfa40a2b6541ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d06820d2a7bc994987302e5b1ac80fc425fe25f8b63169ea78e68fbaaefa59379bbf011d".as_bytes()).unwrap(); 263 | let p = MerkleBlock::read(&mut Cursor::new(&b)).unwrap(); 264 | assert!(p.validate().unwrap().len() == 1); 265 | 266 | // Not enough hashes 267 | let mut p2 = p.clone(); 268 | p2.hashes.truncate(p.hashes.len() - 1); 269 | assert!(p2.validate().is_err()); 270 | 271 | // Too many hashes 272 | let mut p2 = p.clone(); 273 | p2.hashes.push(Hash256([0; 32])); 274 | assert!(p2.validate().is_err()); 275 | 276 | // Not enough flags 277 | let mut p2 = p.clone(); 278 | p2.flags = vec![]; 279 | assert!(p2.validate().is_err()); 280 | 281 | // Too many flags 282 | let mut p2 = p.clone(); 283 | p2.flags.push(0); 284 | assert!(p2.validate().is_err()); 285 | 286 | // Merkle root doesn't match 287 | let mut p2 = p.clone(); 288 | p2.hashes[0] = Hash256([1; 32]); 289 | assert!(p2.validate().is_err()); 290 | } 291 | 292 | #[test] 293 | fn incomplete_tree() { 294 | let hash1 = Hash256([1; 32]); 295 | let hash2 = Hash256([2; 32]); 296 | let hash3 = Hash256([3; 32]); 297 | let hash4 = Hash256([4; 32]); 298 | let right = hash(&hash(&hash2, &hash3), &hash4); 299 | let merkle_root = hash(&hash1, &hash(&right, &right)); 300 | let header = BlockHeader { 301 | version: 12345, 302 | prev_hash: Hash256([0; 32]), 303 | merkle_root, 304 | timestamp: 66, 305 | bits: 4488, 306 | nonce: 9999, 307 | }; 308 | let merkle_block = MerkleBlock { 309 | header, 310 | total_transactions: 11, 311 | hashes: vec![hash1, hash2, hash3, hash4], 312 | flags: vec![0x5d], 313 | }; 314 | assert!(merkle_block.validate().is_ok()); 315 | } 316 | 317 | fn hash(a: &Hash256, b: &Hash256) -> Hash256 { 318 | let mut v = Vec::with_capacity(64); 319 | v.write(&a.0).unwrap(); 320 | v.write(&b.0).unwrap(); 321 | sha256d(&v) 322 | } 323 | } 324 | -------------------------------------------------------------------------------- /src/script/mod.rs: -------------------------------------------------------------------------------- 1 | //! Script opcodes and interpreter 2 | //! 3 | //! # Examples 4 | //! 5 | //! Evaluate a script that divides two numbers: 6 | //! 7 | //! ```rust 8 | //! use sv::script::op_codes::*; 9 | //! use sv::script::{Script, TransactionlessChecker, NO_FLAGS}; 10 | //! 11 | //! let mut script = Script::new(); 12 | //! script.append(OP_10); 13 | //! script.append(OP_5); 14 | //! script.append(OP_DIV); 15 | //! 16 | //! script.eval(&mut TransactionlessChecker {}, NO_FLAGS).unwrap(); 17 | //! ``` 18 | 19 | use crate::script::op_codes::*; 20 | use crate::util::Result; 21 | use hex; 22 | use std::fmt; 23 | 24 | mod checker; 25 | mod interpreter; 26 | #[allow(dead_code)] 27 | pub mod op_codes; 28 | mod stack; 29 | 30 | pub use self::checker::{Checker, TransactionChecker, TransactionlessChecker}; 31 | pub(crate) use self::interpreter::next_op; 32 | pub use self::interpreter::{NO_FLAGS, PREGENESIS_RULES}; 33 | 34 | /// Transaction script 35 | #[derive(Default, Clone, PartialEq, Eq, Hash)] 36 | pub struct Script(pub Vec); 37 | 38 | impl Script { 39 | /// Creates a new empty script 40 | pub fn new() -> Script { 41 | Script(vec![]) 42 | } 43 | 44 | /// Appends a single opcode or data byte 45 | pub fn append(&mut self, byte: u8) { 46 | self.0.push(byte); 47 | } 48 | 49 | /// Appends a slice of data 50 | pub fn append_slice(&mut self, slice: &[u8]) { 51 | self.0.extend_from_slice(slice); 52 | } 53 | 54 | /// Appends the opcodes and provided data that push it onto the stack 55 | pub fn append_data(&mut self, data: &[u8]) { 56 | let len = data.len(); 57 | match len { 58 | 0 => self.0.push(op_codes::OP_0), 59 | 1..=75 => { 60 | self.0.push(op_codes::OP_PUSH + len as u8); 61 | self.0.extend_from_slice(data); 62 | } 63 | 76..=255 => { 64 | self.0.push(op_codes::OP_PUSHDATA1); 65 | self.0.push(len as u8); 66 | self.0.extend_from_slice(data); 67 | } 68 | 256..=65535 => { 69 | self.0.push(op_codes::OP_PUSHDATA2); 70 | self.0.push((len >> 0) as u8); 71 | self.0.push((len >> 8) as u8); 72 | self.0.extend_from_slice(data); 73 | } 74 | _ => { 75 | self.0.push(op_codes::OP_PUSHDATA4); 76 | self.0.push((len >> 0) as u8); 77 | self.0.push((len >> 8) as u8); 78 | self.0.push((len >> 16) as u8); 79 | self.0.push((len >> 24) as u8); 80 | self.0.extend_from_slice(data); 81 | } 82 | } 83 | } 84 | 85 | /// Appends the opcodes to push a number to the stack 86 | /// 87 | /// The number must be in the range [2^-31+1,2^31-1]. 88 | pub fn append_num(&mut self, n: i32) -> Result<()> { 89 | self.append_data(&stack::encode_num(n as i64)?); 90 | Ok(()) 91 | } 92 | 93 | /// Evaluates a script using the provided checker 94 | pub fn eval(&self, checker: &mut T, flags: u32) -> Result<()> { 95 | self::interpreter::eval(&self.0, checker, flags) 96 | } 97 | } 98 | 99 | impl fmt::Debug for Script { 100 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 101 | let script = &self.0; 102 | let mut ret = String::new(); 103 | let mut i = 0; 104 | ret.push_str("["); 105 | while i < script.len() { 106 | if i != 0 { 107 | ret.push_str(" ") 108 | } 109 | match script[i] { 110 | OP_0 => ret.push_str("OP_0"), 111 | OP_1NEGATE => ret.push_str("OP_1NEGATE"), 112 | OP_1 => ret.push_str("OP_1"), 113 | OP_2 => ret.push_str("OP_2"), 114 | OP_3 => ret.push_str("OP_3"), 115 | OP_4 => ret.push_str("OP_4"), 116 | OP_5 => ret.push_str("OP_5"), 117 | OP_6 => ret.push_str("OP_6"), 118 | OP_7 => ret.push_str("OP_7"), 119 | OP_8 => ret.push_str("OP_8"), 120 | OP_9 => ret.push_str("OP_9"), 121 | OP_10 => ret.push_str("OP_10"), 122 | OP_11 => ret.push_str("OP_11"), 123 | OP_12 => ret.push_str("OP_12"), 124 | OP_13 => ret.push_str("OP_13"), 125 | OP_14 => ret.push_str("OP_14"), 126 | OP_15 => ret.push_str("OP_15"), 127 | OP_16 => ret.push_str("OP_16"), 128 | len @ 1..=75 => { 129 | ret.push_str(&format!("OP_PUSH+{} ", len)); 130 | if i + 1 + len as usize <= script.len() { 131 | ret.push_str(&hex::encode(&script[i + 1..i + 1 + len as usize])); 132 | } else { 133 | break; 134 | } 135 | } 136 | OP_PUSHDATA1 => { 137 | ret.push_str("OP_PUSHDATA1 "); 138 | if i + 2 <= script.len() { 139 | let len = script[i + 1] as usize; 140 | ret.push_str(&format!("{} ", len)); 141 | if i + 2 + len <= script.len() { 142 | ret.push_str(&hex::encode(&script[i + 2..i + 2 + len])); 143 | } else { 144 | break; 145 | } 146 | } else { 147 | break; 148 | } 149 | } 150 | OP_PUSHDATA2 => { 151 | ret.push_str("OP_PUSHDATA2 "); 152 | if i + 3 <= script.len() { 153 | let len = ((script[i + 1] as usize) << 0) + ((script[i + 2] as usize) << 8); 154 | ret.push_str(&format!("{} ", len)); 155 | if i + 3 + len <= script.len() { 156 | ret.push_str(&hex::encode(&script[i + 3..i + 3 + len])); 157 | } else { 158 | break; 159 | } 160 | } else { 161 | break; 162 | } 163 | } 164 | OP_PUSHDATA4 => { 165 | ret.push_str("OP_PUSHDATA4 "); 166 | if i + 5 <= script.len() { 167 | let len = ((script[i + 1] as usize) << 0) 168 | + ((script[i + 2] as usize) << 8) 169 | + ((script[i + 3] as usize) << 16) 170 | + ((script[i + 4] as usize) << 24); 171 | ret.push_str(&format!("{} ", len)); 172 | if i + 5 + len <= script.len() { 173 | ret.push_str(&hex::encode(&script[i..i + len])); 174 | } else { 175 | break; 176 | } 177 | } else { 178 | break; 179 | } 180 | } 181 | OP_NOP => ret.push_str("OP_NOP"), 182 | OP_IF => ret.push_str("OP_IF"), 183 | OP_NOTIF => ret.push_str("OP_NOTIF"), 184 | OP_ELSE => ret.push_str("OP_ELSE"), 185 | OP_ENDIF => ret.push_str("OP_ENDIF"), 186 | OP_VERIFY => ret.push_str("OP_VERIFY"), 187 | OP_RETURN => ret.push_str("OP_RETURN"), 188 | OP_TOALTSTACK => ret.push_str("OP_TOALTSTACK"), 189 | OP_FROMALTSTACK => ret.push_str("OP_FROMALTSTACK"), 190 | OP_IFDUP => ret.push_str("OP_IFDUP"), 191 | OP_DEPTH => ret.push_str("OP_DEPTH"), 192 | OP_DROP => ret.push_str("OP_DROP"), 193 | OP_DUP => ret.push_str("OP_DUP"), 194 | OP_NIP => ret.push_str("OP_NIP"), 195 | OP_OVER => ret.push_str("OP_OVER"), 196 | OP_PICK => ret.push_str("OP_PICK"), 197 | OP_ROLL => ret.push_str("OP_ROLL"), 198 | OP_ROT => ret.push_str("OP_ROT"), 199 | OP_SWAP => ret.push_str("OP_SWAP"), 200 | OP_TUCK => ret.push_str("OP_TUCK"), 201 | OP_2DROP => ret.push_str("OP_2DROP"), 202 | OP_2DUP => ret.push_str("OP_2DUP"), 203 | OP_3DUP => ret.push_str("OP_3DUP"), 204 | OP_2OVER => ret.push_str("OP_2OVER"), 205 | OP_2ROT => ret.push_str("OP_2ROT"), 206 | OP_2SWAP => ret.push_str("OP_2SWAP"), 207 | OP_CAT => ret.push_str("OP_CAT"), 208 | OP_SPLIT => ret.push_str("OP_SPLIT"), 209 | OP_SIZE => ret.push_str("OP_SIZE"), 210 | OP_AND => ret.push_str("OP_AND"), 211 | OP_OR => ret.push_str("OP_OR"), 212 | OP_XOR => ret.push_str("OP_XOR"), 213 | OP_EQUAL => ret.push_str("OP_EQUAL"), 214 | OP_EQUALVERIFY => ret.push_str("OP_EQUALVERIFY"), 215 | OP_1ADD => ret.push_str("OP_1ADD"), 216 | OP_1SUB => ret.push_str("OP_1SUB"), 217 | OP_NEGATE => ret.push_str("OP_NEGATE"), 218 | OP_ABS => ret.push_str("OP_ABS"), 219 | OP_NOT => ret.push_str("OP_NOT"), 220 | OP_0NOTEQUAL => ret.push_str("OP_0NOTEQUAL"), 221 | OP_ADD => ret.push_str("OP_ADD"), 222 | OP_SUB => ret.push_str("OP_SUB"), 223 | OP_DIV => ret.push_str("OP_DIV"), 224 | OP_MOD => ret.push_str("OP_MOD"), 225 | OP_BOOLAND => ret.push_str("OP_BOOLAND"), 226 | OP_BOOLOR => ret.push_str("OP_BOOLOR"), 227 | OP_NUMEQUAL => ret.push_str("OP_NUMEQUAL"), 228 | OP_NUMEQUALVERIFY => ret.push_str("OP_NUMEQUALVERIFY"), 229 | OP_NUMNOTEQUAL => ret.push_str("OP_NUMNOTEQUAL"), 230 | OP_LESSTHAN => ret.push_str("OP_LESSTHAN"), 231 | OP_GREATERTHAN => ret.push_str("OP_GREATERTHAN"), 232 | OP_LESSTHANOREQUAL => ret.push_str("OP_LESSTHANOREQUAL"), 233 | OP_GREATERTHANOREQUAL => ret.push_str("OP_GREATERTHANOREQUAL"), 234 | OP_MIN => ret.push_str("OP_MIN"), 235 | OP_MAX => ret.push_str("OP_MAX"), 236 | OP_WITHIN => ret.push_str("OP_WITHIN"), 237 | OP_NUM2BIN => ret.push_str("OP_NUM2BIN"), 238 | OP_BIN2NUM => ret.push_str("OP_BIN2NUM"), 239 | OP_RIPEMD160 => ret.push_str("OP_RIPEMD160"), 240 | OP_SHA1 => ret.push_str("OP_SHA1"), 241 | OP_SHA256 => ret.push_str("OP_SHA256"), 242 | OP_HASH160 => ret.push_str("OP_HASH160"), 243 | OP_HASH256 => ret.push_str("OP_HASH256"), 244 | OP_CODESEPARATOR => ret.push_str("OP_CODESEPARATOR"), 245 | OP_CHECKSIG => ret.push_str("OP_CHECKSIG"), 246 | OP_CHECKSIGVERIFY => ret.push_str("OP_CHECKSIGVERIFY"), 247 | OP_CHECKMULTISIG => ret.push_str("OP_CHECKMULTISIG"), 248 | OP_CHECKMULTISIGVERIFY => ret.push_str("OP_CHECKMULTISIGVERIFY"), 249 | OP_CHECKLOCKTIMEVERIFY => ret.push_str("OP_CHECKLOCKTIMEVERIFY"), 250 | OP_CHECKSEQUENCEVERIFY => ret.push_str("OP_CHECKSEQUENCEVERIFY"), 251 | _ => ret.push_str(&format!("{}", script[i])), 252 | } 253 | i = next_op(i, script); 254 | } 255 | 256 | // Add whatever is remaining if we exited early 257 | if i < script.len() { 258 | for j in i..script.len() { 259 | ret.push_str(&format!(" {}", script[j])); 260 | } 261 | } 262 | ret.push_str("]"); 263 | f.write_str(&ret) 264 | } 265 | } 266 | 267 | #[cfg(test)] 268 | mod tests { 269 | use super::op_codes::*; 270 | use super::*; 271 | 272 | #[test] 273 | fn append_data() { 274 | let mut s = Script::new(); 275 | s.append_data(&vec![]); 276 | assert!(s.0.len() == 1); 277 | 278 | let mut s = Script::new(); 279 | s.append_data(&vec![0; 1]); 280 | assert!(s.0[0] == OP_PUSH + 1 && s.0.len() == 2); 281 | 282 | let mut s = Script::new(); 283 | s.append_data(&vec![0; 75]); 284 | assert!(s.0[0] == OP_PUSH + 75 && s.0.len() == 76); 285 | 286 | let mut s = Script::new(); 287 | s.append_data(&vec![0; 76]); 288 | assert!(s.0[0] == OP_PUSHDATA1 && s.0[1] == 76 && s.0.len() == 78); 289 | 290 | let mut s = Script::new(); 291 | s.append_data(&vec![0; 255]); 292 | assert!(s.0[0] == OP_PUSHDATA1 && s.0[1] == 255 && s.0.len() == 257); 293 | 294 | let mut s = Script::new(); 295 | s.append_data(&vec![0; 256]); 296 | assert!(s.0[0] == OP_PUSHDATA2 && s.0[1] == 0 && s.0[2] == 1 && s.0.len() == 259); 297 | 298 | let mut s = Script::new(); 299 | s.append_data(&vec![0; 65535]); 300 | assert!(s.0[0] == OP_PUSHDATA2 && s.0[1] == 255 && s.0[2] == 255 && s.0.len() == 65538); 301 | 302 | let mut s = Script::new(); 303 | s.append_data(&vec![0; 65536]); 304 | assert!(s.0[0] == OP_PUSHDATA4 && s.0[1] == 0 && s.0[2] == 0 && s.0[3] == 1); 305 | assert!(s.0.len() == 65541); 306 | } 307 | } 308 | --------------------------------------------------------------------------------