Skip to content

Commit 76ada74

Browse files
committed
Merge #71: Add ffi module
01a48d1 Add public ffi module (Tobin C. Harding) 6782fd1 Remove travis config file (Tobin C. Harding) a446115 Remove written by comment (Tobin C. Harding) e8ff1a9 Shoosh C++ compiler (Tobin C. Harding) 8d21e3d Fix rustdoc link (Tobin C. Harding) 596e2ce Move extern C stuff to bottom of file (Tobin C. Harding) 7c1cb29 Remove wildcard import (Tobin C. Harding) 1d36f2c Move error code to bottom of file (Tobin C. Harding) bed7cde Improve docs on verify function (Tobin C. Harding) Pull request description: This is #67 without the final version bump patch. Do a bunch of cleanups then add an `ffi` module to encapsulate the FFI function declarations. ACKs for top commit: apoelstra: ACK 01a48d1 Tree-SHA512: 5e951156498319c0559c5ba48da10810d3112f2372801d778b579e0ecf12bfe2c69d570c9837563d0de06272f4a8e76ae2d9a8afdc1f3a10733cbed96cc5e201
2 parents a692bb3 + 01a48d1 commit 76ada74

File tree

4 files changed

+96
-109
lines changed

4 files changed

+96
-109
lines changed

.travis.yml

Lines changed: 0 additions & 13 deletions
This file was deleted.

build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ fn main() {
2424
.cpp(true)
2525
.include("depend/bitcoin/src")
2626
.include("depend/bitcoin/src/secp256k1/include")
27-
.define("__STDC_FORMAT_MACROS", None);
27+
.define("__STDC_FORMAT_MACROS", None)
28+
.flag_if_supported("-Wno-implicit-fallthrough");
2829

2930
// **Secp256k1**
3031
if !cfg!(feature = "external-secp") {

src/lib.rs

Lines changed: 94 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -11,64 +11,13 @@
1111
//!
1212
//! And that is exactly what this library is, the Rust bindings to `bitcoinconsensus`.
1313
//!
14-
//! [`bitcoin/doc/shared-libraries`]: <https://github.com/bitcoin/bitcoin/blob/master/doc/shared-libraries.md>
14+
//! [`bitcoin/doc/shared-libraries.md`]: <https://github.com/bitcoin/bitcoin/blob/master/doc/shared-libraries.md>
1515
1616
mod types;
1717

1818
use core::fmt;
1919

20-
use crate::types::*;
21-
22-
/// Errors returned by [`libbitcoinconsensus`].
23-
///
24-
/// The error variant identifiers mimic those from `libbitcoinconsensus`.
25-
///
26-
/// [`libbitcoinconsensus`]: <https://github.com/bitcoin/bitcoin/blob/master/doc/shared-libraries.md#errors>
27-
#[allow(non_camel_case_types)]
28-
#[derive(Debug)]
29-
#[repr(C)]
30-
pub enum Error {
31-
/// Default value, passed to `libbitcoinconsensus` as a return parameter.
32-
ERR_SCRIPT = 0,
33-
/// An invalid index for `txTo`.
34-
ERR_TX_INDEX,
35-
/// `txToLen` did not match with the size of `txTo`.
36-
ERR_TX_SIZE_MISMATCH,
37-
/// An error deserializing `txTo`.
38-
ERR_TX_DESERIALIZE,
39-
/// Input amount is required if WITNESS is used.
40-
ERR_AMOUNT_REQUIRED,
41-
/// Script verification `flags` are invalid (i.e. not part of the libconsensus interface).
42-
ERR_INVALID_FLAGS,
43-
}
44-
45-
impl fmt::Display for Error {
46-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47-
use self::Error::*;
48-
49-
let s = match *self {
50-
ERR_SCRIPT => "error value was not set (value still 0)",
51-
ERR_TX_INDEX => "an invalid index for txTo",
52-
ERR_TX_SIZE_MISMATCH => "txToLen did not match with the size of txTo",
53-
ERR_TX_DESERIALIZE => "an error deserializing txTo",
54-
ERR_AMOUNT_REQUIRED => "input amount is required if WITNESS is used",
55-
ERR_INVALID_FLAGS => "script verification flags are invalid",
56-
};
57-
f.write_str(s)
58-
}
59-
}
60-
61-
#[cfg(feature = "std")]
62-
impl std::error::Error for Error {
63-
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
64-
use self::Error::*;
65-
66-
match *self {
67-
ERR_SCRIPT | ERR_TX_INDEX | ERR_TX_SIZE_MISMATCH | ERR_TX_DESERIALIZE
68-
| ERR_AMOUNT_REQUIRED | ERR_INVALID_FLAGS => None,
69-
}
70-
}
71-
}
20+
use crate::types::c_uint;
7221

