diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7904627a6..000000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: rust -rust: - - stable - - beta - - nightly - - 1.22.0 - -script: - - cargo generate-lockfile --verbose - - cargo update -p cc --precise "1.0.41" --verbose - - cargo build --verbose - - cargo test --verbose - diff --git a/build.rs b/build.rs index 7ed5091eb..ccfbcfd95 100644 --- a/build.rs +++ b/build.rs @@ -24,7 +24,8 @@ fn main() { .cpp(true) .include("depend/bitcoin/src") .include("depend/bitcoin/src/secp256k1/include") - .define("__STDC_FORMAT_MACROS", None); + .define("__STDC_FORMAT_MACROS", None) + .flag_if_supported("-Wno-implicit-fallthrough"); // **Secp256k1** if !cfg!(feature = "external-secp") { diff --git a/src/lib.rs b/src/lib.rs index 60cec4155..d3c7385ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,64 +11,13 @@ //! //! And that is exactly what this library is, the Rust bindings to `bitcoinconsensus`. //! -//! [`bitcoin/doc/shared-libraries`]: +//! [`bitcoin/doc/shared-libraries.md`]: mod types; use core::fmt; -use crate::types::*; - -/// Errors returned by [`libbitcoinconsensus`]. -/// -/// The error variant identifiers mimic those from `libbitcoinconsensus`. -/// -/// [`libbitcoinconsensus`]: -#[allow(non_camel_case_types)] -#[derive(Debug)] -#[repr(C)] -pub enum Error { - /// Default value, passed to `libbitcoinconsensus` as a return parameter. - ERR_SCRIPT = 0, - /// An invalid index for `txTo`. - ERR_TX_INDEX, - /// `txToLen` did not match with the size of `txTo`. - ERR_TX_SIZE_MISMATCH, - /// An error deserializing `txTo`. - ERR_TX_DESERIALIZE, - /// Input amount is required if WITNESS is used. - ERR_AMOUNT_REQUIRED, - /// Script verification `flags` are invalid (i.e. not part of the libconsensus interface). - ERR_INVALID_FLAGS, -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - - let s = match *self { - ERR_SCRIPT => "error value was not set (value still 0)", - ERR_TX_INDEX => "an invalid index for txTo", - ERR_TX_SIZE_MISMATCH => "txToLen did not match with the size of txTo", - ERR_TX_DESERIALIZE => "an error deserializing txTo", - ERR_AMOUNT_REQUIRED => "input amount is required if WITNESS is used", - ERR_INVALID_FLAGS => "script verification flags are invalid", - }; - f.write_str(s) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; - - match *self { - ERR_SCRIPT | ERR_TX_INDEX | ERR_TX_SIZE_MISMATCH | ERR_TX_DESERIALIZE - | ERR_AMOUNT_REQUIRED | ERR_INVALID_FLAGS => None, - } - } -} +use crate::types::c_uint; /// Do not enable any verification. pub const VERIFY_NONE: c_uint = 0; @@ -92,24 +41,6 @@ pub const VERIFY_ALL: c_uint = VERIFY_P2SH | VERIFY_CHECKSEQUENCEVERIFY | VERIFY_WITNESS; -extern "C" { - /// Returns `libbitcoinconsensus` version. - pub fn bitcoinconsensus_version() -> c_int; - - /// Verifies that the transaction input correctly spends the previous - /// output, considering any additional constraints specified by flags. - pub fn bitcoinconsensus_verify_script_with_amount( - script_pubkey: *const c_uchar, - script_pubkeylen: c_uint, - amount: u64, - tx_to: *const c_uchar, - tx_tolen: c_uint, - n_in: c_uint, - flags: c_uint, - err: *mut Error, - ) -> c_int; -} - /// Computes flags for soft fork activation heights on the Bitcoin network. pub fn height_to_flags(height: u32) -> u32 { let mut flag = VERIFY_NONE; @@ -134,7 +65,7 @@ pub fn height_to_flags(height: u32) -> u32 { } /// Returns `libbitcoinconsensus` version. -pub fn version() -> u32 { unsafe { bitcoinconsensus_version() as u32 } } +pub fn version() -> u32 { unsafe { ffi::bitcoinconsensus_version() as u32 } } /// Verifies a single spend (input) of a Bitcoin transaction. /// @@ -142,38 +73,33 @@ pub fn version() -> u32 { unsafe { bitcoinconsensus_version() as u32 } } /// /// # Arguments /// -/// * spend_output_script: A Bitcoin transaction output script to be spent, serialized in Bitcoin's on wire format. -/// * amount: The spent output amount in satoshis. -/// * spending_transaction: The spending Bitcoin transaction, serialized in Bitcoin's on wire format. -/// * input_index: The index of the input within spending_transaction. +/// * `spend_output`: A Bitcoin transaction output script to be spent, serialized in Bitcoin's on wire format. +/// * `amount`: The spent output amount in satoshis. +/// * `spending_transaction`: The spending Bitcoin transaction, serialized in Bitcoin's on wire format. +/// * `input_index`: The index of the input within spending_transaction. /// /// # Examples /// -/// The (randomly choosen) Bitcoin transaction [aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d](https://blockchain.info/tx/aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d) +/// The (randomly choosen) Bitcoin transaction +/// +/// `aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d` +/// /// spends one input, that is the first output of -/// [95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f](https://blockchain.info/tx/95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f) -/// with a value of 630482530 satoshis. /// -/// The spending transaction in wire format is: +/// `95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f` /// -/// ` -/// spending = 02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700 -/// ` +/// The spending transaction serialized is: /// -/// The script of the first output of the spent transaction is: +/// `spending = 02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700` /// -/// ` -/// spent = 76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ac -/// ` +/// The script of the first output of the spent transaction is: /// -/// The (pseudo code) call: +/// `spent = 76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ac` /// -/// ` -/// verify(spent, 630482530, spending, 0) -/// ` -/// should return `Ok(())`. +/// The (pseudo code) call: `verify(spent, 630482530, spending, 0)` should return `Ok(())`. /// -/// **Note** since the spent amount will only be checked for Segwit transactions and the above example is not segwit, `verify` will succeed with any amount. +/// **Note** since the spent amount will only be checked for Segwit transactions and the above +/// example is not segwit, `verify` will succeed with any amount. pub fn verify( spent_output: &[u8], amount: u64, @@ -194,7 +120,7 @@ pub fn verify_with_flags( unsafe { let mut error = Error::ERR_SCRIPT; - let ret = bitcoinconsensus_verify_script_with_amount( + let ret = ffi::bitcoinconsensus_verify_script_with_amount( spent_output_script.as_ptr(), spent_output_script.len() as c_uint, amount, @@ -212,6 +138,80 @@ pub fn verify_with_flags( } } +pub mod ffi { + use crate::types::{c_int, c_uchar, c_uint}; + use crate::Error; + + extern "C" { + /// Returns `libbitcoinconsensus` version. + pub fn bitcoinconsensus_version() -> c_int; + + /// Verifies that the transaction input correctly spends the previous + /// output, considering any additional constraints specified by flags. + pub fn bitcoinconsensus_verify_script_with_amount( + script_pubkey: *const c_uchar, + script_pubkeylen: c_uint, + amount: u64, + tx_to: *const c_uchar, + tx_tolen: c_uint, + n_in: c_uint, + flags: c_uint, + err: *mut Error, + ) -> c_int; + } +} + +/// Errors returned by [`libbitcoinconsensus`]. +/// +/// The error variant identifiers mimic those from `libbitcoinconsensus`. +/// +/// [`libbitcoinconsensus`]: +#[allow(non_camel_case_types)] +#[derive(Debug)] +#[repr(C)] +pub enum Error { + /// Default value, passed to `libbitcoinconsensus` as a return parameter. + ERR_SCRIPT = 0, + /// An invalid index for `txTo`. + ERR_TX_INDEX, + /// `txToLen` did not match with the size of `txTo`. + ERR_TX_SIZE_MISMATCH, + /// An error deserializing `txTo`. + ERR_TX_DESERIALIZE, + /// Input amount is required if WITNESS is used. + ERR_AMOUNT_REQUIRED, + /// Script verification `flags` are invalid (i.e. not part of the libconsensus interface). + ERR_INVALID_FLAGS, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::Error::*; + + let s = match *self { + ERR_SCRIPT => "error value was not set (value still 0)", + ERR_TX_INDEX => "an invalid index for txTo", + ERR_TX_SIZE_MISMATCH => "txToLen did not match with the size of txTo", + ERR_TX_DESERIALIZE => "an error deserializing txTo", + ERR_AMOUNT_REQUIRED => "input amount is required if WITNESS is used", + ERR_INVALID_FLAGS => "script verification flags are invalid", + }; + f.write_str(s) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use self::Error::*; + + match *self { + ERR_SCRIPT | ERR_TX_INDEX | ERR_TX_SIZE_MISMATCH | ERR_TX_DESERIALIZE + | ERR_AMOUNT_REQUIRED | ERR_INVALID_FLAGS => None, + } + } +} + #[cfg(test)] mod tests { extern crate rustc_serialize as serialize; diff --git a/src/types.rs b/src/types.rs index a031e6bbb..c040b33c5 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,4 +1,3 @@ -// Written by the Rust Bitcoin developers. // SPDX-License-Identifier: CC0-1.0 #![allow(non_camel_case_types)]