diff --git a/.travis.yml b/.travis.yml index 7fabfa7..85ae2a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ addons: rust: # Feel free to bump this version if you need features of newer Rust. # Sync with badge in README.md - - 1.31.0 + - 1.33.0 matrix: allow_failures: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c0d7ca..ac1b5d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## 0.11.0 - 2018-03-15 + +### Internal improvements + +- Updated to the `Rust-bitcoin 0.17` release. (#142) +- Crate has been updated to Rust 2018 edition. This means that it is required + to use Rust 1.31 or newer for compilation. (#142) + ## 0.10.0 - 2018-12-14 ### Internal improvements diff --git a/Cargo.toml b/Cargo.toml index 8736859..7ad9c02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "exonum-btc-anchoring" -version = "0.10.0" +edition = "2018" +version = "0.11.0" authors = ["The Exonum Team "] homepage = "https://exonum.com/doc/advanced/bitcoin-anchoring/" repository = "https://github.com/exonum/exonum-btc-anchoring" @@ -15,24 +16,25 @@ description = "An Exonum service that provides anchoring to Bitcoin blockchain." travis-ci = { repository = "exonum/exonum-btc-anchoring" } [dependencies] -bitcoin = { version = "0.15", features = ["serde"] } -btc-transaction-utils = "0.4" -byteorder = "1.2" +bitcoin = { version = "0.17", features = ["serde"] } +bitcoin_hashes = { version = "0.3", features = ["serde"] } +btc-transaction-utils = "0.5" +byteorder = "1.3" clap = "2.32" -derive_more = "0.13" -exonum = "0.10.0" +derive_more = "0.14" +exonum = "0.11.0" exonum_bitcoinrpc = "0.6" -exonum-derive = "0.10.0" -exonum-testkit = "0.10.0" +exonum-derive = "0.11.0" +exonum-testkit = "0.11.0" failure = "0.1" failure_derive = "0.1" hex = "0.3" log = "0.4" maplit = "1.0" matches = "0.1" -protobuf = { version = "2.2", features = ["with-serde"] } +protobuf = { version = "2.4", features = ["with-serde"] } rand = "0.4" -secp256k1 = { version = "0.11", features = ["serde"] } +secp256k1 = { version = "0.12", features = ["serde"] } serde = "1.0" serde_derive = "1.0" serde_json = "1.0" @@ -41,10 +43,9 @@ structopt = "0.2" toml = "0.4" [dev-dependencies] -exonum-configuration = "0.10.0" +exonum-configuration = "0.11.0" libc = "0.2" -pretty_assertions = "0.5" -proptest = "0.8" +proptest = "0.9" [build-dependencies] -exonum-build = "0.10.0" +exonum-build = "0.11.0" diff --git a/README.md b/README.md index 59f1fb1..58c5a7b 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,9 @@ btc_anchoring generate-template template.toml \ Each node generates its own public and secret node configuration files. ```bash -btc_anchoring generate-config template.toml pub/0.toml sec/0.toml \ +btc_anchoring generate-config template.toml 0/pub.toml 0/sec.toml \ + --consensus-path 0/.keys/consensus.toml + --service-path 0/.keys/service.toml --peer-address 127.0.0.0:7000 \ --btc-anchoring-rpc-host http://localhost:18332 \ --btc-anchoring-rpc-user user \ diff --git a/exonum-dictionary.txt b/exonum-dictionary.txt index 32d61ae..53cbe9f 100644 --- a/exonum-dictionary.txt +++ b/exonum-dictionary.txt @@ -135,8 +135,8 @@ precommits prevote prevotes println -privkey -Privkey +PrivateKey +PrivateKey proptest proto protobuf diff --git a/src/api.rs b/src/api.rs index 13a05dd..fc4a1c2 100644 --- a/src/api.rs +++ b/src/api.rs @@ -21,15 +21,16 @@ use exonum::helpers::Height; use exonum::storage::{ListProof, MapProof}; use failure::Fail; +use serde_derive::{Deserialize, Serialize}; use std::cmp::{ self, Ordering::{self, Equal, Greater, Less}, }; -use blockchain::BtcAnchoringSchema; -use btc; -use BTC_ANCHORING_SERVICE_ID; +use crate::blockchain::BtcAnchoringSchema; +use crate::btc; +use crate::BTC_ANCHORING_SERVICE_ID; /// Query parameters for the find transaction request. #[derive(Debug, Clone, Copy, Serialize, Deserialize)] diff --git a/src/blockchain/data_layout/input_signatures.rs b/src/blockchain/data_layout/input_signatures.rs index c6b4ddd..8a94073 100644 --- a/src/blockchain/data_layout/input_signatures.rs +++ b/src/blockchain/data_layout/input_signatures.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; - use exonum::crypto::{self, CryptoHash, Hash}; use exonum::helpers::ValidatorId; use exonum::storage::StorageValue; +use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; +use serde_derive::{Deserialize, Serialize}; + use std::borrow::Cow; use std::io::{Cursor, Write}; use std::iter::{FilterMap, IntoIterator}; diff --git a/src/blockchain/errors.rs b/src/blockchain/errors.rs index 1b3ca32..87af840 100644 --- a/src/blockchain/errors.rs +++ b/src/blockchain/errors.rs @@ -14,11 +14,14 @@ //! Error types of the BTC anchoring service. -use btc; use exonum::blockchain::ExecutionError; use exonum::crypto::Hash; use exonum::helpers::ValidatorId; +use failure_derive::Fail; + +use crate::btc; + /// Possible errors during execution of the `Signature` transaction. #[derive(Debug, Fail)] pub enum SignatureError { diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index f826dbd..143218f 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -23,8 +23,8 @@ use bitcoin::blockdata::script::Script; use btc_transaction_utils::multisig::RedeemScript; use btc_transaction_utils::p2wsh; -use btc::Address; -use config::GlobalConfig; +use crate::btc::Address; +use crate::config::GlobalConfig; pub mod data_layout; pub mod errors; diff --git a/src/blockchain/schema.rs b/src/blockchain/schema.rs index d9bf743..92d1155 100644 --- a/src/blockchain/schema.rs +++ b/src/blockchain/schema.rs @@ -20,11 +20,12 @@ use exonum::helpers::Height; use exonum::storage::{Fork, ProofListIndex, ProofMapIndex, Snapshot}; use btc_transaction_utils::multisig::RedeemScript; +use log::{error, trace}; use serde_json; -use btc::{BtcAnchoringTransactionBuilder, BuilderError, Transaction}; -use config::GlobalConfig; -use BTC_ANCHORING_SERVICE_NAME; +use crate::btc::{BtcAnchoringTransactionBuilder, BuilderError, Transaction}; +use crate::config::GlobalConfig; +use crate::BTC_ANCHORING_SERVICE_NAME; use super::data_layout::*; use super::BtcAnchoringState; diff --git a/src/blockchain/transactions.rs b/src/blockchain/transactions.rs index 251962a..d97fdc0 100644 --- a/src/blockchain/transactions.rs +++ b/src/blockchain/transactions.rs @@ -18,15 +18,18 @@ use exonum::{ blockchain::{ExecutionResult, Transaction, TransactionContext}, helpers::ValidatorId, }; +use exonum_derive::{ProtobufConvert, TransactionSet}; use btc_transaction_utils::{p2wsh::InputSigner, InputSignature, TxInRef}; -use secp256k1::Secp256k1; +use log::{info, trace}; +use serde_derive::{Deserialize, Serialize}; + +use crate::btc; +use crate::proto; use super::data_layout::TxInputId; use super::errors::SignatureError; use super::BtcAnchoringSchema; -use btc; -use proto; /// Exonum message with the signature for the new anchoring transaction. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, ProtobufConvert)] @@ -102,7 +105,6 @@ impl Transaction for TxSignature { }; let input_signer = InputSigner::new(redeem_script.clone()); - let context = Secp256k1::without_caps(); // Checks signature content. let input_signature_ref = self.input_signature.as_ref(); @@ -145,7 +147,7 @@ impl Transaction for TxSignature { &mut tx.0.input[index], input_signatures .into_iter() - .map(|bytes| InputSignature::from_bytes(&context, bytes).unwrap()), + .map(|bytes| InputSignature::from_bytes(bytes).unwrap()), ); } diff --git a/src/btc/macros.rs b/src/btc/macros.rs index 6adab53..1661bef 100644 --- a/src/btc/macros.rs +++ b/src/btc/macros.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[macro_export] macro_rules! impl_wrapper_for_bitcoin_type { ($name:ident) => { impl_wrapper_for_bitcoin_consensus_encoding! { $name } @@ -21,7 +20,6 @@ macro_rules! impl_wrapper_for_bitcoin_type { }; } -#[macro_export] macro_rules! impl_wrapper_for_bitcoin_consensus_encoding { ($name:ident) => { impl ::exonum::storage::StorageValue for $name { @@ -66,7 +64,6 @@ macro_rules! impl_wrapper_for_bitcoin_consensus_encoding { }; } -#[macro_export] macro_rules! impl_string_conversions_for_hex { ($name:ident) => { impl ::std::fmt::LowerHex for $name { @@ -95,7 +92,6 @@ macro_rules! impl_string_conversions_for_hex { }; } -#[macro_export] macro_rules! impl_serde_str { ($name:ident) => { impl ::serde::Serialize for $name { diff --git a/src/btc/mod.rs b/src/btc/mod.rs index 7f69c72..14b6371 100644 --- a/src/btc/mod.rs +++ b/src/btc/mod.rs @@ -19,27 +19,28 @@ pub use self::transaction::{BtcAnchoringTransactionBuilder, BuilderError, Transa use bitcoin::network::constants::Network; use bitcoin::util::address; -use bitcoin::util::privkey; use btc_transaction_utils; +use derive_more::{From, Into}; use hex::{self, FromHex, ToHex}; -use rand::{self, Rng}; -use secp256k1; +use rand::Rng; use std::ops::Deref; #[macro_use] mod macros; +pub use btc_transaction_utils::test_data::{secp_gen_keypair, secp_gen_keypair_with_rng}; + pub(crate) mod payload; pub(crate) mod transaction; /// Bitcoin ECDSA private key wrapper. #[derive(Clone, From, Into, PartialEq, Eq)] -pub struct Privkey(pub privkey::Privkey); +pub struct PrivateKey(pub bitcoin::PrivateKey); /// Secp256k1 public key wrapper, used for verification of signatures. #[derive(Debug, Clone, Copy, From, Into, PartialEq, Eq)] -pub struct PublicKey(pub secp256k1::PublicKey); +pub struct PublicKey(pub bitcoin::PublicKey); /// Bitcoin address wrapper. #[derive(Debug, Clone, From, Into, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -49,23 +50,23 @@ pub struct Address(pub address::Address); #[derive(Debug, Clone, PartialEq, Into, From)] pub struct InputSignature(pub btc_transaction_utils::InputSignature); -impl ToString for Privkey { +impl ToString for PrivateKey { fn to_string(&self) -> String { self.0.to_string() } } -impl ::std::str::FromStr for Privkey { - type Err = ::Err; +impl ::std::str::FromStr for PrivateKey { + type Err = ::Err; fn from_str(s: &str) -> Result { - privkey::Privkey::from_str(s).map(From::from) + bitcoin::PrivateKey::from_str(s).map(From::from) } } -impl ::std::fmt::Debug for Privkey { +impl ::std::fmt::Debug for PrivateKey { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - f.debug_struct("Privkey").finish() + f.debug_struct("PrivateKey").finish() } } @@ -74,21 +75,22 @@ impl FromHex for PublicKey { fn from_hex>(hex: T) -> Result { let bytes = hex::decode(hex)?; - let context = secp256k1::Secp256k1::without_caps(); - let inner = secp256k1::PublicKey::from_slice(&context, &bytes)?; + let inner = bitcoin::PublicKey::from_slice(&bytes)?; Ok(PublicKey(inner)) } } impl ToHex for PublicKey { fn write_hex(&self, w: &mut W) -> ::std::fmt::Result { - let bytes = self.0.serialize(); - bytes.as_ref().write_hex(w) + let mut bytes = Vec::default(); + self.0.write_into(&mut bytes); + bytes.write_hex(w) } fn write_hex_upper(&self, w: &mut W) -> ::std::fmt::Result { - let bytes = self.0.serialize(); - bytes.as_ref().write_hex_upper(w) + let mut bytes = Vec::default(); + self.0.write_into(&mut bytes); + bytes.write_hex_upper(w) } } @@ -120,8 +122,7 @@ impl FromHex for InputSignature { fn from_hex>(hex: T) -> Result { let bytes = hex::decode(hex)?; - let context = secp256k1::Secp256k1::without_caps(); - let inner = btc_transaction_utils::InputSignature::from_bytes(&context, bytes)?; + let inner = btc_transaction_utils::InputSignature::from_bytes(bytes)?; Ok(InputSignature(inner)) } } @@ -151,25 +152,21 @@ impl From for Vec { impl_string_conversions_for_hex! { PublicKey } impl_string_conversions_for_hex! { InputSignature } -impl_serde_str! { Privkey } +impl_serde_str! { PrivateKey } impl_serde_str! { PublicKey } impl_serde_str! { Address } impl_serde_str! { InputSignature } /// Generates public and secret keys for Bitcoin node /// using given random number generator. -pub fn gen_keypair_with_rng(network: Network, rng: &mut R) -> (PublicKey, Privkey) { - let context = secp256k1::Secp256k1::new(); - let sk = secp256k1::key::SecretKey::new(&context, rng); - - let priv_key = privkey::Privkey::from_secret_key(sk, true, network); - let pub_key = secp256k1::PublicKey::from_secret_key(&context, &sk); - (pub_key.into(), priv_key.into()) +pub fn gen_keypair_with_rng(rng: &mut R, network: Network) -> (PublicKey, PrivateKey) { + let (pk, sk) = secp_gen_keypair_with_rng(rng, network); + (PublicKey(pk), PrivateKey(sk)) } /// Same as [`gen_keypair_with_rng`](fn.gen_keypair_with_rng.html) /// but it uses default random number generator. -pub fn gen_keypair(network: Network) -> (PublicKey, Privkey) { - let mut rng = rand::thread_rng(); - gen_keypair_with_rng(network, &mut rng) +pub fn gen_keypair(network: Network) -> (PublicKey, PrivateKey) { + let (pk, sk) = secp_gen_keypair(network); + (PublicKey(pk), PrivateKey(sk)) } diff --git a/src/btc/payload.rs b/src/btc/payload.rs index 37248f4..e92a8be 100644 --- a/src/btc/payload.rs +++ b/src/btc/payload.rs @@ -15,9 +15,10 @@ use exonum::crypto::Hash; use exonum::helpers::Height; -use bitcoin::blockdata::opcodes::All; +use bitcoin::blockdata::opcodes::all::OP_RETURN; use bitcoin::blockdata::script::{Builder, Instruction, Script}; use byteorder::{ByteOrder, LittleEndian}; +use serde_derive::{Deserialize, Serialize}; const PAYLOAD_PREFIX: &[u8] = b"EXONUM"; const PAYLOAD_HEADER_LEN: usize = 8; @@ -136,7 +137,7 @@ impl PayloadV1 { self.write(&mut buf[7..]); // Build script Builder::new() - .push_opcode(All::OP_RETURN) + .push_opcode(OP_RETURN) .push_slice(buf.as_ref()) .into_script() } @@ -185,7 +186,7 @@ impl Payload { instructions .next() .and_then(|instr| { - if instr == Instruction::Op(All::OP_RETURN) { + if instr == Instruction::Op(OP_RETURN) { instructions.next() } else { None diff --git a/src/btc/transaction.rs b/src/btc/transaction.rs index 255ae1e..6876806 100644 --- a/src/btc/transaction.rs +++ b/src/btc/transaction.rs @@ -13,6 +13,8 @@ use exonum::helpers::Height; use bitcoin::blockdata::script::Script; use bitcoin::blockdata::transaction::{self, OutPoint, TxIn, TxOut}; use btc_transaction_utils::multisig::RedeemScript; +use derive_more::{From, Into}; +use failure_derive::Fail; use super::{payload::PayloadBuilder, Payload}; @@ -246,22 +248,25 @@ impl BtcAnchoringTransactionBuilder { #[cfg(test)] mod tests { - use std::borrow::Cow; + use exonum::crypto::CryptoHash; + use exonum::crypto::Hash; + use exonum::helpers::Height; + use exonum::storage::StorageValue; - use bitcoin::blockdata::opcodes::All; + use bitcoin::blockdata::opcodes::all::OP_RETURN; use bitcoin::blockdata::script::{Builder, Script}; use bitcoin::blockdata::transaction::{self, OutPoint, TxIn, TxOut}; use bitcoin::network::constants::Network; use bitcoin::util::address::Address; - use bitcoin::util::hash::Sha256dHash; - use btc::PublicKey; + use bitcoin_hashes::{sha256d::Hash as Sha256dHash, Hash as BitcoinHash}; use btc_transaction_utils::multisig::RedeemScriptBuilder; use hex::FromHex; + use matches::assert_matches; + use proptest::proptest; - use exonum::crypto::CryptoHash; - use exonum::crypto::Hash; - use exonum::helpers::Height; - use exonum::storage::StorageValue; + use std::borrow::Cow; + + use crate::btc::PublicKey; use super::{BtcAnchoringTransactionBuilder, BuilderError, Transaction}; @@ -335,8 +340,8 @@ mod tests { value in 1u64..1_000_000_000, ref s in "\\PC*") { let input = (0..input_num).map(|_| { - // just random hash - let txid = Sha256dHash::from_data(s.as_bytes()); + // Just a random hash + let txid = Sha256dHash::hash(s.as_bytes()); TxIn { previous_output: OutPoint { txid, @@ -352,7 +357,7 @@ mod tests { TxOut { value, script_pubkey: Builder::new() - .push_opcode(All::OP_RETURN) + .push_opcode(OP_RETURN) .push_slice(s.as_bytes()) .into_script(), } diff --git a/src/config.rs b/src/config.rs index 04a36db..3500701 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,11 +19,12 @@ use exonum::helpers::Height; use bitcoin::network::constants::Network; use btc_transaction_utils::multisig::{RedeemScript, RedeemScriptBuilder, RedeemScriptError}; use btc_transaction_utils::p2wsh; +use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; -use btc::{Address, Privkey, PublicKey, Transaction}; -use rpc::BitcoinRpcConfig; +use crate::btc::{Address, PrivateKey, PublicKey, Transaction}; +use crate::rpc::BitcoinRpcConfig; /// Returns sufficient number of keys for the given validators number. pub fn byzantine_quorum(total: usize) -> usize { @@ -109,7 +110,7 @@ pub struct LocalConfig { pub rpc: Option, /// Set of private keys for each anchoring address. #[serde(with = "flatten_keypairs")] - pub private_keys: HashMap, + pub private_keys: HashMap, } /// BTC anchoring configuration. @@ -122,7 +123,9 @@ pub struct Config { } mod flatten_keypairs { - use btc::{Address, Privkey}; + use crate::btc::{Address, PrivateKey}; + + use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; @@ -133,11 +136,11 @@ mod flatten_keypairs { /// Bitcoin address. address: Address, /// Corresponding private key. - private_key: Privkey, + private_key: PrivateKey, } pub fn serialize( - keys: &HashMap, + keys: &HashMap, ser: S, ) -> ::std::result::Result where @@ -155,7 +158,7 @@ mod flatten_keypairs { keypairs.serialize(ser) } - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: ::serde::Deserializer<'de>, { @@ -177,12 +180,12 @@ mod tests { use btc_transaction_utils::test_data::secp_gen_keypair; use super::{GlobalConfig, LocalConfig}; - use rpc::BitcoinRpcConfig; + use crate::rpc::BitcoinRpcConfig; #[test] fn test_global_config() { let public_keys = (0..4) - .map(|_| secp_gen_keypair().0.into()) + .map(|_| secp_gen_keypair(Network::Bitcoin).0.into()) .collect::>(); let config = GlobalConfig::with_public_keys(Network::Bitcoin, public_keys).unwrap(); @@ -218,7 +221,7 @@ mod tests { #[test] fn test_global_config_anchoring_height() { let public_keys = (0..4) - .map(|_| secp_gen_keypair().0.into()) + .map(|_| secp_gen_keypair(Network::Bitcoin).0.into()) .collect::>(); let mut config = GlobalConfig::with_public_keys(Network::Bitcoin, public_keys).unwrap(); diff --git a/src/factory/args.rs b/src/factory/args.rs index 2d5c74e..d39db06 100644 --- a/src/factory/args.rs +++ b/src/factory/args.rs @@ -14,10 +14,11 @@ use exonum::helpers::fabric::{Argument, Context}; -use failure; +use failure::format_err; use hex::{FromHex, FromHexError}; use serde::de::DeserializeOwned; use serde::Serialize; +use serde_derive::{Deserialize, Serialize}; use toml; use std::collections::BTreeMap; diff --git a/src/factory/mod.rs b/src/factory/mod.rs index abc7f94..268edb5 100644 --- a/src/factory/mod.rs +++ b/src/factory/mod.rs @@ -20,18 +20,21 @@ use exonum::helpers::fabric::{ use exonum::node::NodeConfig; use bitcoin::network::constants::Network; -use failure; +use failure::{ensure, format_err}; +use log::info; use toml; -use {BtcAnchoringService, BTC_ANCHORING_SERVICE_NAME}; use std::collections::{BTreeMap, HashMap}; +use std::path::PathBuf; +use std::sync::{Arc, RwLock}; + +use crate::btc::{gen_keypair, PrivateKey, PublicKey}; +use crate::config::{Config, GlobalConfig, LocalConfig}; +use crate::rpc::{BitcoinRpcClient, BitcoinRpcConfig, BtcRelay}; +use crate::{BtcAnchoringService, BTC_ANCHORING_SERVICE_NAME}; use self::args::{Hash, NamedArgumentOptional, NamedArgumentRequired, TypedArgument}; -use btc::{gen_keypair, Privkey, PublicKey}; -use config::{Config, GlobalConfig, LocalConfig}; -use rpc::{BitcoinRpcClient, BitcoinRpcConfig, BtcRelay}; -use std::sync::{Arc, RwLock}; mod args; const BTC_ANCHORING_NETWORK: NamedArgumentRequired = NamedArgumentRequired { @@ -209,7 +212,7 @@ impl CommandExtension for Finalize { } fn execute(&self, mut context: Context) -> Result { - let mut node_config: NodeConfig = context.get(keys::NODE_CONFIG)?; + let mut node_config: NodeConfig = context.get(keys::NODE_CONFIG)?; let public_config_list = context.get(keys::PUBLIC_CONFIG_LIST)?; let services_secret_config: BTreeMap = context .get(keys::SERVICES_SECRET_CONFIGS) @@ -224,7 +227,7 @@ impl CommandExtension for Finalize { BTC_ANCHORING_UTXO_CONFIRMATIONS.output_value(&common_config.services_config)?; // Private part. - let private_key: Privkey = services_secret_config + let private_key: PrivateKey = services_secret_config .get("btc_anchoring_private_key") .ok_or_else(|| format_err!("BTC private key not found"))? .clone() diff --git a/src/handler.rs b/src/handler.rs index 5840668..54bece0 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -17,29 +17,30 @@ use exonum::helpers::ValidatorId; use btc_transaction_utils::p2wsh; use btc_transaction_utils::TxInRef; -use failure; +use failure::format_err; +use log::trace; use std::cmp; use std::collections::HashMap; -use blockchain::data_layout::TxInputId; -use blockchain::transactions::TxSignature; -use blockchain::{BtcAnchoringSchema, BtcAnchoringState}; -use btc::{Address, Privkey}; -use rpc::BtcRelay; +use crate::blockchain::data_layout::TxInputId; +use crate::blockchain::transactions::TxSignature; +use crate::blockchain::{BtcAnchoringSchema, BtcAnchoringState}; +use crate::btc::{Address, PrivateKey}; +use crate::rpc::BtcRelay; /// The goal of this task is to create anchoring transactions for the corresponding heights. pub struct UpdateAnchoringChainTask<'a> { context: &'a ServiceContext, anchoring_state: BtcAnchoringState, - private_keys: &'a HashMap, + private_keys: &'a HashMap, } impl<'a> UpdateAnchoringChainTask<'a> { /// Creates the anchoring chain updater for the given context and private keys. pub fn new( context: &'a ServiceContext, - private_keys: &'a HashMap, + private_keys: &'a HashMap, ) -> UpdateAnchoringChainTask<'a> { UpdateAnchoringChainTask { context, @@ -54,12 +55,12 @@ impl<'a> UpdateAnchoringChainTask<'a> { if let Some(validator_id) = self.context.validator_id() { let address = self.anchoring_state.output_address(); - let privkey = self + let private_key = self .private_keys .get(&address) .ok_or_else(|| format_err!("Private key for the address {} is absent.", address))?; - self.handle_as_validator(validator_id, &privkey) + self.handle_as_validator(validator_id, &private_key) } else { self.handle_as_auditor() } @@ -68,7 +69,7 @@ impl<'a> UpdateAnchoringChainTask<'a> { fn handle_as_validator( self, validator_id: ValidatorId, - privkey: &Privkey, + private_key: &PrivateKey, ) -> Result<(), failure::Error> { let schema = BtcAnchoringSchema::new(self.context.snapshot()); let latest_anchored_height = schema.latest_anchored_height(); @@ -111,7 +112,7 @@ impl<'a> UpdateAnchoringChainTask<'a> { let signature = signer.sign_input( TxInRef::new(proposal.as_ref(), index), proposal_inputs[index].as_ref(), - privkey.0.secret_key(), + &private_key.0.key, )?; signer diff --git a/src/lib.rs b/src/lib.rs index 8c3af39..4fa7977 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,60 +62,25 @@ bare_trait_objects )] -#[macro_use] -extern crate derive_more; -#[macro_use] -extern crate exonum_derive; -#[macro_use] -extern crate failure; -#[macro_use] -extern crate failure_derive; -#[macro_use] -extern crate log; -#[macro_use] -extern crate serde_derive; -#[macro_use] -extern crate serde_json; -#[macro_use] -extern crate maplit; +use log::{error, warn}; -#[cfg(test)] -#[macro_use] -extern crate matches; -#[cfg(test)] -#[macro_use] -extern crate proptest; - -extern crate bitcoin; -extern crate btc_transaction_utils; -extern crate byteorder; -extern crate exonum; -extern crate exonum_bitcoinrpc as bitcoin_rpc; -extern crate hex; -extern crate protobuf; -extern crate rand; -extern crate secp256k1; -extern crate serde; -extern crate serde_str; -extern crate toml; - -extern crate exonum_testkit; +mod handler; +mod proto; -pub use factory::BtcAnchoringFactory as ServiceFactory; -pub use service::{BtcAnchoringService, BTC_ANCHORING_SERVICE_ID, BTC_ANCHORING_SERVICE_NAME}; +pub use crate::factory::BtcAnchoringFactory as ServiceFactory; +pub use crate::service::{ + BtcAnchoringService, BTC_ANCHORING_SERVICE_ID, BTC_ANCHORING_SERVICE_NAME, +}; pub mod api; pub mod blockchain; pub mod btc; pub mod config; -pub(crate) mod factory; pub mod rpc; -pub(crate) mod service; - pub mod test_helpers; -mod handler; -mod proto; +pub(crate) mod factory; +pub(crate) mod service; pub(crate) trait ResultEx { fn log_error(self); diff --git a/src/proto/mod.rs b/src/proto/mod.rs index 1ffdcd0..82c05c4 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -23,11 +23,10 @@ pub use self::btc_anchoring::TxSignature; use bitcoin; use btc_transaction_utils; use failure; -use secp256k1::Secp256k1; use exonum::proto::ProtobufConvert; -use btc; +use crate::btc; include!(concat!(env!("OUT_DIR"), "/protobuf_mod.rs")); @@ -58,9 +57,8 @@ impl ProtobufConvert for btc::InputSignature { fn from_pb(pb: Self::ProtoStruct) -> Result { let bytes = pb.get_data().to_vec(); - let context = Secp256k1::without_caps(); Ok(btc::InputSignature( - btc_transaction_utils::InputSignature::from_bytes(&context, bytes)?, + btc_transaction_utils::InputSignature::from_bytes(bytes)?, )) } } diff --git a/src/rpc.rs b/src/rpc.rs index 62ff0ff..28d01ed 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -17,11 +17,12 @@ use exonum::crypto::Hash; use bitcoin::util::address::Address; -use bitcoin_rpc; +use exonum_bitcoinrpc as bitcoin_rpc; use failure; use hex::FromHex; +use serde_derive::{Deserialize, Serialize}; -use btc::Transaction; +use crate::btc::Transaction; /// Short information about bitcoin transaction. #[derive(Debug, Clone, PartialEq)] diff --git a/src/service.rs b/src/service.rs index c28b0e2..985b499 100644 --- a/src/service.rs +++ b/src/service.rs @@ -20,27 +20,26 @@ use exonum::crypto::Hash; use exonum::messages::RawTransaction; use exonum::storage::{Fork, Snapshot}; -use failure; -use serde_json; +use serde_json::json; use std::sync::{Arc, RwLock}; use std::collections::HashMap; -use api; -use blockchain::{BtcAnchoringSchema, Transactions}; -use btc::{Address, Privkey}; -use config::GlobalConfig; -use handler::{SyncWithBtcRelayTask, UpdateAnchoringChainTask}; -use rpc::BtcRelay; -use ResultEx; +use crate::api; +use crate::blockchain::{BtcAnchoringSchema, Transactions}; +use crate::btc::{Address, PrivateKey}; +use crate::config::GlobalConfig; +use crate::handler::{SyncWithBtcRelayTask, UpdateAnchoringChainTask}; +use crate::rpc::BtcRelay; +use crate::ResultEx; /// Anchoring service id. pub const BTC_ANCHORING_SERVICE_ID: u16 = 3; /// Anchoring service name. pub const BTC_ANCHORING_SERVICE_NAME: &str = "btc_anchoring"; /// Set of bitcoin private keys for corresponding anchoring addresses. -pub(crate) type KeyPool = Arc>>; +pub(crate) type KeyPool = Arc>>; /// Btc anchoring service implementation for the Exonum blockchain. pub struct BtcAnchoringService { diff --git a/src/test_helpers/rpc.rs b/src/test_helpers/rpc.rs index ad7be5c..d4c7f54 100644 --- a/src/test_helpers/rpc.rs +++ b/src/test_helpers/rpc.rs @@ -14,17 +14,19 @@ //! Helpers for the bitcoin rpc testing. -use bitcoin::util::address::Address; - -use std::collections::VecDeque; - use exonum::crypto::Hash; -use btc; +use bitcoin::util::address::Address; use failure; +use log::trace; + +use std::collections::VecDeque; use std::sync::{Arc, Mutex}; -use rpc::{BitcoinRpcConfig, BtcRelay, TransactionInfo as BtcTransactionInfo}; +use crate::{ + btc, + rpc::{BitcoinRpcConfig, BtcRelay, TransactionInfo as BtcTransactionInfo}, +}; const UNEXPECTED_RESPONSE: &str = "Unexpected response. Error in test data."; diff --git a/src/test_helpers/testkit.rs b/src/test_helpers/testkit.rs index 2dd7faa..cc1bb7e 100644 --- a/src/test_helpers/testkit.rs +++ b/src/test_helpers/testkit.rs @@ -15,9 +15,12 @@ //! Helpers collection to test the service with the testkit. use bitcoin::{self, network::constants::Network, util::address::Address}; +use bitcoin_hashes::{sha256d::Hash as Sha256dHash, Hash as BitcoinHash}; use btc_transaction_utils::{multisig::RedeemScript, p2wsh, TxInRef}; -use failure; +use failure::{ensure, format_err}; use hex::FromHex; +use log::trace; +use maplit::hashmap; use rand::{thread_rng, Rng, SeedableRng, StdRng}; use exonum::api; @@ -34,7 +37,7 @@ use std::ops::{Deref, DerefMut}; use std::str::FromStr; use std::sync::{Arc, RwLock}; -use { +use crate::{ api::{BlockHeaderProof, FindTransactionQuery, HeightQuery, PublicApi, TransactionProof}, blockchain::{transactions::TxSignature, BtcAnchoringSchema, BtcAnchoringState}, btc, @@ -58,7 +61,7 @@ pub fn create_fake_funding_transaction(address: &bitcoin::Address, value: u64) - input: vec![bitcoin::TxIn { previous_output: bitcoin::OutPoint { vout: 0, - txid: ::bitcoin::util::hash::Sha256dHash::from_data(&data), + txid: Sha256dHash::from_slice(&data).unwrap(), }, script_sig: bitcoin::Script::new(), sequence: 0, @@ -83,7 +86,7 @@ pub fn gen_anchoring_config( ) -> (GlobalConfig, Vec) { let count = count as usize; let (public_keys, private_keys): (Vec<_>, Vec<_>) = (0..count) - .map(|_| btc::gen_keypair_with_rng(network, rng)) + .map(|_| btc::gen_keypair_with_rng(rng, network)) .unzip(); let mut global = GlobalConfig { @@ -344,14 +347,15 @@ impl AnchoringTestKit { let (proposal, proposal_inputs) = p?; let address = schema.actual_state().output_address(); - let privkey = &self.node_configs[validator_id.0 as usize].private_keys[&address]; + let btc_private_key = + &self.node_configs[validator_id.0 as usize].private_keys[&address]; for (index, proposal_input) in proposal_inputs.iter().enumerate() { let signature = signer .sign_input( TxInRef::new(proposal.as_ref(), index), proposal_input.as_ref(), - privkey.0.secret_key(), + &btc_private_key.0.key, ) .unwrap(); diff --git a/tests/api.rs b/tests/api.rs index 513f93f..5274ba1 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -11,14 +11,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate bitcoin; -extern crate btc_transaction_utils; -extern crate exonum; -extern crate exonum_bitcoinrpc as bitcoin_rpc; -extern crate exonum_btc_anchoring; -extern crate exonum_testkit; -extern crate serde_json; - use exonum::{helpers::Height, storage::Snapshot}; use exonum_btc_anchoring::{ api::{FindTransactionQuery, HeightQuery, PublicApi}, diff --git a/tests/sync.rs b/tests/sync.rs index 29d9535..93414d0 100644 --- a/tests/sync.rs +++ b/tests/sync.rs @@ -11,21 +11,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate bitcoin; -extern crate btc_transaction_utils; -extern crate hex; -extern crate rand; -extern crate serde_json; - -extern crate exonum; -extern crate exonum_bitcoinrpc as bitcoin_rpc; -extern crate exonum_btc_anchoring; -extern crate exonum_testkit; - use hex::FromHex; use exonum::crypto::Hash; use exonum::helpers::Height; +use exonum_bitcoinrpc as bitcoin_rpc; use exonum_btc_anchoring::blockchain::BtcAnchoringSchema; use exonum_btc_anchoring::btc::Transaction; use exonum_btc_anchoring::rpc::TransactionInfo as BtcTransactionInfo; diff --git a/tests/testnet_tests.rs b/tests/testnet_tests.rs index 4172435..0823350 100644 --- a/tests/testnet_tests.rs +++ b/tests/testnet_tests.rs @@ -12,21 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate bitcoin; -extern crate exonum; - -extern crate exonum_bitcoinrpc as bitcoin_rpc; - -extern crate exonum_btc_anchoring; -extern crate exonum_testkit; - -extern crate serde_json; - -#[macro_use] -extern crate matches; - -extern crate btc_transaction_utils; - use exonum::blockchain::TransactionErrorType; use exonum::explorer::BlockWithTransactions; use exonum::helpers::Height; @@ -38,6 +23,8 @@ use exonum_btc_anchoring::{ BTC_ANCHORING_SERVICE_NAME, }; +use matches::assert_matches; + fn assert_tx_error(block: BlockWithTransactions, e: ErrorCode) { assert_eq!( block[0].status().unwrap_err().error_type(),