From 160f2f9ea61c5716d4f897a6063a20d41555921c Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 4 Apr 2015 22:13:19 -0500 Subject: [PATCH] Drop ThinVec, many other changes toward updating for librustc --- Cargo.toml | 1 + src/blockdata/opcodes.rs | 118 +++++++------- src/blockdata/script.rs | 74 ++++----- src/blockdata/utxoset.rs | 36 ++--- src/internal_macros.rs | 62 ++++++-- src/lib.rs | 3 + src/network/encodable.rs | 22 +-- src/util/base58.rs | 13 -- src/util/misc.rs | 1 - src/util/mod.rs | 1 - src/util/thinvec.rs | 309 ------------------------------------ src/util/uint.rs | 71 ++++----- src/wallet/address.rs | 10 +- src/wallet/address_index.rs | 2 +- src/wallet/bip32.rs | 40 ++--- src/wallet/wallet.rs | 51 ++---- 16 files changed, 247 insertions(+), 567 deletions(-) delete mode 100644 src/util/thinvec.rs diff --git a/Cargo.toml b/Cargo.toml index 933e693..f9641bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,6 @@ num_cpus = "*" rand = "*" rust-crypto = "*" rustc-serialize = "*" +serde = "*" time = "*" diff --git a/src/blockdata/opcodes.rs b/src/blockdata/opcodes.rs index 3a210d1..64b12e1 100644 --- a/src/blockdata/opcodes.rs +++ b/src/blockdata/opcodes.rs @@ -22,25 +22,20 @@ use serialize::json; -/// Submodule to handle -all- opcodes. Outside of this module we use -/// a restricted set where the push/return/noop/illegal opcodes have -/// a more convienient representation. -pub mod all { - use serialize::json; - // Heavy stick to translate between opcode types - use std::mem::transmute; +// Heavy stick to translate between opcode types +use std::mem::transmute; - use network::serialize::{SimpleDecoder, SimpleEncoder}; - use network::encodable::{ConsensusDecodable, ConsensusEncodable}; +use network::serialize::{SimpleDecoder, SimpleEncoder}; +use network::encodable::{ConsensusDecodable, ConsensusEncodable}; - // Note: I am deliberately not implementing PartialOrd or Ord on the - // opcode enum. If you want to check ranges of opcodes, etc., - // write an #[inline] helper function which casts to u8s. +// Note: I am deliberately not implementing PartialOrd or Ord on the +// opcode enum. If you want to check ranges of opcodes, etc., +// write an #[inline] helper function which casts to u8s. - /// A script Opcode - #[derive(Clone, PartialEq, Eq, Debug)] - #[repr(u8)] - pub enum Opcode { +/// A script Opcode +#[derive(Clone, PartialEq, Eq, Debug)] +#[repr(u8)] +pub enum All { /// Push an empty array onto the stack OP_PUSHBYTES_0 = 0x0, /// Push the next byte as an array onto the stack @@ -558,79 +553,80 @@ pub mod all { OP_RETURN_254 = 0xfe, /// Synonym for OP_RETURN OP_RETURN_255 = 0xff, - } +} - impl Opcode { - /// Translates a u8 to an Opcode +impl All { + /// Translates a u8 to an opcode #[inline] - pub fn from_u8(b: u8) -> Opcode { + pub fn from_u8(b: u8) -> All { unsafe { transmute(b) } } /// Classifies an Opcode into a broad class #[inline] - pub fn classify(&self) -> super::OpcodeClass { + pub fn classify(&self) -> OpcodeClass { // 17 opcodes - if *self == OP_VERIF || *self == OP_VERNOTIF || - *self == OP_CAT || *self == OP_SUBSTR || - *self == OP_LEFT || *self == OP_RIGHT || - *self == OP_INVERT || *self == OP_AND || - *self == OP_OR || *self == OP_XOR || - *self == OP_2MUL || *self == OP_2DIV || - *self == OP_MUL || *self == OP_DIV || *self == OP_MOD || - *self == OP_LSHIFT || *self == OP_RSHIFT { - super::IllegalOp + if *self == All::OP_VERIF || *self == All::OP_VERNOTIF || + *self == All::OP_CAT || *self == All::OP_SUBSTR || + *self == All::OP_LEFT || *self == All::OP_RIGHT || + *self == All::OP_INVERT || *self == All::OP_AND || + *self == All::OP_OR || *self == All::OP_XOR || + *self == All::OP_2MUL || *self == All::OP_2DIV || + *self == All::OP_MUL || *self == All::OP_DIV || *self == All::OP_MOD || + *self == All::OP_LSHIFT || *self == All::OP_RSHIFT { + OpcodeClass::IllegalOp // 11 opcodes - } else if *self == OP_NOP || - (OP_NOP1 as u8 <= *self as u8 && *self as u8 <= OP_NOP10 as u8) { - super::NoOp + } else if *self == All::OP_NOP || + (All::OP_NOP1 as u8 <= *self as u8 && + *self as u8 <= All::OP_NOP10 as u8) { + OpcodeClass::NoOp // 75 opcodes - } else if *self == OP_RESERVED || *self == OP_VER || *self == OP_RETURN || - *self == OP_RESERVED1 || *self == OP_RESERVED2 || - *self as u8 >= OP_RETURN_186 as u8 { - super::ReturnOp + } else if *self == All::OP_RESERVED || *self == All::OP_VER || *self == All::OP_RETURN || + *self == All::OP_RESERVED1 || *self == All::OP_RESERVED2 || + *self as u8 >= All::OP_RETURN_186 as u8 { + OpcodeClass::ReturnOp // 1 opcode - } else if *self == OP_PUSHNUM_NEG1 { - super::PushNum(-1) + } else if *self == All::OP_PUSHNUM_NEG1 { + OpcodeClass::PushNum(-1) // 16 opcodes - } else if OP_PUSHNUM_1 as u8 <= *self as u8 && *self as u8 <= OP_PUSHNUM_16 as u8 { - super::PushNum(1 + *self as isize - OP_PUSHNUM_1 as isize) + } else if All::OP_PUSHNUM_1 as u8 <= *self as u8 && + *self as u8 <= All::OP_PUSHNUM_16 as u8 { + OpcodeClass::PushNum(1 + *self as isize - OP_PUSHNUM_1 as isize) // 76 opcodes - } else if *self as u8 <= OP_PUSHBYTES_75 as u8 { - super::PushBytes(*self as usize) + } else if *self as u8 <= All::OP_PUSHBYTES_75 as u8 { + OpcodeClass::PushBytes(*self as usize) // 60 opcodes } else { - super::Ordinary(unsafe { transmute(*self) }) + OpcodeClass::Ordinary(unsafe { transmute(*self) }) } } - } +} - impl, E> ConsensusDecodable for Opcode { +impl, E> ConsensusDecodable for All { #[inline] - fn consensus_decode(d: &mut D) -> Result { - Ok(Opcode::from_u8(try!(d.read_u8()))) + fn consensus_decode(d: &mut D) -> Result { + Ok(All::from_u8(try!(d.read_u8()))) } - } +} - impl, E> ConsensusEncodable for Opcode { +impl, E> ConsensusEncodable for All { #[inline] fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u8(*self as u8) } - } +} - impl json::ToJson for Opcode { +impl json::ToJson for All { fn to_json(&self) -> json::Json { json::String(self.to_string()) } - } - - /// Empty stack is also FALSE - pub static OP_FALSE: Opcode = OP_PUSHBYTES_0; - /// Number 1 is also TRUE - pub static OP_TRUE: Opcode = OP_PUSHNUM_1; } +/// Empty stack is also FALSE +pub static OP_FALSE: All = OP_PUSHBYTES_0; +/// Number 1 is also TRUE +pub static OP_TRUE: All = OP_PUSHNUM_1; + /// Broad categories of opcodes with similar behavior #[derive(Clone, PartialEq, Eq, Debug)] pub enum OpcodeClass { @@ -645,7 +641,7 @@ pub enum OpcodeClass { /// Does nothing NoOp, /// Any opcode not covered above - Ordinary(Opcode) + Ordinary(Ordinary) } impl json::ToJson for OpcodeClass { @@ -659,8 +655,8 @@ macro_rules! ordinary_opcode { #[repr(u8)] #[doc(hidden)] #[derive(Clone, PartialEq, Eq, Debug)] - pub enum Opcode { - $( $op = all::$op as u8 ),* + pub enum Ordinary { + $( $op = All::$op as u8 ),* } ); } diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index e6cc32a..a03065d 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -39,18 +39,15 @@ use secp256k1::Secp256k1; use secp256k1::key::PublicKey; use blockdata::opcodes; -use blockdata::opcodes::Opcode; -use blockdata::opcodes::all as allops; use blockdata::transaction::{Transaction, TxIn}; use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::serialize::{SimpleDecoder, SimpleEncoder, serialize}; use util::hash::Sha256dHash; use util::misc::script_find_and_remove; -use util::thinvec::ThinVec; #[derive(PartialEq, Eq, Debug, Clone)] /// A Bitcoin script -pub struct Script(ThinVec); +pub struct Script(Box<[u8]>); impl hash::Hash for Script { #[inline] @@ -1208,7 +1205,7 @@ impl json::ToJson for ScriptError { pub struct TraceIteration { index: usize, op_count: usize, - opcode: allops::Opcode, + opcode: opcodes::All, executed: bool, errored: bool, effect: opcodes::OpcodeClass, @@ -1409,7 +1406,7 @@ fn check_signature(sig_slice: &[u8], pk_slice: &[u8], script: Vec, // For anyone-can-pay transactions we replace the whole input array // with just the current input, to ensure the others have no effect. let mut old_input = tx.input[input_index].clone(); - old_input.script_sig = Script(ThinVec::from_vec(script.take().unwrap())); + old_input.script_sig = Script(script.take().unwrap().into_boxed_slice()); tx_copy.input = vec![old_input]; } else { // Otherwise we keep all the inputs, blanking out the others and even @@ -1421,7 +1418,7 @@ fn check_signature(sig_slice: &[u8], pk_slice: &[u8], script: Vec, sequence: input.sequence, script_sig: Script::new() }; if n == input_index { - new_input.script_sig = Script(ThinVec::from_vec(script.take().unwrap())); + new_input.script_sig = Script(script.take().unwrap().into_boxed_slice()); } else { new_input.script_sig = Script::new(); // If we aren't signing them, also zero out the sequence number @@ -1598,10 +1595,10 @@ macro_rules! op_verify_satisfy { impl Script { /// Creates a new empty script - pub fn new() -> Script { Script(ThinVec::new()) } + pub fn new() -> Script { Script(vec![].into_boxed_slice()) } /// Creates a new script from an existing vector - pub fn from_vec(v: Vec) -> Script { Script(ThinVec::from_vec(v)) } + pub fn from_vec(v: Vec) -> Script { Script(v.into_boxed_slice()) } /// The length in bytes of the script pub fn len(&self) -> usize { @@ -1664,7 +1661,7 @@ impl Script { } /// Adds an individual opcode to the script - pub fn push_opcode(&mut self, data: allops::Opcode) { + pub fn push_opcode(&mut self, data: opcodes::All) { let &Script(ref mut raw) = self; raw.push(data as u8); } @@ -2413,7 +2410,7 @@ impl Script { } impl Default for Script { - fn default() -> Script { Script(ThinVec::new()) } + fn default() -> Script { Script(vec![].into_boxed_slice()) } } // User-facing serialization @@ -2458,7 +2455,6 @@ mod test { use network::serialize::{deserialize, serialize}; use blockdata::opcodes; use blockdata::transaction::Transaction; - use util::thinvec::ThinVec; fn test_tx(tx_hex: &'static str, output_hex: Vec<&'static str>) { let tx_hex = tx_hex.from_hex().unwrap(); @@ -2483,9 +2479,9 @@ mod test { #[test] fn script() { - let mut comp = ThinVec::new(); + let mut comp = vec![]; let mut script = Script::new(); - assert_eq!(script, Script(ThinVec::new())); + assert_eq!(script, Script(comp.into_boxed_slice())); // small ints script.push_int(1); comp.push(82u8); assert_eq!(script, Script(comp.clone())); @@ -2712,43 +2708,43 @@ mod test { #[test] fn provably_unspendable_test() { // p2pk - assert_eq!(Script(ThinVec::from_vec("410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("4104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("410446ef0102d1ec5240f0d061a4246c1bdef63fc3dbab7733052fbbf0ecd8f41fc26bf049ebb4f9527f374280259e7cfa99c48b0e3f39c51347a19a5819651503a5ac".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("4104ea1feff861b51fe3f5f8a3b12d0f4712db80e919548a80839fc47c6a21e66d957e9c5d8cd108c7a2d2324bad71f9904ac0ae7336507d785b17a2c115e427a32fac".from_hex().unwrap()).is_provably_unspendable(), false); // p2pkhash - assert_eq!(Script(ThinVec::from_vec("76a914ee61d57ab51b9d212335b1dba62794ac20d2bcf988ac".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("6aa9149eb21980dc9d413d8eac27314938b9da920ee53e87".from_hex().unwrap())).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("76a914ee61d57ab51b9d212335b1dba62794ac20d2bcf988ac".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("6aa9149eb21980dc9d413d8eac27314938b9da920ee53e87".from_hex().unwrap()).is_provably_unspendable(), true); // if return; else return - assert_eq!(Script(ThinVec::from_vec("636a676a68".from_hex().unwrap())).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("636a676a68".from_hex().unwrap()).is_provably_unspendable(), true); // if return; else don't - assert_eq!(Script(ThinVec::from_vec("636a6768".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("636a6768".from_hex().unwrap()).is_provably_unspendable(), false); // op_equal - assert_eq!(Script(ThinVec::from_vec("87".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("000087".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("510087".from_hex().unwrap())).is_provably_unspendable(), true); - assert_eq!(Script(ThinVec::from_vec("510088".from_hex().unwrap())).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("87".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("000087".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("510087".from_hex().unwrap()).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("510088".from_hex().unwrap()).is_provably_unspendable(), true); // nested ifs - assert_eq!(Script(ThinVec::from_vec("6363636363686868686800".from_hex().unwrap())).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("6363636363686868686800".from_hex().unwrap()).is_provably_unspendable(), true); // repeated op_equals - assert_eq!(Script(ThinVec::from_vec("8787878787878787".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("8787878787878787".from_hex().unwrap()).is_provably_unspendable(), false); // op_ifdup - assert_eq!(Script(ThinVec::from_vec("73".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("5173".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("0073".from_hex().unwrap())).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("73".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("5173".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("0073".from_hex().unwrap()).is_provably_unspendable(), true); // this is honest to god tx e411dbebd2f7d64dafeef9b14b5c59ec60c36779d43f850e5e347abee1e1a455 on mainnet - assert_eq!(Script(ThinVec::from_vec("76a9144838a081d73cf134e8ff9cfd4015406c73beceb388acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac".from_hex().unwrap())).is_provably_unspendable(), true); + assert_eq!(Script::from_vec("76a9144838a081d73cf134e8ff9cfd4015406c73beceb388acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac".from_hex().unwrap()).is_provably_unspendable(), true); // Real, testnet spent ones that caused me trouble - assert_eq!(Script(ThinVec::from_vec("7c51880087".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("9e91".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("76a97ca8a687".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("04010203047576a914bfbd43270c1e824c01e27386844d062d2f7518a688ad76a97614d2f7b8a37fb9b46782534078f9748f41d61a22f3877c148d4c6a901a3d87ed680478931dc9b6f0871af0ab879b69ac".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("03800000".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("7c51880087".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("9e91".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("76a97ca8a687".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("04010203047576a914bfbd43270c1e824c01e27386844d062d2f7518a688ad76a97614d2f7b8a37fb9b46782534078f9748f41d61a22f3877c148d4c6a901a3d87ed680478931dc9b6f0871af0ab879b69ac".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("03800000".from_hex().unwrap()).is_provably_unspendable(), false); // This one is cool -- a 2-of-4 multisig with four pks given, only two of which are legit - assert_eq!(Script(ThinVec::from_vec("522103bb52138972c48a132fc1f637858c5189607dd0f7fe40c4f20f6ad65f2d389ba42103bb52138972c48a132fc1f637858c5189607dd0f7fe40c4f20f6ad65f2d389ba45f6054ae".from_hex().unwrap())).is_provably_unspendable(), false); - assert_eq!(Script(ThinVec::from_vec("64635167006867630067516868".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("522103bb52138972c48a132fc1f637858c5189607dd0f7fe40c4f20f6ad65f2d389ba42103bb52138972c48a132fc1f637858c5189607dd0f7fe40c4f20f6ad65f2d389ba45f6054ae".from_hex().unwrap()).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("64635167006867630067516868".from_hex().unwrap()).is_provably_unspendable(), false); // This one is on mainnet oeO - assert_eq!(Script(ThinVec::from_vec("827651a0698faaa9a8a7a687".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("827651a0698faaa9a8a7a687".from_hex().unwrap()).is_provably_unspendable(), false); // gmaxwell found this one - assert_eq!(Script(ThinVec::from_vec("76009f69905160a56b210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71ad6c".from_hex().unwrap())).is_provably_unspendable(), false); + assert_eq!(Script::from_vec("76009f69905160a56b210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71ad6c".from_hex().unwrap()).is_provably_unspendable(), false); } } diff --git a/src/blockdata/utxoset.rs b/src/blockdata/utxoset.rs index 4966c0d..2029907 100644 --- a/src/blockdata/utxoset.rs +++ b/src/blockdata/utxoset.rs @@ -33,7 +33,6 @@ use blockdata::block::Block; use network::constants::Network; use network::serialize::BitcoinHash; use util::hash::{DumbHasher, Sha256dHash}; -use util::thinvec::ThinVec; /// The amount of validation to do when updating the UTXO set #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)] @@ -63,7 +62,7 @@ struct UtxoNode { /// Blockheight at which this UTXO appeared in the blockchain height: u32, /// Vector of outputs; None indicates a nonexistent or already spent output - outputs: ThinVec> + outputs: Box<[Option]> } impl_consensus_encoding!(UtxoNode, height, outputs); @@ -137,22 +136,22 @@ impl UtxoSet { let txid = tx.bitcoin_hash(); // Locate node if it's already there let new_node = unsafe { - let mut new_node = ThinVec::with_capacity(tx.output.len() as u32); - for (vout, txo) in tx.output.iter().enumerate() { + let mut new_node = Vec::with_capacity(tx.output.len()); + for txo in tx.output.iter() { // Unsafe since we are not uninitializing the old data in the vector if txo.script_pubkey.is_provably_unspendable() { - new_node.init(vout as usize, None); + new_node.push(None); self.n_utxos -= 1; self.n_pruned += 1; } else { - new_node.init(vout as usize, Some(txo.clone())); + new_node.push(Some(txo.clone())); } } - UtxoNode { outputs: new_node, height: height } + UtxoNode { outputs: new_node.into_boxed_slice(), height: height } }; // Get the old value, if any (this is suprisingly possible, c.f. BIP30 // and the other comments in this file referring to it) - let ret = self.table.swap(txid, new_node); + let ret = self.table.swap(txid, new_node.into_boxed_slice()); if ret.is_none() { self.n_utxos += tx.output.len() as u64; } @@ -354,26 +353,17 @@ impl UtxoSet { let new_node = match self.table.pop(&txid) { Some(mut node) => { - let old_len = node.outputs.len() as u32; - if old_len < n + 1 { - unsafe { - node.outputs.reserve(n + 1); - for i in range(old_len, n + 1) { - node.outputs.init(i as usize, None); - } - } - } - unsafe { *node.outputs.get_mut(n as usize) = Some(txo); } + node.outputs[n as usize] = Some(txo); node } None => { unsafe { - let mut thinvec = ThinVec::with_capacity(n + 1); - for i in range(0, n) { - thinvec.init(i as usize, None); + let mut thinvec = Vec::with_capacity(n + 1); + for _ in 0..n { + thinvec.push(None); } - thinvec.init(n as usize, Some(txo)); - UtxoNode { outputs: thinvec, height: height } + thinvec.push(Some(txo)); + UtxoNode { outputs: thinvec.into_boxed_slice(), height: height } } } }; diff --git a/src/internal_macros.rs b/src/internal_macros.rs index c4c923f..2b06835 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -131,13 +131,55 @@ macro_rules! impl_array_newtype { } } - impl Index for $thing { - #[inline] - fn index<'a>(&'a self, idx: &usize) -> &'a $ty { - let &$thing(ref data) = self; - &data[*idx] - } - } + impl ::std::ops::Index for $thing { + type Output = $ty; + + #[inline] + fn index(&self, index: usize) -> &$ty { + let &$thing(ref dat) = self; + &dat[index] + } + } + + impl ::std::ops::Index<::std::ops::Range> for $thing { + type Output = [$ty]; + + #[inline] + fn index(&self, index: ::std::ops::Range) -> &[$ty] { + let &$thing(ref dat) = self; + &dat[index.start..index.end] + } + } + + impl ::std::ops::Index<::std::ops::RangeTo> for $thing { + type Output = [$ty]; + + #[inline] + fn index(&self, index: ::std::ops::RangeTo) -> &[$ty] { + let &$thing(ref dat) = self; + &dat[..index.end] + } + } + + impl ::std::ops::Index<::std::ops::RangeFrom> for $thing { + type Output = [$ty]; + + #[inline] + fn index(&self, index: ::std::ops::RangeFrom) -> &[$ty] { + let &$thing(ref dat) = self; + &dat[index.start..] + } + } + + impl ::std::ops::Index<::std::ops::RangeFull> for $thing { + type Output = [$ty]; + + #[inline] + fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] { + let &$thing(ref dat) = self; + &dat[..] + } + } impl PartialEq for $thing { #[inline] @@ -160,7 +202,7 @@ macro_rules! impl_array_newtype { macro_rules! impl_array_newtype_encodable { ($thing:ident, $ty:ty, $len:expr) => { impl, E> ::serialize::Decodable for $thing { - fn decode(d: &mut D) -> ::std::prelude::Result<$thing, E> { + fn decode(d: &mut D) -> Result<$thing, E> { use serialize::Decodable; ::assert_type_is_copy::<$ty>(); @@ -172,7 +214,7 @@ macro_rules! impl_array_newtype_encodable { unsafe { use std::mem; let mut ret: [$ty; $len] = mem::uninitialized(); - for i in range(0, len) { + for i in 0..len { ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); } Ok($thing(ret)) @@ -183,7 +225,7 @@ macro_rules! impl_array_newtype_encodable { } impl, S> ::serialize::Encodable for $thing { - fn encode(&self, e: &mut E) -> ::std::prelude::Result<(), S> { + fn encode(&self, e: &mut E) -> Result<(), S> { self.as_slice().encode(e) } } diff --git a/src/lib.rs b/src/lib.rs index ab4e1a7..0bef8bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ #![crate_type = "rlib"] // Experimental features we need +#![feature(custom_derive, plugin)] #![feature(overloaded_calls)] #![feature(unsafe_destructor)] #![feature(unboxed_closure_sugar)] @@ -49,6 +50,8 @@ extern crate core; extern crate num_cpus; extern crate rand; extern crate rustc_serialize as serialize; +extern crate serde; +#[plugin(serde_macros)] extern crate test; extern crate time; diff --git a/src/network/encodable.rs b/src/network/encodable.rs index af2af87..00dccd6 100644 --- a/src/network/encodable.rs +++ b/src/network/encodable.rs @@ -34,7 +34,6 @@ use std::default::Default; use std::hash::{Hash, Hasher}; use std::u32; -use util::thinvec::ThinVec; use util::hash::Sha256dHash; use network::serialize::{SimpleDecoder, SimpleEncoder}; @@ -230,25 +229,20 @@ impl, E, T:ConsensusDecodable> ConsensusDecodable } } -impl, E, T:ConsensusEncodable> ConsensusEncodable for ThinVec { +impl, E, T:ConsensusEncodable> ConsensusEncodable for Box<[T]> { #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), E> { self.as_slice().consensus_encode(s) } + fn consensus_encode(&self, s: &mut S) -> Result<(), E> { (&self[..]).consensus_encode(s) } } -impl, E, T:ConsensusDecodable> ConsensusDecodable for ThinVec { +impl, E, T:ConsensusDecodable> ConsensusDecodable for Box<[T]> { #[inline] - fn consensus_decode(d: &mut D) -> Result, E> { + fn consensus_decode(d: &mut D) -> Result, E> { let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); - if len > u32::MAX as u64 { - return Err(d.error("ThinVec length out of range!")); - } unsafe { - let mut ret = ThinVec::with_capacity(len as u32); - // Huge danger: if this fails, the remaining uninitialized part of the ThinVec - // will be freed. This is ok, but only because the memory is u8, which has no - // destructor...and assuming there are no trap representations...very fragile. - for i in range(0, len as usize) { ret.init(i, try!(ConsensusDecodable::consensus_decode(d))); } - Ok(ret) + let len = len as usize; + let mut ret = Vec::with_capacity(len); + for i in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); } + Ok(ret.into_boxed_slice()) } } } diff --git a/src/util/base58.rs b/src/util/base58.rs index 03f53a8..6f37e9e 100644 --- a/src/util/base58.rs +++ b/src/util/base58.rs @@ -18,7 +18,6 @@ use byteorder::{ByteOrder, LittleEndian}; use std::string; -use util::thinvec::ThinVec; use util::hash::Sha256dHash; /// An error that might occur during base58 decoding @@ -174,24 +173,12 @@ impl ToBase58 for Vec { fn to_base58(&self) -> String { base58_encode_slice(self.as_slice()) } } -impl ToBase58 for ThinVec { - fn base58_layout(&self) -> Vec { self.as_slice().to_vec() } - fn to_base58(&self) -> String { base58_encode_slice(self.as_slice()) } -} - impl FromBase58 for Vec { fn from_base58_layout(data: Vec) -> Result, Base58Error> { Ok(data) } } -impl FromBase58 for ThinVec { - fn from_base58_layout(data: Vec) -> Result, Base58Error> { - Ok(ThinVec::from_vec(data)) - } -} - - #[cfg(test)] mod tests { use serialize::hex::FromHex; diff --git a/src/util/misc.rs b/src/util/misc.rs index 3a3ad8c..80c3f3b 100644 --- a/src/util/misc.rs +++ b/src/util/misc.rs @@ -19,7 +19,6 @@ use std::io::{Error, Result, ErrorKind}; use blockdata::opcodes; -use blockdata::opcodes::all::Opcode; use util::iter::Pairable; /// Convert a hexadecimal-encoded string to its corresponding bytes diff --git a/src/util/mod.rs b/src/util/mod.rs index 846d75c..b62ba4e 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -22,7 +22,6 @@ pub mod hash; pub mod iter; pub mod misc; pub mod patricia_tree; -pub mod thinvec; pub mod uint; /// A trait which allows numbers to act as fixed-size bit arrays diff --git a/src/util/thinvec.rs b/src/util/thinvec.rs deleted file mode 100644 index d3afa12..0000000 --- a/src/util/thinvec.rs +++ /dev/null @@ -1,309 +0,0 @@ -// Rust Bitcoin Library -// Written in 2014 by -// Andrew Poelstra -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # Thin vectors -//! -//! A vector type designed to take as little memory as possible by limiting -//! its size to 4bn elements and not distinguishing between size and capacity. -//! It is very easy to read uninitialized memory: make sure you assign all -//! values after calling `reserve` or `with_capacity`. -//! - -use alloc::heap::{allocate, reallocate, deallocate}; -use std::raw; -use std::slice::{Iter, IterMut}; -use std::{fmt, mem, ptr}; -use std::u32; - -/// A vector type designed to take very little memory -pub struct ThinVec { - ptr: *mut T, - cap: u32 // capacity and length are the same -} - -impl ThinVec { - /// Constructor - #[inline] - pub fn new() -> ThinVec { ThinVec { ptr: RawPtr::null(), cap: 0 } } - - /// Constructor with predetermined capacity - #[inline] - pub unsafe fn with_capacity(capacity: u32) -> ThinVec { - if mem::size_of::() == 0 { - ThinVec { ptr: RawPtr::null(), cap: capacity } - } else if capacity == 0 { - ThinVec::new() - } else { - let size = (capacity as usize).checked_mul(&mem::size_of::()) - .expect("ThinVec::reserve: capacity overflow"); - let ptr = allocate(size, mem::min_align_of::()); - ThinVec { ptr: ptr as *mut T, cap: capacity } - } - } - - /// Constructor from an ordinary vector - #[inline] - pub fn from_vec(mut v: Vec) -> ThinVec { - v.shrink_to_fit(); - assert!(v.len() <= u32::MAX as usize); - let ret = ThinVec { ptr: v.as_mut_ptr(), cap: v.len() as u32 }; - unsafe { mem::forget(v); } - ret - } - - /// Iterator over elements of the vector - #[inline] - pub fn iter<'a>(&'a self) -> Iter<'a, T> { - self.as_slice().iter() - } - - /// Mutable iterator over elements of the vector - #[inline] - pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { - self.as_mut_slice().iter_mut() - } - - /// Get vector as mutable slice - #[inline] - pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { - unsafe { mem::transmute(raw::Slice { data: self.ptr as *const T, len: self.cap as usize }) } - } - - /// Accessor - #[inline] - pub unsafe fn get<'a>(&'a self, index: usize) -> &'a T { - &self.as_slice()[index] - } - - /// Mutable accessor NOT for first use - #[inline] - pub unsafe fn get_mut<'a>(&'a mut self, index: usize) -> &'a mut T { - &mut self.as_mut_slice()[index] - } - - /// Mutable accessor for first use - #[inline] - pub unsafe fn init<'a>(&'a mut self, index: usize, value: T) { - ptr::write(&mut *self.ptr.offset(index as isize), value); - } - - /// Returns a slice starting from `index` - #[inline] - pub fn slice_from<'a>(&'a self, index: usize) -> &'a [T] { - self.as_slice().slice_from(index) - } - - /// Returns a slice ending just before `index` - #[inline] - pub fn slice_to<'a>(&'a self, index: usize) -> &'a [T] { - self.as_slice().slice_to(index) - } - - /// Returns a slice starting from `s` ending just before `e` - #[inline] - pub fn slice<'a>(&'a self, s: usize, e: usize) -> &'a [T] { - self.as_slice().slice(s, e) - } - - /// Push: always reallocates, try not to use this - #[inline] - pub fn push(&mut self, value: T) { - self.cap = self.cap.checked_add(&1).expect("ThinVec::push: length overflow"); - if mem::size_of::() == 0 { - unsafe { mem::forget(value); } - } else { - let old_size = (self.cap - 1) as usize * mem::size_of::(); - let new_size = self.cap as usize * mem::size_of::(); - if new_size < old_size { panic!("ThinVec::push: cap overflow") } - unsafe { - self.ptr = - if old_size == 0 { - allocate(new_size, mem::min_align_of::()) as *mut T - } else { - reallocate(self.ptr as *mut u8, new_size, - mem::min_align_of::(), self.cap as usize) as *mut T - }; - ptr::write(&mut *self.ptr.offset((self.cap - 1) as isize), value); - } - } - } - - /// Set the length of the vector to the minimum of the current capacity and new capacity - pub unsafe fn reserve(&mut self, new_cap: u32) { - if new_cap > self.cap { - let new_size = (new_cap as usize).checked_mul(&mem::size_of::()) - .expect("ThinVec::reserve: capacity overflow"); - self.ptr = - if self.cap == 0 { - allocate(new_size, mem::min_align_of::()) as *mut T - } else { - reallocate(self.ptr as *mut u8, new_size, - mem::min_align_of::(), self.cap as usize) as *mut T - }; - self.cap = new_cap; - } - } - - /// Increase the length of the vector - pub unsafe fn reserve_additional(&mut self, extra: u32) { - let new_cap = self.cap.checked_add(&extra).expect("ThinVec::reserve_additional: length overflow"); - self.reserve(new_cap); - } -} - -impl ThinVec { - /// Push an entire slice onto the ThinVec - #[inline] - pub fn push_all(&mut self, other: &[T]) { - let old_cap = self.cap as usize; - unsafe { self.reserve_additional(other.len() as u32); } - // Copied from vec.rs, which claims this will be optimized to a memcpy - // if T is Copy - for i in range(0, other.len()) { - unsafe { - ptr::write(self.as_mut_slice().unsafe_mut(old_cap + i), - other.unsafe_get(i).clone()); - } - } - } -} - -impl CloneableVector for ThinVec { - fn to_vec(&self) -> Vec { - self.as_slice().to_vec() - } - - fn into_vec(self) -> Vec { - unsafe { Vec::from_raw_parts(self.cap as usize, self.cap as usize, self.ptr) } - } -} - -impl Slice for ThinVec { - #[inline] - fn as_slice<'a>(&'a self) -> &'a [T] { - unsafe { mem::transmute(raw::Slice { data: self.ptr as *const T, len: self.cap as usize }) } - } -} - -impl Clone for ThinVec { - fn clone(&self) -> ThinVec { - unsafe { - let mut ret = ThinVec::with_capacity(self.len() as u32); - // Copied from vec.rs, which claims this will be optimized to a memcpy - // if T is Copy - for i in range(0, self.len()) { - ptr::write(ret.as_mut_slice().unsafe_mut(i), - self.as_slice().unsafe_get(i).clone()); - } - ret - } - } - - // TODO: clone_from -} - -impl FromIterator for ThinVec { - #[inline] - fn from_iter>(iter: I) -> ThinVec { - let (lower, _) = iter.size_hint(); - assert!(lower <= u32::MAX as usize); - unsafe { - let mut vector = ThinVec::with_capacity(lower as u32); - for (n, elem) in iter.enumerate() { - if n < lower { - vector.init(n, elem); - } else { - vector.push(elem); - } - } - vector - } - } -} - -impl Extendable for ThinVec { - #[inline] - fn extend>(&mut self, iter: I) { - let old_cap = self.cap; - let (lower, _) = iter.size_hint(); - unsafe { self.reserve_additional(lower as u32); } - for (n, elem) in iter.enumerate() { - if n < lower { - unsafe { self.init(old_cap as usize + n, elem) }; - } else { - self.push(elem); - } - } - } -} - -impl Collection for ThinVec { - #[inline] - fn len(&self) -> usize { self.cap as usize } -} - -impl fmt::Debug for ThinVec { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.as_slice().fmt(f) - } -} - -impl PartialEq for ThinVec { - #[inline] - fn eq(&self, other: &ThinVec) -> bool { - self.as_slice() == other.as_slice() - } -} - -impl Eq for ThinVec {} - -#[unsafe_destructor] -impl Drop for ThinVec { - fn drop(&mut self) { - if self.cap != 0 { - unsafe { - for x in self.as_mut_slice().iter() { - ptr::read(x); - } - if mem::size_of::() != 0 { - deallocate(self.ptr as *mut u8, - self.cap as usize * mem::size_of::(), - mem::min_align_of::()); - } - } - } - } -} - -#[cfg(test)] -mod tests { - use super::ThinVec; - - #[test] - fn simple_destructor_thinvec_test() { - let cap = 2; - unsafe { - let mut thinvec = ThinVec::with_capacity(cap); - - for i in range(0, cap) { - thinvec.init(i, Some(Box::new(i))); - } - - for i in range(0, cap) { - assert_eq!(thinvec.get_mut(i).take(), Some(Box::new(i))); - assert_eq!(thinvec.get_mut(i).take(), None); - } - } - } -} - diff --git a/src/util/uint.rs b/src/util/uint.rs index 236394f..7003a9a 100644 --- a/src/util/uint.rs +++ b/src/util/uint.rs @@ -41,9 +41,9 @@ macro_rules! construct_uint { /// Return the least number of bits needed to represent the number #[inline] - pub fn bits(&self) -> uzise { + pub fn bits(&self) -> usize { let &$name(ref arr) = self; - for i in range(1, $n_words) { + for i in 1..$n_words { if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as usize; } } 0x40 - arr[0].leading_zeros() @@ -54,7 +54,7 @@ macro_rules! construct_uint { let &$name(ref arr) = self; let mut carry = [0u64; $n_words]; let mut ret = [0u64; $n_words]; - for i in range(0, $n_words) { + for i in 0..$n_words { let upper = other as u64 * (arr[i] >> 32); let lower = other as u64 * (arr[i] & 0xFFFFFFFF); if i < 3 { @@ -66,7 +66,7 @@ macro_rules! construct_uint { } } - impl FromPrimitive for $name { + impl ::std::num::FromPrimitive for $name { #[inline] fn from_u64(init: u64) -> Option<$name> { let mut ret = [0; $n_words]; @@ -76,29 +76,28 @@ macro_rules! construct_uint { #[inline] fn from_i64(init: i64) -> Option<$name> { - FromPrimitive::from_u64(init as u64) + ::std::num::FromPrimitive::from_u64(init as u64) } } - impl Zero for $name { + impl ::std::num::Zero for $name { fn zero() -> $name { $name([0; $n_words]) } - fn is_zero(&self) -> bool { *self == Zero::zero() } } - impl One for $name { + impl ::std::num::One for $name { fn one() -> $name { $name({ let mut ret = [0; $n_words]; ret[0] = 1; ret }) } } - impl Add<$name,$name> for $name { + impl ::std::ops::Add<$name,$name> for $name { fn add(&self, other: &$name) -> $name { let &$name(ref me) = self; let &$name(ref you) = other; let mut ret = [0u64; $n_words]; let mut carry = [0u64; $n_words]; let mut b_carry = false; - for i in range(0, $n_words) { + for i in 0..$n_words { ret[i] = me[i] + you[i]; if i < $n_words - 1 && ret[i] < me[i] { carry[i + 1] = 1; @@ -109,25 +108,25 @@ macro_rules! construct_uint { } } - impl Sub<$name,$name> for $name { + impl ::std::ops::Sub<$name,$name> for $name { #[inline] fn sub(&self, other: &$name) -> $name { *self + !*other + One::one() } } - impl Mul<$name,$name> for $name { + impl ::std::ops::Mul<$name,$name> for $name { fn mul(&self, other: &$name) -> $name { let mut me = *self; // TODO: be more efficient about this - for i in range(0, 2 * $n_words) { + for i in 0..(2 * $n_words) { me = me + me.mul_u32((other >> (32 * i)).low_u32()) << (32 * i); } me } } - impl Div<$name,$name> for $name { + impl ::std::ops::Div<$name,$name> for $name { fn div(&self, other: &$name) -> $name { let mut sub_copy = *self; let mut shift_copy = *other; @@ -177,7 +176,7 @@ macro_rules! construct_uint { fn mask(&self, n: usize) -> $name { let &$name(ref arr) = self; let mut ret = [0; $n_words]; - for i in range(0, $n_words) { + for i in 0..$n_words { if n >= 0x40 * (i + 1) { ret[i] = arr[i]; } else { @@ -191,71 +190,71 @@ macro_rules! construct_uint { #[inline] fn trailing_zeros(&self) -> usize { let &$name(ref arr) = self; - for i in range(0, $n_words - 1) { + for i in 0..($n_words - 1) { if arr[i] > 0 { return (0x40 * i) + arr[i].trailing_zeros(); } } (0x40 * ($n_words - 1)) + arr[3].trailing_zeros() } } - impl BitAnd<$name,$name> for $name { + impl ::std::ops::BitAnd<$name,$name> for $name { #[inline] fn bitand(&self, other: &$name) -> $name { let &$name(ref arr1) = self; let &$name(ref arr2) = other; let mut ret = [0u64; $n_words]; - for i in range(0, $n_words) { + for i in 0..$n_words { ret[i] = arr1[i] & arr2[i]; } $name(ret) } } - impl BitXor<$name,$name> for $name { + impl ::std::ops::BitXor<$name,$name> for $name { #[inline] fn bitxor(&self, other: &$name) -> $name { let &$name(ref arr1) = self; let &$name(ref arr2) = other; let mut ret = [0u64; $n_words]; - for i in range(0, $n_words) { + for i in 0..$n_words { ret[i] = arr1[i] ^ arr2[i]; } $name(ret) } } - impl BitOr<$name,$name> for $name { + impl ::std::ops::BitOr<$name,$name> for $name { #[inline] fn bitor(&self, other: &$name) -> $name { let &$name(ref arr1) = self; let &$name(ref arr2) = other; let mut ret = [0u64; $n_words]; - for i in range(0, $n_words) { + for i in 0..$n_words { ret[i] = arr1[i] | arr2[i]; } $name(ret) } } - impl Not<$name> for $name { + impl ::std::ops::Not<$name> for $name { #[inline] fn not(&self) -> $name { let &$name(ref arr) = self; let mut ret = [0u64; $n_words]; - for i in range(0, $n_words) { + for i in 0..$n_words { ret[i] = !arr[i]; } $name(ret) } } - impl Shl for $name { + impl ::std::ops::Shl for $name { fn shl(&self, shift: &usize) -> $name { let &$name(ref original) = self; let mut ret = [0u64; $n_words]; let word_shift = *shift / 64; let bit_shift = *shift % 64; - for i in range(0, $n_words) { + for i in 0..$n_words { // Shift if bit_shift < 64 && i + word_shift < $n_words { ret[i + word_shift] += original[i] << bit_shift; @@ -269,14 +268,14 @@ macro_rules! construct_uint { } } - impl Shr for $name { + impl ::std::ops::Shr for $name { #[allow(unsigned_negate)] fn shr(&self, shift: &usize) -> $name { let &$name(ref original) = self; let mut ret = [0u64; $n_words]; let word_shift = *shift / 64; let bit_shift = *shift % 64; - for i in range(0, $n_words) { + for i in 0..$n_words { // Shift if bit_shift < 64 && i - word_shift < $n_words { ret[i - word_shift] += original[i] >> bit_shift; @@ -290,20 +289,20 @@ macro_rules! construct_uint { } } - impl Ord for $name { - fn cmp(&self, other: &$name) -> Ordering { + impl ::std::cmp::Ord for $name { + fn cmp(&self, other: &$name) -> ::std::cmp::Ordering { let &$name(ref me) = self; let &$name(ref you) = other; - for i in range(0, $n_words) { - if me[$n_words - 1 - i] < you[$n_words - 1 - i] { return Less; } - if me[$n_words - 1 - i] > you[$n_words - 1 - i] { return Greater; } + for i in 0..$n_words { + if me[$n_words - 1 - i] < you[$n_words - 1 - i] { return ::std::cmp::Ordering::Less; } + if me[$n_words - 1 - i] > you[$n_words - 1 - i] { return ::std::cmp::Ordering::Greater; } } - return Equal; + return ::std::cmp::Ordering::Equal; } } - impl PartialOrd for $name { - fn partial_cmp(&self, other: &$name) -> Option { + impl ::std::cmp::PartialOrd for $name { + fn partial_cmp(&self, other: &$name) -> Option<::std::cmp::Ordering> { Some(self.cmp(other)) } } diff --git a/src/wallet/address.rs b/src/wallet/address.rs index 0b68d86..f488440 100644 --- a/src/wallet/address.rs +++ b/src/wallet/address.rs @@ -21,7 +21,7 @@ use crypto::digest::Digest; use crypto::sha2::Sha256; use blockdata::script::Script; -use blockdata::opcodes::all; +use blockdata::opcodes; use network::constants::Network::{self, Bitcoin, BitcoinTestnet}; use util::hash::Ripemd160Hash; use util::base58::Base58Error::{self, InvalidLength, InvalidVersion}; @@ -61,11 +61,11 @@ impl Address { #[inline] pub fn script_pubkey(&self) -> Script { let mut script = Script::new(); - script.push_opcode(all::OP_DUP); - script.push_opcode(all::OP_HASH160); + script.push_opcode(opcodes::All::OP_DUP); + script.push_opcode(opcodes::All::OP_HASH160); script.push_slice(self.hash.as_slice()); - script.push_opcode(all::OP_EQUALVERIFY); - script.push_opcode(all::OP_CHECKSIG); + script.push_opcode(opcodes::All::OP_EQUALVERIFY); + script.push_opcode(opcodes::All::OP_CHECKSIG); script } } diff --git a/src/wallet/address_index.rs b/src/wallet/address_index.rs index 3c093e5..75453b6 100644 --- a/src/wallet/address_index.rs +++ b/src/wallet/address_index.rs @@ -86,7 +86,7 @@ impl AddressIndex { vout: idx, height: height, txo: txo.clone(), - kind: Unknown + kind: WalletTxOutType::Unknown }; ret.tentative_index.find_or_insert(txo.script_pubkey.clone(), vec![]).push(new); } diff --git a/src/wallet/bip32.rs b/src/wallet/bip32.rs index 720d43b..dd60c8a 100644 --- a/src/wallet/bip32.rs +++ b/src/wallet/bip32.rs @@ -17,7 +17,7 @@ //! at https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki use std::default::Default; -use serialize::{Decoder, Encoder}; +use serde; use byteorder::{ByteOrder, BigEndian}; use crypto::digest::Digest; @@ -51,7 +51,7 @@ impl Default for Fingerprint { } /// Extended private key -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub struct ExtendedPrivKey { /// The network this key is to be used on pub network: Network, @@ -68,7 +68,7 @@ pub struct ExtendedPrivKey { } /// Extended public key -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub struct ExtendedPubKey { /// The network this key is to be used on pub network: Network, @@ -93,18 +93,20 @@ pub enum ChildNumber { Normal(u32), } -impl, E> Encodable for ChildNumber { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl serde::Serialize for ChildNumber { + fn serialize(&self, s: &mut S) -> Result<(), S::Error> + where S: serde::Serializer { match *self { - ChildNumber::Hardened(n) => (n + (1 << 31)).encode(s), - ChildNumber::Normal(n) => n.encode(s) + ChildNumber::Hardened(n) => (n + (1 << 31)).serialize(s), + ChildNumber::Normal(n) => n.serialize(s) } } } -impl, E> RustcDecodable for ChildNumber { - fn decode(d: &mut D) -> Result { - let n: u32 = try!(RustcDecodable::decode(d)); +impl serde::Deserialize for ChildNumber { + fn deserialize(&self, d: &mut D) -> Result + where D: serde::Deserializer { + let n: u32 = try!(serde::Deserialize::decode(d)); if n < (1 << 31) { Ok(ChildNumber::Normal(n)) } else { @@ -139,7 +141,7 @@ impl ExtendedPrivKey { depth: 0, parent_fingerprint: Default::default(), child_number: ChildNumber::Normal(0), - secret_key: try!(SecretKey::from_slice(result.slice_to(32)).map_err(EcdsaError)), + secret_key: try!(SecretKey::from_slice(result.slice_to(32)).map_err(Error::EcdsaError)), chain_code: ChainCode::from_slice(result.slice_from(32)) }) } @@ -160,7 +162,7 @@ impl ExtendedPrivKey { let mut hmac = Hmac::new(Sha512::new(), self.chain_code.as_slice()); match i { ChildNumber::Normal(n) => { - if n >= (1 << 31) { return Err(InvalidChildNumber(i)) } + if n >= (1 << 31) { return Err(Error::InvalidChildNumber(i)) } // Non-hardened key: compute public data and use that secp256k1::init(); // Note the unwrap: this is fine, we checked the SK when we created it @@ -168,7 +170,7 @@ impl ExtendedPrivKey { hmac.write_u32::(n); } ChildNumber::Hardened(n) => { - if n >= (1 << 31) { return Err(InvalidChildNumber(i)) } + if n >= (1 << 31) { return Err(Error::InvalidChildNumber(i)) } // Hardened key: use only secret data to prevent public derivation hmac.input([0]); hmac.input(self.secret_key.as_slice()); @@ -176,8 +178,8 @@ impl ExtendedPrivKey { } } hmac.raw_result(result.as_mut_slice()); - let mut sk = try!(SecretKey::from_slice(result.slice_to(32)).map_err(EcdsaError)); - try!(sk.add_assign(&self.secret_key).map_err(EcdsaError)); + let mut sk = try!(SecretKey::from_slice(result.slice_to(32)).map_err(Error::EcdsaError)); + try!(sk.add_assign(&self.secret_key).map_err(Error::EcdsaError)); Ok(ExtendedPrivKey { network: self.network, @@ -232,9 +234,9 @@ impl ExtendedPubKey { match i { ChildNumber::Hardened(n) => { if n >= (1 << 31) { - Err(InvalidChildNumber(i)) + Err(Error::InvalidChildNumber(i)) } else { - Err(CannotDeriveFromHardenedKey) + Err(Error::CannotDeriveFromHardenedKey) } } ChildNumber::Normal(n) => { @@ -245,9 +247,9 @@ impl ExtendedPubKey { let mut result = [0; 64]; hmac.raw_result(result.as_mut_slice()); - let sk = try!(SecretKey::from_slice(result.slice_to(32)).map_err(EcdsaError)); + let sk = try!(SecretKey::from_slice(result.slice_to(32)).map_err(Error::EcdsaError)); let mut pk = self.public_key.clone(); - try!(pk.add_exp_assign(&sk).map_err(EcdsaError)); + try!(pk.add_exp_assign(&sk).map_err(Error::EcdsaError)); Ok(ExtendedPubKey { network: self.network, diff --git a/src/wallet/wallet.rs b/src/wallet/wallet.rs index e3b63ed..a6606f6 100644 --- a/src/wallet/wallet.rs +++ b/src/wallet/wallet.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use std::default::Default; -use serialize::{Decoder, Encoder}; +use serde; use secp256k1::key::PublicKey; @@ -54,9 +54,8 @@ pub enum AccountChain { } /// An account -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub struct Account { - name: String, internal_path: Vec, internal_used: Vec, internal_next: u32, @@ -68,7 +67,6 @@ pub struct Account { impl Default for Account { fn default() -> Account { Account { - name: String::new(), internal_path: vec![Hardened(0), Normal(1)], internal_used: vec![], internal_next: 0, @@ -87,39 +85,23 @@ pub struct Wallet { index: Option } -impl, E> Encodable for Wallet { - fn encode(&self, s: &mut S) -> Result<(), E> { - s.emit_struct("wallet", 2, |s| { - try!(s.emit_struct_field("master", 0, |s| self.master.encode(s))); - s.emit_struct_field("accounts", 1, - |s| s.emit_seq(self.accounts.len(), |s| { - for (_, account) in self.accounts.iter() { - try!(account.encode(s)); - } - Ok(()) - })) - }) +impl serde::Serialize for Wallet { + fn serialize(&self, s: &mut S) -> Result<(), S::Error> + where S: serde::Serializer { + let len = self.accounts.len(); + try!(self.master.serialize(s)); + self.accounts.serialize(s) } } -impl, E> Decodable for Wallet { - fn decode(d: &mut D) -> Result { - d.read_struct("wallet", 2, |d| { - Ok(Wallet { - master: try!(d.read_struct_field("master", 0, Decodable::decode)), - accounts: try!(d.read_struct_field("accounts", 1, |d| { - d.read_seq(|d, len| { - let mut ret = HashMap::new(); - for i in range(0, len) { - let accnt: Account = try!(d.read_seq_elt(i, Decodable::decode)); - ret.insert(accnt.name.clone(), accnt); - } - Ok(ret) - }) - })), +impl serde::Deserialize for Wallet { + fn deserialize(&self, d: &mut D) -> Result + where D: serde::Deserializer { + Wallet { + master: try!(serde::Deserialize::deserialize(d)), + accounts: try!(serde::Deserialize::deserialize(d)), index: None - }) - }) + } } } @@ -164,8 +146,7 @@ impl Wallet { } let idx = self.accounts.len() as u32; - self.accounts.insert(name.clone(), Account { - name: name, + self.accounts.insert(name, Account { internal_path: vec![Hardened(idx), Normal(1)], internal_used: vec![], internal_next: 0,