Merge branch 'master' into add-regtest
This commit is contained in:
commit
97908ea058
|
@ -20,14 +20,6 @@ For JSONRPC interaction with Bitcoin Core, it is recommended to use [rust-jsonrp
|
||||||
which uses the underlying [strason library](https://github.com/apoelstra/strason)
|
which uses the underlying [strason library](https://github.com/apoelstra/strason)
|
||||||
which parses decimal numbers as strings, preventing precision errors.
|
which parses decimal numbers as strings, preventing precision errors.
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
To use rust-bitcoin, just add the following to your Cargo.toml.
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
bitcoin = "0.12"
|
|
||||||
```
|
|
||||||
|
|
||||||
# Known limitations
|
# Known limitations
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,10 @@ macro_rules! impl_array_newtype {
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Returns whether the object, as an array, is empty. Always false.
|
/// Returns whether the object, as an array, is empty. Always false.
|
||||||
pub fn is_empty(&self) -> bool { false }
|
pub fn is_empty(&self) -> bool { false }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Returns the underlying data.
|
||||||
|
pub fn data(&self) -> [$ty; $len] { self.0.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [$ty]> for $thing {
|
impl<'a> From<&'a [$ty]> for $thing {
|
||||||
|
|
|
@ -105,6 +105,20 @@ macro_rules! user_enum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ::std::str::FromStr for $name {
|
||||||
|
type Err = ::std::io::Error;
|
||||||
|
#[inline]
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
$($txt => Ok($name::$elem)),*,
|
||||||
|
_ => Err(::std::io::Error::new(
|
||||||
|
::std::io::ErrorKind::InvalidInput,
|
||||||
|
format!("Unknown network (type {})", s),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ::serde::Deserialize for $name {
|
impl ::serde::Deserialize for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(d: &mut D) -> Result<$name, D::Error>
|
fn deserialize<D>(d: &mut D) -> Result<$name, D::Error>
|
||||||
|
|
|
@ -90,5 +90,15 @@ mod tests {
|
||||||
let bad: Result<Network, _> = deserialize("fakenet".as_bytes());
|
let bad: Result<Network, _> = deserialize("fakenet".as_bytes());
|
||||||
assert!(bad.is_err());
|
assert!(bad.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string_test() {
|
||||||
|
assert_eq!(Network::Bitcoin.to_string(), "bitcoin");
|
||||||
|
assert_eq!(Network::Testnet.to_string(), "testnet");
|
||||||
|
|
||||||
|
assert_eq!("bitcoin".parse::<Network>().unwrap(), Network::Bitcoin);
|
||||||
|
assert_eq!("testnet".parse::<Network>().unwrap(), Network::Testnet);
|
||||||
|
assert!("fakenet".parse::<Network>().is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -481,6 +481,18 @@ mod tests {
|
||||||
"56944C5D3F98413EF45CF54545538103CC9F298E0575820AD3591376E2E0F65D");
|
"56944C5D3F98413EF45CF54545538103CC9F298E0575820AD3591376E2E0F65D");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sha256d_data() {
|
||||||
|
assert_eq!(
|
||||||
|
Sha256dHash::from_data(&[]).data(),
|
||||||
|
[
|
||||||
|
0x5d, 0xf6, 0xe0, 0xe2, 0x76, 0x13, 0x59, 0xd3, 0x0a, 0x82, 0x75, 0x05, 0x8e, 0x29,
|
||||||
|
0x9f, 0xcc, 0x03, 0x81, 0x53, 0x45, 0x45, 0xf5, 0x5c, 0xf4, 0x3e, 0x41, 0x98, 0x3f,
|
||||||
|
0x5d, 0x4c, 0x94, 0x56,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sha256d_encoder() {
|
fn sha256d_encoder() {
|
||||||
let test = vec![true, false, true, true, false];
|
let test = vec![true, false, true, true, false];
|
||||||
|
|
|
@ -61,12 +61,17 @@ macro_rules! construct_uint {
|
||||||
let mut carry = [0u64; $n_words];
|
let mut carry = [0u64; $n_words];
|
||||||
let mut ret = [0u64; $n_words];
|
let mut ret = [0u64; $n_words];
|
||||||
for i in 0..$n_words {
|
for i in 0..$n_words {
|
||||||
|
let not_last_word = i < $n_words - 1;
|
||||||
let upper = other as u64 * (arr[i] >> 32);
|
let upper = other as u64 * (arr[i] >> 32);
|
||||||
let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
|
let lower = other as u64 * (arr[i] & 0xFFFFFFFF);
|
||||||
if i < 3 {
|
if not_last_word {
|
||||||
carry[i + 1] += upper >> 32;
|
carry[i + 1] += upper >> 32;
|
||||||
}
|
}
|
||||||
ret[i] = lower + (upper << 32);
|
let (sum, overflow) = lower.overflowing_add(upper << 32);
|
||||||
|
ret[i] = sum;
|
||||||
|
if overflow && not_last_word {
|
||||||
|
carry[i + 1] += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$name(ret) + $name(carry)
|
$name(ret) + $name(carry)
|
||||||
}
|
}
|
||||||
|
@ -118,10 +123,11 @@ macro_rules! construct_uint {
|
||||||
type Output = $name;
|
type Output = $name;
|
||||||
|
|
||||||
fn mul(self, other: $name) -> $name {
|
fn mul(self, other: $name) -> $name {
|
||||||
let mut me = self;
|
let mut me = $name::zero();
|
||||||
// TODO: be more efficient about this
|
// TODO: be more efficient about this
|
||||||
for i in 0..(2 * $n_words) {
|
for i in 0..(2 * $n_words) {
|
||||||
me = (me + me.mul_u32((other >> (32 * i)).low_u32())) << (32 * i);
|
let to_mul = (other >> (32 * i)).low_u32();
|
||||||
|
me = me + (self.mul_u32(to_mul) << (32 * i));
|
||||||
}
|
}
|
||||||
me
|
me
|
||||||
}
|
}
|
||||||
|
@ -323,6 +329,12 @@ macro_rules! construct_uint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for $name {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
<fmt::Debug>::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $name {
|
impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
|
@ -401,6 +413,19 @@ mod tests {
|
||||||
assert!(!Uint256::from_u64(10).unwrap().bit(4));
|
assert!(!Uint256::from_u64(10).unwrap().bit(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn uint256_display_test() {
|
||||||
|
assert_eq!(format!("{}", Uint256::from_u64(0xDEADBEEF).unwrap()),
|
||||||
|
"0x00000000000000000000000000000000000000000000000000000000deadbeef");
|
||||||
|
assert_eq!(format!("{}", Uint256::from_u64(u64::max_value()).unwrap()),
|
||||||
|
"0x000000000000000000000000000000000000000000000000ffffffffffffffff");
|
||||||
|
|
||||||
|
let max_val = Uint256([0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
|
||||||
|
0xFFFFFFFFFFFFFFFF]);
|
||||||
|
assert_eq!(format!("{}", max_val),
|
||||||
|
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn uint256_comp_test() {
|
pub fn uint256_comp_test() {
|
||||||
let small = Uint256([10u64, 0, 0, 0]);
|
let small = Uint256([10u64, 0, 0, 0]);
|
||||||
|
@ -449,6 +474,39 @@ mod tests {
|
||||||
// TODO: bit inversion
|
// TODO: bit inversion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn mul_u32_test() {
|
||||||
|
let u64_val = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
|
|
||||||
|
let u96_res = u64_val.mul_u32(0xFFFFFFFF);
|
||||||
|
let u128_res = u96_res.mul_u32(0xFFFFFFFF);
|
||||||
|
let u160_res = u128_res.mul_u32(0xFFFFFFFF);
|
||||||
|
let u192_res = u160_res.mul_u32(0xFFFFFFFF);
|
||||||
|
let u224_res = u192_res.mul_u32(0xFFFFFFFF);
|
||||||
|
let u256_res = u224_res.mul_u32(0xFFFFFFFF);
|
||||||
|
|
||||||
|
assert_eq!(u96_res, Uint256([0xffffffff21524111u64, 0xDEADBEEE, 0, 0]));
|
||||||
|
assert_eq!(u128_res, Uint256([0x21524111DEADBEEFu64, 0xDEADBEEE21524110, 0, 0]));
|
||||||
|
assert_eq!(u160_res, Uint256([0xBD5B7DDD21524111u64, 0x42A4822200000001, 0xDEADBEED, 0]));
|
||||||
|
assert_eq!(u192_res, Uint256([0x63F6C333DEADBEEFu64, 0xBD5B7DDFBD5B7DDB, 0xDEADBEEC63F6C334, 0]));
|
||||||
|
assert_eq!(u224_res, Uint256([0x7AB6FBBB21524111u64, 0xFFFFFFFBA69B4558, 0x854904485964BAAA, 0xDEADBEEB]));
|
||||||
|
assert_eq!(u256_res, Uint256([0xA69B4555DEADBEEFu64, 0xA69B455CD41BB662, 0xD41BB662A69B4550, 0xDEADBEEAA69B455C]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn multiplication_test() {
|
||||||
|
let u64_val = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
|
|
||||||
|
let u128_res = u64_val * u64_val;
|
||||||
|
|
||||||
|
assert_eq!(u128_res, Uint256([0x048D1354216DA321u64, 0xC1B1CD13A4D13D46, 0, 0]));
|
||||||
|
|
||||||
|
let u256_res = u128_res * u128_res;
|
||||||
|
|
||||||
|
assert_eq!(u256_res, Uint256([0xF4E166AAD40D0A41u64, 0xF5CF7F3618C2C886u64,
|
||||||
|
0x4AFCFF6F0375C608u64, 0x928D92B4D7F5DF33u64]));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn uint256_bitslice_test() {
|
pub fn uint256_bitslice_test() {
|
||||||
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
|
||||||
|
|
Loading…
Reference in New Issue