Giant collection of fixes ... we are into lifetime errors now :)
This commit is contained in:
parent
7b89c15ed5
commit
811df8a713
|
@ -97,7 +97,7 @@ impl BlockHeader {
|
|||
/// Performs an SPV validation of a block, which confirms that the proof-of-work
|
||||
/// is correct, but does not verify that the transactions are valid or encoded
|
||||
/// correctly.
|
||||
pub fn spv_validate(&self, required_target: &Uint256) -> error::Result<()> {
|
||||
pub fn spv_validate(&self, required_target: &Uint256) -> Result<(), error::Error> {
|
||||
let ref target = self.target();
|
||||
if target != required_target {
|
||||
return Err(SpvBadTarget);
|
||||
|
@ -132,7 +132,6 @@ impl BitcoinHash for Block {
|
|||
}
|
||||
|
||||
impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
|
||||
impl_json!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
|
||||
impl_consensus_encoding!(Block, header, txdata);
|
||||
impl_consensus_encoding!(LoneBlockHeader, header, tx_count);
|
||||
|
||||
|
|
|
@ -80,9 +80,9 @@ impl BlockchainNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for BlockchainNode {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for BlockchainNode {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(self.block.consensus_encode(s));
|
||||
try!(self.total_work.consensus_encode(s));
|
||||
try!(self.required_difficulty.consensus_encode(s));
|
||||
|
@ -93,9 +93,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for BlockchainNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for BlockchainNode {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for BlockchainNode {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<BlockchainNode, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<BlockchainNode, D::Error> {
|
||||
Ok(BlockchainNode {
|
||||
block: try!(ConsensusDecodable::consensus_decode(d)),
|
||||
total_work: try!(ConsensusDecodable::consensus_decode(d)),
|
||||
|
@ -123,9 +123,9 @@ pub struct Blockchain {
|
|||
genesis_hash: Sha256dHash
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Blockchain {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for Blockchain {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(self.network.consensus_encode(s));
|
||||
try!(self.tree.consensus_encode(s));
|
||||
try!(self.best_hash.consensus_encode(s));
|
||||
|
@ -134,8 +134,8 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Blockchain {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Blockchain {
|
||||
fn consensus_decode(d: &mut D) -> Result<Blockchain, E> {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for Blockchain {
|
||||
fn consensus_decode(d: &mut D) -> Result<Blockchain, D::Error> {
|
||||
let network: Network = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let mut tree: BlockTree = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let best_hash: Sha256dHash = try!(ConsensusDecodable::consensus_decode(d));
|
||||
|
@ -204,7 +204,9 @@ impl LocatorHashIter {
|
|||
}
|
||||
}
|
||||
|
||||
impl Iterator<Sha256dHash> for LocatorHashIter {
|
||||
impl Iterator for LocatorHashIter {
|
||||
type Item = Sha256dHash;
|
||||
|
||||
fn next(&mut self) -> Option<Sha256dHash> {
|
||||
if self.index.is_null() {
|
||||
return None;
|
||||
|
@ -274,7 +276,9 @@ pub struct RevStaleBlockIter<'tree> {
|
|||
chain: &'tree Blockchain
|
||||
}
|
||||
|
||||
impl<'tree> Iterator<&'tree BlockchainNode> for BlockIter<'tree> {
|
||||
impl<'tree> Iterator for BlockIter<'tree> {
|
||||
type Item = &'tree BlockchainNode;
|
||||
|
||||
fn next(&mut self) -> Option<&'tree BlockchainNode> {
|
||||
if self.index.is_null() {
|
||||
return None;
|
||||
|
@ -287,7 +291,9 @@ impl<'tree> Iterator<&'tree BlockchainNode> for BlockIter<'tree> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tree> Iterator<&'tree BlockchainNode> for RevBlockIter<'tree> {
|
||||
impl<'tree> Iterator for RevBlockIter<'tree> {
|
||||
type Item = &'tree BlockchainNode;
|
||||
|
||||
fn next(&mut self) -> Option<&'tree BlockchainNode> {
|
||||
if self.index.is_null() {
|
||||
return None;
|
||||
|
@ -300,7 +306,9 @@ impl<'tree> Iterator<&'tree BlockchainNode> for RevBlockIter<'tree> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tree> Iterator<&'tree Block> for RevStaleBlockIter<'tree> {
|
||||
impl<'tree> Iterator for RevStaleBlockIter<'tree> {
|
||||
type Item = &'tree Block;
|
||||
|
||||
fn next(&mut self) -> Option<&'tree Block> {
|
||||
if self.index.is_null() {
|
||||
return None;
|
||||
|
@ -365,7 +373,7 @@ impl Blockchain {
|
|||
}
|
||||
}
|
||||
|
||||
fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec<Transaction>, has_txdata: bool) -> error::Result<()> {
|
||||
fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec<Transaction>, has_txdata: bool) -> Result<(), error::Error> {
|
||||
match self.tree.lookup_mut(hash, 256) {
|
||||
Some(existing_block) => {
|
||||
unsafe {
|
||||
|
@ -405,26 +413,26 @@ impl Blockchain {
|
|||
}
|
||||
|
||||
/// Locates a block in the chain and overwrites its txdata
|
||||
pub fn add_txdata(&mut self, block: Block) -> error::Result<()> {
|
||||
pub fn add_txdata(&mut self, block: Block) -> Result<(), error::Error> {
|
||||
self.replace_txdata(&block.header.bitcoin_hash().into_le(), block.txdata, true)
|
||||
}
|
||||
|
||||
/// Locates a block in the chain and removes its txdata
|
||||
pub fn remove_txdata(&mut self, hash: Sha256dHash) -> error::Result<()> {
|
||||
pub fn remove_txdata(&mut self, hash: Sha256dHash) -> Result<(), error::Error> {
|
||||
self.replace_txdata(&hash.into_le(), vec![], false)
|
||||
}
|
||||
|
||||
/// Adds a block header to the chain
|
||||
pub fn add_header(&mut self, header: BlockHeader) -> error::Result<()> {
|
||||
pub fn add_header(&mut self, header: BlockHeader) -> Result<(), error::Error> {
|
||||
self.real_add_block(Block { header: header, txdata: vec![] }, false)
|
||||
}
|
||||
|
||||
/// Adds a block to the chain
|
||||
pub fn add_block(&mut self, block: Block) -> error::Result<()> {
|
||||
pub fn add_block(&mut self, block: Block) -> Result<(), error::Error> {
|
||||
self.real_add_block(block, true)
|
||||
}
|
||||
|
||||
fn real_add_block(&mut self, block: Block, has_txdata: bool) -> error::Result<()> {
|
||||
fn real_add_block(&mut self, block: Block, has_txdata: bool) -> Result<(), error::Error> {
|
||||
// get_prev optimizes the common case where we are extending the best tip
|
||||
#[inline]
|
||||
fn get_prev<'a>(chain: &'a Blockchain, hash: Sha256dHash) -> Option<NodePtr> {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use serialize::json;
|
||||
use serde;
|
||||
|
||||
// Heavy stick to translate between opcode types
|
||||
use std::mem::transmute;
|
||||
|
@ -602,23 +602,25 @@ impl All {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for All {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for All {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<All, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<All, D::Error> {
|
||||
Ok(All::from_u8(try!(d.read_u8())))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for All {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for All {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
s.emit_u8(*self as u8)
|
||||
}
|
||||
}
|
||||
|
||||
impl json::ToJson for All {
|
||||
fn to_json(&self) -> json::Json {
|
||||
json::String(self.to_string())
|
||||
impl serde::Serialize for All {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: serde::Serializer,
|
||||
{
|
||||
serializer.visit_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,9 +646,11 @@ pub enum Class {
|
|||
Ordinary(Ordinary)
|
||||
}
|
||||
|
||||
impl json::ToJson for Class {
|
||||
fn to_json(&self) -> json::Json {
|
||||
json::String(self.to_string())
|
||||
impl serde::Serialize for Class {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: serde::Serializer,
|
||||
{
|
||||
serializer.visit_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,9 @@ use crypto::digest::Digest;
|
|||
use crypto::ripemd160::Ripemd160;
|
||||
use crypto::sha1::Sha1;
|
||||
use crypto::sha2::Sha256;
|
||||
|
||||
use secp256k1::Secp256k1;
|
||||
use secp256k1::key::PublicKey;
|
||||
use serde;
|
||||
|
||||
use blockdata::opcodes;
|
||||
use blockdata::transaction::{Transaction, TxIn};
|
||||
|
@ -1207,9 +1207,11 @@ impl AbstractStack {
|
|||
}
|
||||
}
|
||||
|
||||
impl json::ToJson for Error {
|
||||
fn to_json(&self) -> json::Json {
|
||||
json::String(self.to_string())
|
||||
impl serde::Serialize for Error {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: serde::Serializer,
|
||||
{
|
||||
serializer.visit_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1238,8 +1240,6 @@ pub struct ScriptTrace {
|
|||
pub error: Option<Error>
|
||||
}
|
||||
|
||||
impl_json!(TraceIteration, index, opcode, op_count, executed, errored, effect, stack);
|
||||
|
||||
/// Hashtype of a transaction, encoded in the last byte of a signature,
|
||||
/// specifically in the last 5 bits `byte & 31`
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
|
@ -1337,11 +1337,11 @@ impl<'a> ops::Index<ops::RangeFrom<usize>> for MaybeOwned<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ops::Index<ops::RangeFull<usize>> for MaybeOwned<'a> {
|
||||
impl<'a> ops::Index<ops::RangeFull> for MaybeOwned<'a> {
|
||||
type Output = [u8];
|
||||
|
||||
#[inline]
|
||||
fn index(&self, _: ops::RangeFull<usize>) -> &[u8] {
|
||||
fn index(&self, _: ops::RangeFull) -> &[u8] {
|
||||
match *self {
|
||||
MaybeOwned::Owned(ref v) => &v[..],
|
||||
MaybeOwned::Borrowed(ref s) => &s[..]
|
||||
|
@ -1427,16 +1427,16 @@ pub fn read_scriptbool(v: &[u8]) -> bool {
|
|||
}
|
||||
|
||||
/// Read a script-encoded unsigned integer
|
||||
pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: usize)
|
||||
-> Result<usize, Error> {
|
||||
pub fn read_uint(data: &[u8], size: usize) -> Result<usize, Error> {
|
||||
if data.len() < size {
|
||||
Err(Error::EarlyEndOfScript)
|
||||
} else {
|
||||
let mut ret = 0;
|
||||
for i in 0..size {
|
||||
match iter.next() {
|
||||
Some(&n) => ret += (n as usize) << (i * 8),
|
||||
None => { return Err(Error::EarlyEndOfScript); }
|
||||
}
|
||||
ret += (data[i] as usize) << (i * 8);
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
/// Check a signature -- returns an error that is currently just translated
|
||||
|
@ -2477,31 +2477,30 @@ impl Default for Script {
|
|||
}
|
||||
|
||||
// User-facing serialization
|
||||
impl json::ToJson for Script {
|
||||
// TODO: put this in a struct alongside an opcode decode
|
||||
fn to_json(&self) -> json::Json {
|
||||
impl serde::Serialize for Script {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: serde::Serializer,
|
||||
{
|
||||
let &Script(ref raw) = self;
|
||||
let mut ret = String::new();
|
||||
for dat in raw.iter() {
|
||||
ret.push_char(from_digit((dat / 0x10) as usize, 16).unwrap());
|
||||
ret.push_char(from_digit((dat & 0x0f) as usize, 16).unwrap());
|
||||
serializer.visit_char(from_digit((dat / 0x10) as usize, 16).unwrap());
|
||||
serializer.visit_char(from_digit((dat & 0x0f) as usize, 16).unwrap());
|
||||
}
|
||||
json::String(ret)
|
||||
}
|
||||
}
|
||||
|
||||
// Network serialization
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Script {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for Script {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let &Script(ref data) = self;
|
||||
data.consensus_encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Script {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for Script {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Script, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Script, D::Error> {
|
||||
Ok(Script(try!(ConsensusDecodable::consensus_decode(d))))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
//!
|
||||
|
||||
use std::default::Default;
|
||||
use serialize::json;
|
||||
use serde;
|
||||
|
||||
use util::hash::Sha256dHash;
|
||||
use blockdata::script::{self, Script, ScriptTrace, read_scriptbool};
|
||||
|
@ -123,9 +123,11 @@ pub enum Error {
|
|||
InputNotFound(Sha256dHash, u32),
|
||||
}
|
||||
|
||||
impl json::ToJson for Error {
|
||||
fn to_json(&self) -> json::Json {
|
||||
json::String(self.to_string())
|
||||
impl serde::Serialize for Error {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: serde::Serializer,
|
||||
{
|
||||
serializer.visit_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,10 +142,6 @@ pub struct InputTrace {
|
|||
error: Option<Error>
|
||||
}
|
||||
|
||||
impl_json!(ScriptTrace, script, initial_stack, iterations, error);
|
||||
impl_json!(InputTrace, input_txid, input_vout, sig_trace,
|
||||
pubkey_trace, p2sh_trace, error);
|
||||
|
||||
/// A trace of a transaction's execution
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct TransactionTrace {
|
||||
|
@ -151,8 +149,6 @@ pub struct TransactionTrace {
|
|||
inputs: Vec<InputTrace>
|
||||
}
|
||||
|
||||
impl_json!(TransactionTrace, txid, inputs);
|
||||
|
||||
impl TxIn {
|
||||
/// Check an input's script for validity
|
||||
pub fn validate(&self,
|
||||
|
@ -304,12 +300,8 @@ impl BitcoinHash for Transaction {
|
|||
}
|
||||
|
||||
impl_consensus_encoding!(TxIn, prev_hash, prev_index, script_sig, sequence);
|
||||
impl_json!(TxIn, prev_hash, prev_index, script_sig, sequence);
|
||||
impl_consensus_encoding!(TxOut, value, script_pubkey);
|
||||
impl_json!(TxOut, value, script_pubkey);
|
||||
impl_consensus_encoding!(Transaction, version, input, output, lock_time);
|
||||
impl_json!(Transaction, version, input, output, lock_time);
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -74,7 +74,9 @@ pub struct UtxoIterator<'a> {
|
|||
tx_index: u32
|
||||
}
|
||||
|
||||
impl<'a> Iterator<(Sha256dHash, u32, &'a TxOut, u32)> for UtxoIterator<'a> {
|
||||
impl<'a> Iterator for UtxoIterator<'a> {
|
||||
type Item = (Sha256dHash, u32, &'a TxOut, u32);
|
||||
|
||||
fn next(&mut self) -> Option<(Sha256dHash, u32, &'a TxOut, u32)> {
|
||||
while self.current.is_some() {
|
||||
let current = &self.current.unwrap().outputs;
|
||||
|
|
|
@ -14,17 +14,17 @@
|
|||
|
||||
macro_rules! impl_consensus_encoding {
|
||||
($thing:ident, $($field:ident),+) => (
|
||||
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing {
|
||||
impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $thing {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
$( try!(self.$field.consensus_encode(s)); )+
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $thing {
|
||||
impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $thing {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<$thing, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<$thing, D::Error> {
|
||||
use network::encodable::ConsensusDecodable;
|
||||
Ok($thing {
|
||||
$( $field: try!(ConsensusDecodable::consensus_decode(d)), )+
|
||||
|
@ -36,37 +36,23 @@ macro_rules! impl_consensus_encoding {
|
|||
|
||||
macro_rules! impl_newtype_consensus_encoding {
|
||||
($thing:ident) => (
|
||||
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing {
|
||||
impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $thing {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let &$thing(ref data) = self;
|
||||
data.consensus_encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $thing {
|
||||
impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $thing {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<$thing, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<$thing, D::Error> {
|
||||
Ok($thing(try!(ConsensusDecodable::consensus_decode(d))))
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! impl_json {
|
||||
($thing:ident, $($field:ident),+) => (
|
||||
impl ::serialize::json::ToJson for $thing {
|
||||
fn to_json(&self) -> ::serialize::json::Json {
|
||||
use std::collections::BTreeMap;
|
||||
use serialize::json::{ToJson, Object};
|
||||
let mut ret = BTreeMap::new();
|
||||
$( ret.insert(stringify!($field).to_string(), self.$field.to_json()); )+
|
||||
Object(ret)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! impl_array_newtype {
|
||||
($thing:ident, $ty:ty, $len:expr) => {
|
||||
impl $thing {
|
||||
|
@ -201,32 +187,46 @@ macro_rules! impl_array_newtype {
|
|||
|
||||
macro_rules! impl_array_newtype_encodable {
|
||||
($thing:ident, $ty:ty, $len:expr) => {
|
||||
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $thing {
|
||||
fn decode(d: &mut D) -> Result<$thing, E> {
|
||||
use serialize::Decodable;
|
||||
|
||||
::assert_type_is_copy::<$ty>();
|
||||
impl ::serde::Deserialize for $thing {
|
||||
fn deserialize<D>(d: &mut D) -> Result<$thing, D::Error>
|
||||
where D: ::serde::Deserializer
|
||||
{
|
||||
// We have to define the Visitor struct inside the function
|
||||
// to make it local ... what we really need is that it's
|
||||
// local to the macro, but this is Close Enough.
|
||||
struct Visitor {
|
||||
marker: ::std::marker::PhantomData<$thing>,
|
||||
}
|
||||
impl ::serde::de::Visitor for Visitor {
|
||||
type Value = $thing;
|
||||
|
||||
d.read_seq(|d, len| {
|
||||
if len != $len {
|
||||
Err(d.error("Invalid length"))
|
||||
} else {
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, mut v: V) -> Result<$thing, V::Error>
|
||||
where V: ::serde::de::SeqVisitor
|
||||
{
|
||||
unsafe {
|
||||
use std::mem;
|
||||
let mut ret: [$ty; $len] = mem::uninitialized();
|
||||
for i in 0..len {
|
||||
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
|
||||
for i in 0..$len {
|
||||
ret[i] = try!(v.visit());
|
||||
}
|
||||
Ok($thing(ret))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Begin actual function
|
||||
d.visit(Visitor { marker: ::std::marker::PhantomData })
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: ::serialize::Encoder<S>, S> ::serialize::Encodable<E, S> for $thing {
|
||||
fn encode(&self, e: &mut E) -> Result<(), S> {
|
||||
self.as_slice().encode(e)
|
||||
impl ::serde::Serialize for $thing {
|
||||
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
|
||||
where S: ::serde::Serializer
|
||||
{
|
||||
let &$thing(ref dat) = self;
|
||||
(&dat[..]).serialize(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,17 +98,38 @@ macro_rules! user_enum {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: ::serialize::Encoder<E>, E> ::serialize::Encodable<S, E> for $name {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
s.emit_str(self.to_string().as_slice())
|
||||
impl ::serde::Deserialize for $name {
|
||||
#[inline]
|
||||
fn deserialize<D>(d: &mut D) -> Result<$name, D::Error>
|
||||
where D: ::serde::Deserializer
|
||||
{
|
||||
struct Visitor;
|
||||
impl ::serde::de::Visitor for Visitor {
|
||||
type Value = $name;
|
||||
|
||||
fn visit_string<E>(&mut self, v: String) -> Result<$name, E>
|
||||
where E: ::serde::de::Error
|
||||
{
|
||||
self.visit_str(&v)
|
||||
}
|
||||
|
||||
fn visit_str<E>(&mut self, s: &str) -> Result<$name, E>
|
||||
where E: ::serde::de::Error
|
||||
{
|
||||
$( if s == $txt { Ok($name::$elem) } )else*
|
||||
else { Err(::serde::de::Error::syntax_error()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl <D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $name {
|
||||
fn decode(d: &mut D) -> Result<$name, E> {
|
||||
let s = try!(d.read_str());
|
||||
$( if s.as_slice() == $txt { Ok($name::$elem) } )else*
|
||||
else { Err(d.error(format!("unknown `{}`", s).as_slice())) }
|
||||
d.visit(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::serde::Serialize for $name {
|
||||
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
|
||||
where S: ::serde::Serializer
|
||||
{
|
||||
s.visit_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -33,9 +33,9 @@ pub struct Address {
|
|||
pub port: u16
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Address {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for Address {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(self.services.consensus_encode(s));
|
||||
try!(self.address.consensus_encode(s));
|
||||
// Explicitly code the port since it needs to be big-endian
|
||||
|
@ -45,9 +45,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Address {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Address {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for Address {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Address, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Address, D::Error> {
|
||||
Ok(Address {
|
||||
services: try!(ConsensusDecodable::consensus_decode(d)),
|
||||
address: try!(ConsensusDecodable::consensus_decode(d)),
|
||||
|
|
|
@ -46,16 +46,16 @@ pub fn magic(network: Network) -> u32 {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Network {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for Network {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
magic(*self).consensus_encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Network {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for Network {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Network, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Network, D::Error> {
|
||||
let magic: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||
match magic {
|
||||
0xD9B4BEF9 => Ok(Network::Bitcoin),
|
||||
|
|
|
@ -38,15 +38,15 @@ use util::hash::Sha256dHash;
|
|||
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
||||
|
||||
/// Data which can be encoded in a consensus-consistent way
|
||||
pub trait ConsensusEncodable<S:SimpleEncoder<E>, E> {
|
||||
pub trait ConsensusEncodable<S: SimpleEncoder> {
|
||||
/// Encode an object with a well-defined format
|
||||
fn consensus_encode(&self, e: &mut S) -> Result<(), E>;
|
||||
fn consensus_encode(&self, e: &mut S) -> Result<(), S::Error>;
|
||||
}
|
||||
|
||||
/// Data which can be encoded in a consensus-consistent way
|
||||
pub trait ConsensusDecodable<D:SimpleDecoder<E>, E> {
|
||||
pub trait ConsensusDecodable<D: SimpleDecoder> {
|
||||
/// Decode an object with a well-defined format
|
||||
fn consensus_decode(d: &mut D) -> Result<Self, E>;
|
||||
fn consensus_decode(d: &mut D) -> Result<Self, D::Error>;
|
||||
}
|
||||
|
||||
/// A variable-length unsigned integer
|
||||
|
@ -58,39 +58,39 @@ pub struct VarInt(pub u64);
|
|||
pub struct CheckedData(pub Vec<u8>);
|
||||
|
||||
// Primitive types
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u8 {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for u8 {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u8(*self) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u8(*self) }
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u16 {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for u16 {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u16(self.to_le()) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u16(self.to_le()) }
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u32 {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for u32 {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u32(self.to_le()) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(self.to_le()) }
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u64 {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for u64 {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u64(self.to_le()) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u64(self.to_le()) }
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for i32 {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for i32 {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_i32(self.to_le()) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i32(self.to_le()) }
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for i64 {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for i64 {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_i64(self.to_le()) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i64(self.to_le()) }
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for VarInt {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for VarInt {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let &VarInt(n) = self;
|
||||
match n {
|
||||
0...0xFC => { (n as u8).consensus_encode(s) }
|
||||
|
@ -101,39 +101,39 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for VarInt {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u8 {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for u8 {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<u8, E> { d.read_u8() }
|
||||
fn consensus_decode(d: &mut D) -> Result<u8, D::Error> { d.read_u8() }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u16 {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for u16 {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<u16, E> { d.read_u16().map(|n| u16::from_le(n)) }
|
||||
fn consensus_decode(d: &mut D) -> Result<u16, D::Error> { d.read_u16().map(|n| u16::from_le(n)) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u32 {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for u32 {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<u32, E> { d.read_u32().map(|n| u32::from_le(n)) }
|
||||
fn consensus_decode(d: &mut D) -> Result<u32, D::Error> { d.read_u32().map(|n| u32::from_le(n)) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u64 {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for u64 {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<u64, E> { d.read_u64().map(|n| u64::from_le(n)) }
|
||||
fn consensus_decode(d: &mut D) -> Result<u64, D::Error> { d.read_u64().map(|n| u64::from_le(n)) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for i32 {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for i32 {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<i32, E> { d.read_i32().map(|n| i32::from_le(n)) }
|
||||
fn consensus_decode(d: &mut D) -> Result<i32, D::Error> { d.read_i32().map(|n| i32::from_le(n)) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for i64 {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for i64 {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<i64, E> { d.read_i64().map(|n| i64::from_le(n)) }
|
||||
fn consensus_decode(d: &mut D) -> Result<i64, D::Error> { d.read_i64().map(|n| i64::from_le(n)) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for VarInt {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for VarInt {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<VarInt, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<VarInt, D::Error> {
|
||||
let n = try!(d.read_u8());
|
||||
match n {
|
||||
0xFF => d.read_u64().map(|n| VarInt(u64::from_le(n))),
|
||||
|
@ -145,27 +145,27 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for VarInt {
|
|||
}
|
||||
|
||||
// Booleans
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for bool {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for bool {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u8(if *self {1} else {0}) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u8(if *self {1} else {0}) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for bool {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for bool {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<bool, E> { d.read_u8().map(|n| n != 0) }
|
||||
fn consensus_decode(d: &mut D) -> Result<bool, D::Error> { d.read_u8().map(|n| n != 0) }
|
||||
}
|
||||
|
||||
// Strings
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for String {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for String {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
self.as_bytes().consensus_encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for String {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for String {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<String, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<String, D::Error> {
|
||||
String::from_utf8(try!(ConsensusDecodable::consensus_decode(d))).map_err(|_| d.error("String was not valid UTF8"))
|
||||
}
|
||||
}
|
||||
|
@ -174,17 +174,17 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for String {
|
|||
// Arrays
|
||||
macro_rules! impl_array {
|
||||
( $size:expr ) => (
|
||||
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for [T; $size] {
|
||||
impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for [T; $size] {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
for i in self.iter() { try!(i.consensus_encode(s)); }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>+Copy> ConsensusDecodable<D, E> for [T; $size] {
|
||||
impl<D: SimpleDecoder, T:ConsensusDecodable<D> + Copy> ConsensusDecodable<D> for [T; $size] {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<[T; $size], E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<[T; $size], D::Error> {
|
||||
// Set everything to the first decode
|
||||
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size];
|
||||
// Set the rest
|
||||
|
@ -202,9 +202,9 @@ impl_array!(12);
|
|||
impl_array!(16);
|
||||
impl_array!(32);
|
||||
|
||||
impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for &'a [T] {
|
||||
impl<'a, S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for &'a [T] {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(VarInt(self.len() as u64).consensus_encode(s));
|
||||
for c in self.iter() { try!(c.consensus_encode(s)); }
|
||||
Ok(())
|
||||
|
@ -214,14 +214,14 @@ impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S
|
|||
// Cannot decode a slice
|
||||
|
||||
// Vectors
|
||||
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Vec<T> {
|
||||
impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Vec<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<(), S::Error> { self.as_slice().consensus_encode(s) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Vec<T> {
|
||||
impl<D: SimpleDecoder, T: ConsensusDecodable<D>> ConsensusDecodable<D> for Vec<T> {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Vec<T>, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Vec<T>, D::Error> {
|
||||
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let mut ret = Vec::with_capacity(len as usize);
|
||||
for _ in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); }
|
||||
|
@ -229,14 +229,14 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
|
|||
}
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Box<[T]> {
|
||||
impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Box<[T]> {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { (&self[..]).consensus_encode(s) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { (&self[..]).consensus_encode(s) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Box<[T]> {
|
||||
impl<D: SimpleDecoder, T: ConsensusDecodable<D>> ConsensusDecodable<D> for Box<[T]> {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Box<[T]>, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Box<[T]>, D::Error> {
|
||||
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
|
||||
unsafe {
|
||||
let len = len as usize;
|
||||
|
@ -248,9 +248,9 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
|
|||
}
|
||||
|
||||
// Options (encoded as vectors of length 0 or 1)
|
||||
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Option<T> {
|
||||
impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Option<T> {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
match *self {
|
||||
Some(ref data) => {
|
||||
try!(1u8.consensus_encode(s));
|
||||
|
@ -262,9 +262,9 @@ impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E>
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Option<T> {
|
||||
impl<D: SimpleDecoder, T:ConsensusDecodable<D>> ConsensusDecodable<D> for Option<T> {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Option<T>, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Option<T>, D::Error> {
|
||||
let bit: u8 = try!(ConsensusDecodable::consensus_decode(d));
|
||||
Ok(if bit != 0 {
|
||||
Some(try!(ConsensusDecodable::consensus_decode(d)))
|
||||
|
@ -282,9 +282,9 @@ fn sha2_checksum(data: &[u8]) -> [u8; 4] {
|
|||
}
|
||||
|
||||
// Checked data
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CheckedData {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for CheckedData {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let &CheckedData(ref data) = self;
|
||||
try!((data.len() as u32).consensus_encode(s));
|
||||
try!(sha2_checksum(data.as_slice()).consensus_encode(s));
|
||||
|
@ -296,9 +296,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CheckedData {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for CheckedData {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<CheckedData, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<CheckedData, D::Error> {
|
||||
let len: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let mut ret = Vec::with_capacity(len as usize);
|
||||
|
@ -315,53 +315,53 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
|
|||
// Tuples
|
||||
macro_rules! tuple_encode {
|
||||
($($x:ident),*) => (
|
||||
impl <SS:SimpleEncoder<EE>, EE, $($x: ConsensusEncodable<SS, EE>),*> ConsensusEncodable<SS, EE> for ($($x),*) {
|
||||
impl <S: SimpleEncoder, $($x: ConsensusEncodable<S>),*> ConsensusEncodable<S> for ($($x),*) {
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn consensus_encode(&self, s: &mut SS) -> Result<(), EE> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let &($(ref $x),*) = self;
|
||||
$( try!($x.consensus_encode(s)); )*
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<DD:SimpleDecoder<EE>, EE, $($x: ConsensusDecodable<DD, EE>),*> ConsensusDecodable<DD, EE> for ($($x),*) {
|
||||
impl<D: SimpleDecoder, $($x: ConsensusDecodable<D>),*> ConsensusDecodable<D> for ($($x),*) {
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn consensus_decode(d: &mut DD) -> Result<($($x),*), EE> {
|
||||
fn consensus_decode(d: &mut D) -> Result<($($x),*), D::Error> {
|
||||
Ok(($(try!({let $x = ConsensusDecodable::consensus_decode(d); $x })),*))
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
tuple_encode!(A, B);
|
||||
tuple_encode!(A, B, C, D);
|
||||
tuple_encode!(A, B, C, D, E, F);
|
||||
tuple_encode!(A, B, C, D, E, F, G, H);
|
||||
|
||||
tuple_encode!(T0, T1);
|
||||
tuple_encode!(T0, T1, T2, T3);
|
||||
tuple_encode!(T0, T1, T2, T3, T4, T5);
|
||||
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
|
||||
|
||||
// References
|
||||
impl<S:SimpleEncoder<E>, E, T: ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Box<T> {
|
||||
impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Box<T> {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { (**self).consensus_encode(s) }
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).consensus_encode(s) }
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, T: ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Box<T> {
|
||||
impl<D: SimpleDecoder, T: ConsensusDecodable<D>> ConsensusDecodable<D> for Box<T> {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Box<T>, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Box<T>, D::Error> {
|
||||
ConsensusDecodable::consensus_decode(d).map(|res| Box::new(res))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// HashMap
|
||||
impl<S:SimpleEncoder<E>, E, T,
|
||||
K:ConsensusEncodable<S,E>+Eq+Hash<T>,
|
||||
V:ConsensusEncodable<S,E>,
|
||||
H:Hasher<T>+Default> ConsensusEncodable<S, E> for HashMap<K, V, H> {
|
||||
impl<S, K, V, H> ConsensusEncodable<S> for HashMap<K, V, H>
|
||||
where S: SimpleEncoder,
|
||||
H: Hasher + Default,
|
||||
K: ConsensusEncodable<S> + Eq + Hash,
|
||||
V: ConsensusEncodable<S>
|
||||
{
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(VarInt(self.len() as u64).consensus_encode(s));
|
||||
for (key, value) in self.iter() {
|
||||
try!(key.consensus_encode(s));
|
||||
|
@ -371,12 +371,14 @@ impl<S:SimpleEncoder<E>, E, T,
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, T,
|
||||
K:ConsensusDecodable<D,E>+Eq+Hash<T>,
|
||||
V:ConsensusDecodable<D,E>,
|
||||
H:Hasher<T>+Default> ConsensusDecodable<D, E> for HashMap<K, V, H> {
|
||||
impl<D, K, V, H> ConsensusDecodable<D> for HashMap<K, V, H>
|
||||
where D: SimpleDecoder,
|
||||
H: Hasher + Default,
|
||||
K: ConsensusDecodable<D> + Eq + Hash,
|
||||
V: ConsensusDecodable<D>
|
||||
{
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<HashMap<K, V, H>, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<HashMap<K, V, H>, D::Error> {
|
||||
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
|
||||
|
||||
let mut ret = HashMap::with_capacity_and_hasher(len as usize, Default::default());
|
||||
|
|
|
@ -38,9 +38,9 @@ use util::misc::prepend_err;
|
|||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct CommandString(pub String);
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for CommandString {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let &CommandString(ref inner_str) = self;
|
||||
let mut rawbytes = [0u8; 12];
|
||||
rawbytes.clone_from_slice(inner_str.as_bytes().as_slice());
|
||||
|
@ -48,9 +48,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CommandString {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for CommandString {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<CommandString, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<CommandString, D::Error> {
|
||||
let rawbytes: [u8; 12] = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None }));
|
||||
Ok(CommandString(rv))
|
||||
|
@ -133,8 +133,8 @@ impl RawNetworkMessage {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for RawNetworkMessage {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for RawNetworkMessage {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(self.magic.consensus_encode(s));
|
||||
try!(CommandString(self.command()).consensus_encode(s));
|
||||
try!(CheckedData(match self.payload {
|
||||
|
@ -156,7 +156,7 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for RawNetworkMessage {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<io::Error>> ConsensusDecodable<D, io::Error> for RawNetworkMessage {
|
||||
impl<D: SimpleDecoder<Error=io::Error>> ConsensusDecodable<D> for RawNetworkMessage {
|
||||
fn consensus_decode(d: &mut D) -> io::Result<RawNetworkMessage> {
|
||||
let magic = try!(ConsensusDecodable::consensus_decode(d));
|
||||
let CommandString(cmd): CommandString= try!(ConsensusDecodable::consensus_decode(d));
|
||||
|
|
|
@ -97,9 +97,9 @@ impl GetHeadersMessage {
|
|||
|
||||
impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash);
|
||||
|
||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory {
|
||||
impl<S: SimpleEncoder> ConsensusEncodable<S> for Inventory {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
try!(match self.inv_type {
|
||||
InvType::Error => 0u32,
|
||||
InvType::Transaction => 1,
|
||||
|
@ -109,9 +109,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Inventory {
|
||||
impl<D: SimpleDecoder> ConsensusDecodable<D> for Inventory {
|
||||
#[inline]
|
||||
fn consensus_decode(d: &mut D) -> Result<Inventory, E> {
|
||||
fn consensus_decode(d: &mut D) -> Result<Inventory, D::Error> {
|
||||
let int_type: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||
Ok(Inventory {
|
||||
inv_type: match int_type {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
//! capabilities
|
||||
//!
|
||||
|
||||
use std::io::Result;
|
||||
use std::io;
|
||||
|
||||
use network::constants;
|
||||
use network::address::Address;
|
||||
|
@ -54,7 +54,7 @@ pub struct VersionMessage {
|
|||
impl VersionMessage {
|
||||
// TODO: we have fixed services and relay to 0
|
||||
/// Constructs a new `version` message
|
||||
pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> Result<VersionMessage> {
|
||||
pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> io::Result<VersionMessage> {
|
||||
let recv_addr = socket.receiver_address();
|
||||
let send_addr = socket.sender_address();
|
||||
// If we are not connected, we might not be able to get these address.s
|
||||
|
@ -88,7 +88,7 @@ impl_consensus_encoding!(VersionMessage, version, services, timestamp,
|
|||
mod tests {
|
||||
use super::VersionMessage;
|
||||
|
||||
use std::io::Result;
|
||||
use std::io;
|
||||
use serialize::hex::FromHex;
|
||||
|
||||
use network::serialize::{deserialize, serialize};
|
||||
|
@ -98,7 +98,7 @@ mod tests {
|
|||
// This message is from my satoshi node, morning of May 27 2014
|
||||
let from_sat = "721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001".from_hex().unwrap();
|
||||
|
||||
let decode: Result<VersionMessage> = deserialize(from_sat.clone());
|
||||
let decode: io::Result<VersionMessage> = deserialize(from_sat.clone());
|
||||
assert!(decode.is_ok());
|
||||
let real_decode = decode.unwrap();
|
||||
assert_eq!(real_decode.version, 70002);
|
||||
|
|
|
@ -39,20 +39,20 @@ impl BitcoinHash for Vec<u8> {
|
|||
}
|
||||
|
||||
/// Encode an object into a vector
|
||||
pub fn serialize<T: ConsensusEncodable<RawEncoder<Cursor>, io::Error>>(obj: &T) -> io::Result<Vec<u8>> {
|
||||
pub fn serialize<T: ConsensusEncodable<RawEncoder<Cursor<Vec<u8>>>>>(obj: &T) -> io::Result<Vec<u8>> {
|
||||
let mut encoder = RawEncoder::new(Cursor::new(vec![]));
|
||||
try!(obj.consensus_encode(&mut encoder));
|
||||
Ok(encoder.unwrap().unwrap())
|
||||
}
|
||||
|
||||
/// Encode an object into a hex-encoded string
|
||||
pub fn serialize_hex<T: ConsensusEncodable<RawEncoder<Cursor>, io::Error>>(obj: &T) -> io::Result<String> {
|
||||
pub fn serialize_hex<T: ConsensusEncodable<RawEncoder<Cursor<Vec<u8>>>>>(obj: &T) -> io::Result<String> {
|
||||
let serial = try!(serialize(obj));
|
||||
Ok(serial.as_slice().to_hex())
|
||||
}
|
||||
|
||||
/// Deserialize an object from a vector
|
||||
pub fn deserialize<T: ConsensusDecodable<RawDecoder<Cursor>, io::Error>>(data: Vec<u8>) -> io::Result<T> {
|
||||
pub fn deserialize<T: ConsensusDecodable<RawDecoder<Cursor<Vec<u8>>>>>(data: Vec<u8>) -> io::Result<T> {
|
||||
let mut decoder = RawDecoder::new(Cursor::new(data));
|
||||
ConsensusDecodable::consensus_decode(&mut decoder)
|
||||
}
|
||||
|
@ -92,59 +92,65 @@ impl<R:Read> RawDecoder<R> {
|
|||
}
|
||||
|
||||
/// A simple Encoder trait
|
||||
pub trait SimpleEncoder<E> {
|
||||
pub trait SimpleEncoder {
|
||||
type Error;
|
||||
|
||||
/// Output a 64-bit uint
|
||||
fn emit_u64(&mut self, v: u64) -> Result<(), E>;
|
||||
fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
|
||||
/// Output a 32-bit uint
|
||||
fn emit_u32(&mut self, v: u32) -> Result<(), E>;
|
||||
fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>;
|
||||
/// Output a 16-bit uint
|
||||
fn emit_u16(&mut self, v: u16) -> Result<(), E>;
|
||||
fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>;
|
||||
/// Output a 8-bit uint
|
||||
fn emit_u8(&mut self, v: u8) -> Result<(), E>;
|
||||
fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>;
|
||||
|
||||
/// Output a 64-bit int
|
||||
fn emit_i64(&mut self, v: i64) -> Result<(), E>;
|
||||
fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>;
|
||||
/// Output a 32-bit int
|
||||
fn emit_i32(&mut self, v: i32) -> Result<(), E>;
|
||||
fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>;
|
||||
/// Output a 16-bit int
|
||||
fn emit_i16(&mut self, v: i16) -> Result<(), E>;
|
||||
fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>;
|
||||
/// Output a 8-bit int
|
||||
fn emit_i8(&mut self, v: i8) -> Result<(), E>;
|
||||
fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error>;
|
||||
|
||||
/// Output a boolean
|
||||
fn emit_bool(&mut self, v: bool) -> Result<(), E>;
|
||||
fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
/// A simple Decoder trait
|
||||
pub trait SimpleDecoder<E> {
|
||||
pub trait SimpleDecoder {
|
||||
type Error;
|
||||
|
||||
/// Read a 64-bit uint
|
||||
fn read_u64(&mut self) -> Result<u64, E>;
|
||||
fn read_u64(&mut self) -> Result<u64, Self::Error>;
|
||||
/// Read a 32-bit uint
|
||||
fn read_u32(&mut self) -> Result<u32, E>;
|
||||
fn read_u32(&mut self) -> Result<u32, Self::Error>;
|
||||
/// Read a 16-bit uint
|
||||
fn read_u16(&mut self) -> Result<u16, E>;
|
||||
fn read_u16(&mut self) -> Result<u16, Self::Error>;
|
||||
/// Read a 8-bit uint
|
||||
fn read_u8(&mut self) -> Result<u8, E>;
|
||||
fn read_u8(&mut self) -> Result<u8, Self::Error>;
|
||||
|
||||
/// Read a 64-bit int
|
||||
fn read_i64(&mut self) -> Result<i64, E>;
|
||||
fn read_i64(&mut self) -> Result<i64, Self::Error>;
|
||||
/// Read a 32-bit int
|
||||
fn read_i32(&mut self) -> Result<i32, E>;
|
||||
fn read_i32(&mut self) -> Result<i32, Self::Error>;
|
||||
/// Read a 16-bit int
|
||||
fn read_i16(&mut self) -> Result<i16, E>;
|
||||
fn read_i16(&mut self) -> Result<i16, Self::Error>;
|
||||
/// Read a 8-bit int
|
||||
fn read_i8(&mut self) -> Result<i8, E>;
|
||||
fn read_i8(&mut self) -> Result<i8, Self::Error>;
|
||||
|
||||
/// Read a boolean
|
||||
fn read_bool(&mut self) -> Result<bool, E>;
|
||||
fn read_bool(&mut self) -> Result<bool, Self::Error>;
|
||||
|
||||
/// Signal a decoding error
|
||||
fn error(&mut self, err: &str) -> E;
|
||||
fn error(&mut self, err: &str) -> Self::Error;
|
||||
}
|
||||
|
||||
// TODO: trait reform: impl SimpleEncoder for every Encoder, ditto for Decoder
|
||||
|
||||
impl<W:Write> SimpleEncoder<io::Error> for RawEncoder<W> {
|
||||
impl<W: Write> SimpleEncoder for RawEncoder<W> {
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn emit_u64(&mut self, v: u64) -> io::Result<()> { self.writer.write_le_u64(v) }
|
||||
#[inline]
|
||||
|
@ -167,7 +173,9 @@ impl<W:Write> SimpleEncoder<io::Error> for RawEncoder<W> {
|
|||
fn emit_bool(&mut self, v: bool) -> io::Result<()> { self.writer.write_i8(if v {1} else {0}) }
|
||||
}
|
||||
|
||||
impl<R:Read> SimpleDecoder<io::Error> for RawDecoder<R> {
|
||||
impl<R: Read> SimpleDecoder for RawDecoder<R> {
|
||||
type Error = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn read_u64(&mut self) -> io::Result<u64> { self.reader.read_le_u64() }
|
||||
#[inline]
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
use std::string;
|
||||
use std::str;
|
||||
|
||||
use util::hash::Sha256dHash;
|
||||
|
||||
|
@ -132,7 +132,7 @@ pub fn base58_encode_slice(data: &[u8]) -> String {
|
|||
// Unsafely translate the bytes to a utf8 string
|
||||
unsafe {
|
||||
// Copy leading zeroes directly
|
||||
let mut ret = string::raw::from_utf8(data.iter().take_while(|&&x| x == 0)
|
||||
let mut ret = str::from_utf8(data.iter().take_while(|&&x| x == 0)
|
||||
.map(|_| BASE58_CHARS[0])
|
||||
.collect());
|
||||
// Copy rest of string
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
use std::io;
|
||||
|
||||
/// A success/failure return value
|
||||
pub type Result<T> = Result<T, Error>;
|
||||
|
||||
/// A general error code
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Error {
|
||||
|
|
|
@ -22,7 +22,7 @@ use std::fmt;
|
|||
use std::io::Cursor;
|
||||
use std::mem::transmute;
|
||||
use std::hash;
|
||||
use serialize::json::{self, ToJson};
|
||||
use serde;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use crypto::digest::Digest;
|
||||
|
@ -160,38 +160,49 @@ impl Sha256dHash {
|
|||
// used only for user-facing stuff. Internal and network serialization is
|
||||
// little-endian and should be done using the consensus `encodable::ConsensusEncodable`
|
||||
// interface.
|
||||
impl ToJson for Sha256dHash {
|
||||
#[inline]
|
||||
fn to_json(&self) -> json::Json {
|
||||
json::String(self.be_hex_string())
|
||||
impl serde::Serialize for Sha256dHash {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: serde::Serializer,
|
||||
{
|
||||
serializer.visit_str(&self.be_hex_string())
|
||||
}
|
||||
}
|
||||
|
||||
// Non-consensus encoding (big-endian hex string)
|
||||
impl<S: ::serialize::Encoder<E>, E> ::serialize::Encodable<S, E> for Sha256dHash {
|
||||
impl serde::Deserialize for Sha256dHash {
|
||||
#[inline]
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
s.emit_str(self.be_hex_string().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for Sha256dHash {
|
||||
#[inline]
|
||||
fn decode(d: &mut D) -> Result<Sha256dHash, E> {
|
||||
fn deserialize<D>(d: &mut D) -> Result<Sha256dHash, D::Error>
|
||||
where D: serde::Deserializer
|
||||
{
|
||||
use serialize::hex::FromHex;
|
||||
|
||||
let hex_str = try!(d.read_str());
|
||||
struct Sha256dHashVisitor;
|
||||
impl serde::de::Visitor for Sha256dHashVisitor {
|
||||
type Value = Sha256dHash;
|
||||
|
||||
fn visit_string<E>(&mut self, v: String) -> Result<Sha256dHash, E>
|
||||
where E: serde::de::Error
|
||||
{
|
||||
self.visit_str(&v)
|
||||
}
|
||||
|
||||
fn visit_str<E>(&mut self, hex_str: &str) -> Result<Sha256dHash, E>
|
||||
where E: serde::de::Error
|
||||
{
|
||||
if hex_str.len() != 64 {
|
||||
d.error("incorrect hash length");
|
||||
return Err(serde::de::Error::syntax_error());
|
||||
}
|
||||
let raw_str = try!(hex_str.as_slice().from_hex()
|
||||
.map_err(|_| d.error("non-hexadecimal hash string")));
|
||||
.map_err(|_| serde::de::Error::syntax_error()));
|
||||
let mut ret = [0u8; 32];
|
||||
for i in 0..32 {
|
||||
ret[i] = raw_str[31 - i];
|
||||
}
|
||||
Ok(Sha256dHash(ret))
|
||||
}
|
||||
}
|
||||
|
||||
d.visit(Sha256dHashVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
// Consensus encoding (little-endian)
|
||||
|
|
|
@ -18,14 +18,18 @@
|
|||
//! standard library.
|
||||
|
||||
/// An iterator that returns pairs of elements
|
||||
pub struct Pair<A, I> {
|
||||
pub struct Pair<I>
|
||||
where I: Iterator
|
||||
{
|
||||
iter: I,
|
||||
last_elem: Option<A>
|
||||
last_elem: Option<I::Item>
|
||||
}
|
||||
|
||||
impl<A, I: Iterator<A>> Iterator<(A, A)> for Pair<A, I> {
|
||||
impl<I: Iterator> Iterator for Pair<I> {
|
||||
type Item = (I::Item, I::Item);
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<(A, A)> {
|
||||
fn next(&mut self) -> Option<(I::Item, I::Item)> {
|
||||
let elem1 = self.iter.next();
|
||||
if elem1.is_none() {
|
||||
None
|
||||
|
@ -49,28 +53,28 @@ impl<A, I: Iterator<A>> Iterator<(A, A)> for Pair<A, I> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<A, I: Iterator<A>> Pair<A, I> {
|
||||
impl<I: Iterator> Pair<I> {
|
||||
/// Returns the last element of the iterator if there were an odd
|
||||
/// number of elements remaining before it was Pair-ified.
|
||||
#[inline]
|
||||
pub fn remainder(self) -> Option<A> {
|
||||
pub fn remainder(self) -> Option<I::Item> {
|
||||
self.last_elem
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator that returns elements of the original iterator 2 at a time
|
||||
pub trait Pairable<A> {
|
||||
pub trait Pairable {
|
||||
/// Returns an iterator that returns elements of the original iterator 2 at a time
|
||||
fn pair(self) -> Pair<A, Self>;
|
||||
fn pair(self) -> Pair<Self>;
|
||||
}
|
||||
|
||||
impl<A, I: Iterator<A>> Pairable<A> for I {
|
||||
impl<I: Iterator> Pairable for I {
|
||||
/// Creates an iterator that yields pairs ef elements from the underlying
|
||||
/// iterator, yielding `None` when there are fewer than two elements to
|
||||
/// return.
|
||||
#[inline]
|
||||
fn pair(self) -> Pair<A, I> {
|
||||
Pair{iter: self, last_elem: None}
|
||||
fn pair(self) -> Pair<I> {
|
||||
Pair {iter: self, last_elem: None }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@ pub struct PatriciaTree<K, V> {
|
|||
skip_len: u8
|
||||
}
|
||||
|
||||
impl<K:BitArray+cmp::Eq+Zero+One+ops::BitXor<K,K>+ops::Shl<usize,K>+ops::Shr<usize,K>, V> PatriciaTree<K, V> {
|
||||
impl<K, V> PatriciaTree<K, V>
|
||||
where K: BitArray + cmp::Eq + Zero + One + ops::BitXor<K> + ops::Shl<usize> + ops::Shr<usize>
|
||||
{
|
||||
/// Constructs a new Patricia tree
|
||||
pub fn new() -> PatriciaTree<K, V> {
|
||||
PatriciaTree {
|
||||
|
@ -214,7 +216,9 @@ impl<K:BitArray+cmp::Eq+Zero+One+ops::BitXor<K,K>+ops::Shl<usize,K>+ops::Shr<usi
|
|||
pub fn delete(&mut self, key: &K, key_len: usize) -> Option<V> {
|
||||
/// Return value is (deletable, actual return value), where `deletable` is true
|
||||
/// is true when the entire node can be deleted (i.e. it has no children)
|
||||
fn recurse<K:BitArray+cmp::Eq+Zero+One+ops::Add<K,K>+ops::Shr<usize,K>+ops::Shl<usize,K>, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>) {
|
||||
fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
|
||||
where K: BitArray + cmp::Eq + Zero + One + ops::Add<K> + ops::Shr<usize> + ops::Shl<usize>
|
||||
{
|
||||
// If the search key is shorter than the node prefix, there is no
|
||||
// way we can match, so fail.
|
||||
if key_len < tree.skip_len as usize {
|
||||
|
@ -386,8 +390,12 @@ impl<K:BitArray, V:Debug> PatriciaTree<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S:SimpleEncoder<E>, E, K:ConsensusEncodable<S, E>, V:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for PatriciaTree<K, V> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
impl<S, K, V> ConsensusEncodable<S> for PatriciaTree<K, V>
|
||||
where S: SimpleEncoder,
|
||||
K: ConsensusEncodable<S>,
|
||||
V: ConsensusEncodable<S>
|
||||
{
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
// Depth-first serialization: serialize self, then children
|
||||
try!(self.skip_prefix.consensus_encode(s));
|
||||
try!(self.skip_len.consensus_encode(s));
|
||||
|
@ -398,8 +406,12 @@ impl<S:SimpleEncoder<E>, E, K:ConsensusEncodable<S, E>, V:ConsensusEncodable<S,
|
|||
}
|
||||
}
|
||||
|
||||
impl<D:SimpleDecoder<E>, E, K:ConsensusDecodable<D, E>, V:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for PatriciaTree<K, V> {
|
||||
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, E> {
|
||||
impl<D, K, V> ConsensusDecodable<D> for PatriciaTree<K, V>
|
||||
where D: SimpleDecoder,
|
||||
K: ConsensusDecodable<D>,
|
||||
V: ConsensusDecodable<D>
|
||||
{
|
||||
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, D::Error> {
|
||||
Ok(PatriciaTree {
|
||||
skip_prefix: try!(ConsensusDecodable::consensus_decode(d)),
|
||||
skip_len: try!(ConsensusDecodable::consensus_decode(d)),
|
||||
|
@ -425,7 +437,9 @@ pub struct MutItems<'tree, K, V> {
|
|||
marker: marker::PhantomData<&'tree PatriciaTree<K, V>>
|
||||
}
|
||||
|
||||
impl<'a, K, V> Iterator<&'a V> for Items<'a, K, V> {
|
||||
impl<'a, K, V> Iterator for Items<'a, K, V> {
|
||||
type Item = &'a V;
|
||||
|
||||
fn next(&mut self) -> Option<&'a V> {
|
||||
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> Option<&'a PatriciaTree<K, V>> {
|
||||
opt_ptr.as_ref().map(|b| &**b)
|
||||
|
@ -469,7 +483,9 @@ impl<'a, K, V> Iterator<&'a V> for Items<'a, K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> Iterator<&'a mut V> for MutItems<'a, K, V> {
|
||||
impl<'a, K, V> Iterator for MutItems<'a, K, V> {
|
||||
type Item = &'a mut V;
|
||||
|
||||
fn next(&mut self) -> Option<&'a mut V> {
|
||||
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> {
|
||||
match *opt_ptr {
|
||||
|
|
|
@ -90,7 +90,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Add<$name,$name> for $name {
|
||||
impl ::std::ops::Add<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
fn add(&self, other: &$name) -> $name {
|
||||
let &$name(ref me) = self;
|
||||
let &$name(ref you) = other;
|
||||
|
@ -108,14 +110,18 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Sub<$name,$name> for $name {
|
||||
impl ::std::ops::Sub<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
#[inline]
|
||||
fn sub(&self, other: &$name) -> $name {
|
||||
*self + !*other + One::one()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Mul<$name,$name> for $name {
|
||||
impl ::std::ops::Mul<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
fn mul(&self, other: &$name) -> $name {
|
||||
let mut me = *self;
|
||||
// TODO: be more efficient about this
|
||||
|
@ -126,7 +132,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Div<$name,$name> for $name {
|
||||
impl ::std::ops::Div<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
fn div(&self, other: &$name) -> $name {
|
||||
let mut sub_copy = *self;
|
||||
let mut shift_copy = *other;
|
||||
|
@ -197,7 +205,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitAnd<$name,$name> for $name {
|
||||
impl ::std::ops::BitAnd<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
#[inline]
|
||||
fn bitand(&self, other: &$name) -> $name {
|
||||
let &$name(ref arr1) = self;
|
||||
|
@ -210,7 +220,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitXor<$name,$name> for $name {
|
||||
impl ::std::ops::BitXor<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
#[inline]
|
||||
fn bitxor(&self, other: &$name) -> $name {
|
||||
let &$name(ref arr1) = self;
|
||||
|
@ -223,7 +235,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitOr<$name,$name> for $name {
|
||||
impl ::std::ops::BitOr<$name> for $name {
|
||||
type Output = $name;
|
||||
|
||||
#[inline]
|
||||
fn bitor(&self, other: &$name) -> $name {
|
||||
let &$name(ref arr1) = self;
|
||||
|
@ -236,7 +250,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Not<$name> for $name {
|
||||
impl ::std::ops::Not for $name {
|
||||
type Output = $name;
|
||||
|
||||
#[inline]
|
||||
fn not(&self) -> $name {
|
||||
let &$name(ref arr) = self;
|
||||
|
@ -248,7 +264,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Shl<usize, $name> for $name {
|
||||
impl ::std::ops::Shl<usize> for $name {
|
||||
type Output = $name;
|
||||
|
||||
fn shl(&self, shift: &usize) -> $name {
|
||||
let &$name(ref original) = self;
|
||||
let mut ret = [0u64; $n_words];
|
||||
|
@ -268,7 +286,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Shr<usize, $name> for $name {
|
||||
impl ::std::ops::Shr<usize> for $name {
|
||||
type Output = $name;
|
||||
|
||||
#[allow(unsigned_negate)]
|
||||
fn shr(&self, shift: &usize) -> $name {
|
||||
let &$name(ref original) = self;
|
||||
|
@ -316,9 +336,9 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $name {
|
||||
impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $name {
|
||||
#[inline]
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
use network::encodable::ConsensusEncodable;
|
||||
let &$name(ref data) = self;
|
||||
for word in data.iter() { try!(word.consensus_encode(s)); }
|
||||
|
@ -326,8 +346,8 @@ macro_rules! construct_uint {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $name {
|
||||
fn consensus_decode(d: &mut D) -> Result<$name, E> {
|
||||
impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $name {
|
||||
fn consensus_decode(d: &mut D) -> Result<$name, D::Error> {
|
||||
use network::encodable::ConsensusDecodable;
|
||||
let ret: [u64; $n_words] = try!(ConsensusDecodable::consensus_decode(d));
|
||||
Ok($name(ret))
|
||||
|
|
Loading…
Reference in New Issue