7322
/// Do not enable any verification.
7423
pub const VERIFY_NONE: c_uint = 0;
@@ -92,24 +41,6 @@ pub const VERIFY_ALL: c_uint = VERIFY_P2SH
9241
| VERIFY_CHECKSEQUENCEVERIFY
9342
| VERIFY_WITNESS;
9443

95-
extern "C" {
96-
/// Returns `libbitcoinconsensus` version.
97-
pub fn bitcoinconsensus_version() -> c_int;
98-
99-
/// Verifies that the transaction input correctly spends the previous
100-
/// output, considering any additional constraints specified by flags.
101-
pub fn bitcoinconsensus_verify_script_with_amount(
102-
script_pubkey: *const c_uchar,
103-
script_pubkeylen: c_uint,
104-
amount: u64,
105-
tx_to: *const c_uchar,
106-
tx_tolen: c_uint,
107-
n_in: c_uint,
108-
flags: c_uint,
109-
err: *mut Error,
110-
) -> c_int;
111-
}
112-
11344
/// Computes flags for soft fork activation heights on the Bitcoin network.
11445
pub fn height_to_flags(height: u32) -> u32 {
11546
let mut flag = VERIFY_NONE;
@@ -134,46 +65,41 @@ pub fn height_to_flags(height: u32) -> u32 {
13465
}
13566

13667
/// Returns `libbitcoinconsensus` version.
137-
pub fn version() -> u32 { unsafe { bitcoinconsensus_version() as u32 } }
68+
pub fn version() -> u32 { unsafe { ffi::bitcoinconsensus_version() as u32 } }
13869

13970
/// Verifies a single spend (input) of a Bitcoin transaction.
14071
///
14172
/// Note that amount will only be checked for Segwit transactions.
14273
///
14374
/// # Arguments
14475
///
145-
/// * spend_output_script: A Bitcoin transaction output script to be spent, serialized in Bitcoin's on wire format.
146-
/// * amount: The spent output amount in satoshis.
147-
/// * spending_transaction: The spending Bitcoin transaction, serialized in Bitcoin's on wire format.
148-
/// * input_index: The index of the input within spending_transaction.
76+
/// * `spend_output`: A Bitcoin transaction output script to be spent, serialized in Bitcoin's on wire format.
77+
/// * `amount`: The spent output amount in satoshis.
78+
/// * `spending_transaction`: The spending Bitcoin transaction, serialized in Bitcoin's on wire format.
79+
/// * `input_index`: The index of the input within spending_transaction.
14980
///
15081
/// # Examples
15182
///
152-
/// The (randomly choosen) Bitcoin transaction [aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d](https://blockchain.info/tx/aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d)
83+
/// The (randomly choosen) Bitcoin transaction
84+
///
85+
/// `aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d`
86+
///
15387
/// spends one input, that is the first output of
154-
/// [95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f](https://blockchain.info/tx/95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f)
155-
/// with a value of 630482530 satoshis.
15688
///
157-
/// The spending transaction in wire format is:
89+
/// `95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f`
15890
///
159-
/// `
160-
/// spending = 02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700
161-
/// `
91+
/// The spending transaction serialized is:
16292
///
163-
/// The script of the first output of the spent transaction is:
93+
/// `spending = 02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700`
16494
///
165-
/// `
166-
/// spent = 76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ac
167-
/// `
95+
/// The script of the first output of the spent transaction is:
16896
///
169-
/// The (pseudo code) call:
97+
/// `spent = 76a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988ac`
17098
///
171-
/// `
172-
/// verify(spent, 630482530, spending, 0)
173-
/// `
174-
/// should return `Ok(())`.
99+
/// The (pseudo code) call: `verify(spent, 630482530, spending, 0)` should return `Ok(())`.
175100
///
176-
/// **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.
101+
/// **Note** since the spent amount will only be checked for Segwit transactions and the above
102+
/// example is not segwit, `verify` will succeed with any amount.
177103
pub fn verify(
178104
spent_output: &[u8],
179105
amount: u64,
@@ -194,7 +120,7 @@ pub fn verify_with_flags(
194120
unsafe {
195121
let mut error = Error::ERR_SCRIPT;
196122

197-
let ret = bitcoinconsensus_verify_script_with_amount(
123+
let ret = ffi::bitcoinconsensus_verify_script_with_amount(
198124
spent_output_script.as_ptr(),
199125
spent_output_script.len() as c_uint,
200126
amount,
@@ -212,6 +138,80 @@ pub fn verify_with_flags(
212138
}
213139
}
214140

141+
pub mod ffi {
142+
use crate::types::{c_int, c_uchar, c_uint};
143+
use crate::Error;
144+
145+
extern "C" {
146+
/// Returns `libbitcoinconsensus` version.
147+
pub fn bitcoinconsensus_version() -> c_int;
148+
149+
/// Verifies that the transaction input correctly spends the previous
150+
/// output, considering any additional constraints specified by flags.
151+
pub fn bitcoinconsensus_verify_script_with_amount(
152+
script_pubkey: *const c_uchar,
153+
script_pubkeylen: c_uint,
154+
amount: u64,
155+
tx_to: *const c_uchar,
156+
tx_tolen: c_uint,
157+
n_in: c_uint,
158+
flags: c_uint,
159+
err: *mut Error,
160+
) -> c_int;
161+
}
162+
}
163+
164+
/// Errors returned by [`libbitcoinconsensus`].
165+
///
166+
/// The error variant identifiers mimic those from `libbitcoinconsensus`.
167+
///
168+
/// [`libbitcoinconsensus`]: <https://github.com/bitcoin/bitcoin/blob/master/doc/shared-libraries.md#errors>
169+
#[allow(non_camel_case_types)]
170+
#[derive(Debug)]
171+
#[repr(C)]
172+
pub enum Error {
173+
/// Default value, passed to `libbitcoinconsensus` as a return parameter.
174+
ERR_SCRIPT = 0,
175+
/// An invalid index for `txTo`.
176+
ERR_TX_INDEX,
177+
/// `txToLen` did not match with the size of `txTo`.
178+
ERR_TX_SIZE_MISMATCH,
179+
/// An error deserializing `txTo`.
180+
ERR_TX_DESERIALIZE,
181+
/// Input amount is required if WITNESS is used.
182+
ERR_AMOUNT_REQUIRED,
183+
/// Script verification `flags` are invalid (i.e. not part of the libconsensus interface).
184+
ERR_INVALID_FLAGS,
185+
}
186+
187+
impl fmt::Display for Error {
188+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
189+
use self::Error::*;
190+
191+
let s = match *self {
192+
ERR_SCRIPT => "error value was not set (value still 0)",
193+
ERR_TX_INDEX => "an invalid index for txTo",
194+
ERR_TX_SIZE_MISMATCH => "txToLen did not match with the size of txTo",
195+
ERR_TX_DESERIALIZE => "an error deserializing txTo",
196+
ERR_AMOUNT_REQUIRED => "input amount is required if WITNESS is used",
197+
ERR_INVALID_FLAGS => "script verification flags are invalid",
198+
};
199+
f.write_str(s)
200+
}
201+
}
202+
203+
#[cfg(feature = "std")]
204+
impl std::error::Error for Error {
205+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
206+
use self::Error::*;
207+
208+
match *self {
209+
ERR_SCRIPT | ERR_TX_INDEX | ERR_TX_SIZE_MISMATCH | ERR_TX_DESERIALIZE
210+
| ERR_AMOUNT_REQUIRED | ERR_INVALID_FLAGS => None,
211+
}
212+
}
213+
}
214+
215215
#[cfg(test)]
216216
mod tests {
217217
extern crate rustc_serialize as serialize;

src/types.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// Written by the Rust Bitcoin developers.
21
// SPDX-License-Identifier: CC0-1.0
32

43
#![allow(non_camel_case_types)]

0 commit comments

Comments
 (0)