From bed7cde4c0745672a84f31e326c09aeca0ad1170 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 1 Dec 2023 11:34:45 +1100 Subject: [PATCH 1/9] Improve docs on verify function Improve the docs on `verify` by doing: - Attempt to make the docs more terse with no loss of meaning. - Remove link to transactions, no need to bless a specific explorer, folk can use the explorer of their choice to look things up. --- src/lib.rs | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 60cec4155..560b21a0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,38 +142,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, From 1d36f2c2555aa5de8fdebdeac96d17cf627803ea Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 1 Dec 2023 11:53:17 +1100 Subject: [PATCH 2/9] Move error code to bottom of file Move the error code to the bottom of the file because it is boring and should not be looked at. Code move only, no other changes. --- src/lib.rs | 102 ++++++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 560b21a0a..a6adcf68f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,57 +19,6 @@ 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, - } - } -} - /// Do not enable any verification. pub const VERIFY_NONE: c_uint = 0; /// Evaluate P2SH (BIP16) subscripts. @@ -207,6 +156,57 @@ pub fn verify_with_flags( } } +/// 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; From 7c1cb294db5f8578fe0d30689a164cc7415c5b5d Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 1 Dec 2023 11:55:17 +1100 Subject: [PATCH 3/9] Remove wildcard import Wildcards obfuscate imports; import the types explicitly. Refactor only, no logic changes. --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index a6adcf68f..5b517a37f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ mod types; use core::fmt; -use crate::types::*; +use crate::types::{c_int, c_uchar, c_uint}; /// Do not enable any verification. pub const VERIFY_NONE: c_uint = 0; From 596e2ce72743360fdaca3e2322e3cb4d3616e135 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 1 Dec 2023 11:56:47 +1100 Subject: [PATCH 4/9] Move extern C stuff to bottom of file The C function declarations can go at the bottom, based on the principle of putting the most important stuff at the top. Refactor only, no logic changes. --- src/lib.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5b517a37f..1269e71dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,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; @@ -156,6 +138,24 @@ pub fn verify_with_flags( } } +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`. From 8d21e3d831ed533e163bab7851496a7b21c7cb57 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 1 Dec 2023 12:17:51 +1100 Subject: [PATCH 5/9] Fix rustdoc link --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 1269e71dd..98f2d9ca2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ //! //! And that is exactly what this library is, the Rust bindings to `bitcoinconsensus`. //! -//! [`bitcoin/doc/shared-libraries`]: +//! [`bitcoin/doc/shared-libraries.md`]: mod types; From e8ff1a927b926c395f44554a9564807bd9c0b426 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 1 Dec 2023 12:20:27 +1100 Subject: [PATCH 6/9] Shoosh C++ compiler We don't need to see C++ build warnings for implicit fallthrough. --- build.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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") { From a446115019cc5a0cc08e36b8ec22bf54042130aa Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 29 Nov 2023 15:41:03 +1100 Subject: [PATCH 7/9] Remove written by comment We have moved away from using this comment in the rest of the `rust-bitcoin` org repos, do so here also. --- src/types.rs | 1 - 1 file changed, 1 deletion(-) 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)] From 6782fd15f90b2a883675b7db0795322528365680 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 29 Nov 2023 16:09:40 +1100 Subject: [PATCH 8/9] Remove travis config file We use github actions for CI now, we no longer need the old travis config file. --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .travis.yml 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 - From 01a48d1d98d0b36ec3d47bd80389cfe75395a088 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 6 Dec 2023 09:44:37 +1100 Subject: [PATCH 9/9] Add public ffi module In order to de-clutter the HTML docs add a public submodule `ffi` and put the C function definitions in it. --- src/lib.rs | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 98f2d9ca2..d3c7385ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ mod types; use core::fmt; -use crate::types::{c_int, c_uchar, c_uint}; +use crate::types::c_uint; /// Do not enable any verification. pub const VERIFY_NONE: c_uint = 0; @@ -65,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. /// @@ -120,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, @@ -138,22 +138,27 @@ pub fn verify_with_flags( } } -extern "C" { - /// Returns `libbitcoinconsensus` version. - pub fn bitcoinconsensus_version() -> c_int; +pub mod ffi { + use crate::types::{c_int, c_uchar, c_uint}; + use crate::Error; - /// 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; + 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`].