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
|
/// 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
|
/// is correct, but does not verify that the transactions are valid or encoded
|
||||||
/// correctly.
|
/// 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();
|
let ref target = self.target();
|
||||||
if target != required_target {
|
if target != required_target {
|
||||||
return Err(SpvBadTarget);
|
return Err(SpvBadTarget);
|
||||||
|
@ -132,7 +132,6 @@ impl BitcoinHash for Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
|
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!(Block, header, txdata);
|
||||||
impl_consensus_encoding!(LoneBlockHeader, header, tx_count);
|
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]
|
#[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.block.consensus_encode(s));
|
||||||
try!(self.total_work.consensus_encode(s));
|
try!(self.total_work.consensus_encode(s));
|
||||||
try!(self.required_difficulty.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]
|
#[inline]
|
||||||
fn consensus_decode(d: &mut D) -> Result<BlockchainNode, E> {
|
fn consensus_decode(d: &mut D) -> Result<BlockchainNode, D::Error> {
|
||||||
Ok(BlockchainNode {
|
Ok(BlockchainNode {
|
||||||
block: try!(ConsensusDecodable::consensus_decode(d)),
|
block: try!(ConsensusDecodable::consensus_decode(d)),
|
||||||
total_work: try!(ConsensusDecodable::consensus_decode(d)),
|
total_work: try!(ConsensusDecodable::consensus_decode(d)),
|
||||||
|
@ -123,9 +123,9 @@ pub struct Blockchain {
|
||||||
genesis_hash: Sha256dHash
|
genesis_hash: Sha256dHash
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Blockchain {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for Blockchain {
|
||||||
#[inline]
|
#[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.network.consensus_encode(s));
|
||||||
try!(self.tree.consensus_encode(s));
|
try!(self.tree.consensus_encode(s));
|
||||||
try!(self.best_hash.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 {
|
impl<D: SimpleDecoder> ConsensusDecodable<D> for Blockchain {
|
||||||
fn consensus_decode(d: &mut D) -> Result<Blockchain, E> {
|
fn consensus_decode(d: &mut D) -> Result<Blockchain, D::Error> {
|
||||||
let network: Network = try!(ConsensusDecodable::consensus_decode(d));
|
let network: Network = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
let mut tree: BlockTree = try!(ConsensusDecodable::consensus_decode(d));
|
let mut tree: BlockTree = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
let best_hash: Sha256dHash = 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> {
|
fn next(&mut self) -> Option<Sha256dHash> {
|
||||||
if self.index.is_null() {
|
if self.index.is_null() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -274,7 +276,9 @@ pub struct RevStaleBlockIter<'tree> {
|
||||||
chain: &'tree Blockchain
|
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> {
|
fn next(&mut self) -> Option<&'tree BlockchainNode> {
|
||||||
if self.index.is_null() {
|
if self.index.is_null() {
|
||||||
return None;
|
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> {
|
fn next(&mut self) -> Option<&'tree BlockchainNode> {
|
||||||
if self.index.is_null() {
|
if self.index.is_null() {
|
||||||
return None;
|
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> {
|
fn next(&mut self) -> Option<&'tree Block> {
|
||||||
if self.index.is_null() {
|
if self.index.is_null() {
|
||||||
return None;
|
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) {
|
match self.tree.lookup_mut(hash, 256) {
|
||||||
Some(existing_block) => {
|
Some(existing_block) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -405,26 +413,26 @@ impl Blockchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locates a block in the chain and overwrites its txdata
|
/// 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)
|
self.replace_txdata(&block.header.bitcoin_hash().into_le(), block.txdata, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locates a block in the chain and removes its txdata
|
/// 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)
|
self.replace_txdata(&hash.into_le(), vec![], false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a block header to the chain
|
/// 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)
|
self.real_add_block(Block { header: header, txdata: vec![] }, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a block to the chain
|
/// 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)
|
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
|
// get_prev optimizes the common case where we are extending the best tip
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_prev<'a>(chain: &'a Blockchain, hash: Sha256dHash) -> Option<NodePtr> {
|
fn get_prev<'a>(chain: &'a Blockchain, hash: Sha256dHash) -> Option<NodePtr> {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
use serialize::json;
|
use serde;
|
||||||
|
|
||||||
// Heavy stick to translate between opcode types
|
// Heavy stick to translate between opcode types
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
@ -602,24 +602,26 @@ impl All {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for All {
|
impl<D: SimpleDecoder> ConsensusDecodable<D> for All {
|
||||||
#[inline]
|
#[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())))
|
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]
|
#[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)
|
s.emit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl json::ToJson for All {
|
impl serde::Serialize for All {
|
||||||
fn to_json(&self) -> json::Json {
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
json::String(self.to_string())
|
where S: serde::Serializer,
|
||||||
}
|
{
|
||||||
|
serializer.visit_str(&self.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Empty stack is also FALSE
|
/// Empty stack is also FALSE
|
||||||
|
@ -644,9 +646,11 @@ pub enum Class {
|
||||||
Ordinary(Ordinary)
|
Ordinary(Ordinary)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl json::ToJson for Class {
|
impl serde::Serialize for Class {
|
||||||
fn to_json(&self) -> json::Json {
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
json::String(self.to_string())
|
where S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.visit_str(&self.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,9 @@ use crypto::digest::Digest;
|
||||||
use crypto::ripemd160::Ripemd160;
|
use crypto::ripemd160::Ripemd160;
|
||||||
use crypto::sha1::Sha1;
|
use crypto::sha1::Sha1;
|
||||||
use crypto::sha2::Sha256;
|
use crypto::sha2::Sha256;
|
||||||
|
|
||||||
use secp256k1::Secp256k1;
|
use secp256k1::Secp256k1;
|
||||||
use secp256k1::key::PublicKey;
|
use secp256k1::key::PublicKey;
|
||||||
|
use serde;
|
||||||
|
|
||||||
use blockdata::opcodes;
|
use blockdata::opcodes;
|
||||||
use blockdata::transaction::{Transaction, TxIn};
|
use blockdata::transaction::{Transaction, TxIn};
|
||||||
|
@ -1207,9 +1207,11 @@ impl AbstractStack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl json::ToJson for Error {
|
impl serde::Serialize for Error {
|
||||||
fn to_json(&self) -> json::Json {
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
json::String(self.to_string())
|
where S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.visit_str(&self.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,8 +1240,6 @@ pub struct ScriptTrace {
|
||||||
pub error: Option<Error>
|
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,
|
/// Hashtype of a transaction, encoded in the last byte of a signature,
|
||||||
/// specifically in the last 5 bits `byte & 31`
|
/// specifically in the last 5 bits `byte & 31`
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[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];
|
type Output = [u8];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, _: ops::RangeFull<usize>) -> &[u8] {
|
fn index(&self, _: ops::RangeFull) -> &[u8] {
|
||||||
match *self {
|
match *self {
|
||||||
MaybeOwned::Owned(ref v) => &v[..],
|
MaybeOwned::Owned(ref v) => &v[..],
|
||||||
MaybeOwned::Borrowed(ref s) => &s[..]
|
MaybeOwned::Borrowed(ref s) => &s[..]
|
||||||
|
@ -1427,16 +1427,16 @@ pub fn read_scriptbool(v: &[u8]) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a script-encoded unsigned integer
|
/// Read a script-encoded unsigned integer
|
||||||
pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: usize)
|
pub fn read_uint(data: &[u8], size: usize) -> Result<usize, Error> {
|
||||||
-> Result<usize, Error> {
|
if data.len() < size {
|
||||||
let mut ret = 0;
|
Err(Error::EarlyEndOfScript)
|
||||||
for i in 0..size {
|
} else {
|
||||||
match iter.next() {
|
let mut ret = 0;
|
||||||
Some(&n) => ret += (n as usize) << (i * 8),
|
for i in 0..size {
|
||||||
None => { return Err(Error::EarlyEndOfScript); }
|
ret += (data[i] as usize) << (i * 8);
|
||||||
}
|
}
|
||||||
|
Ok(ret)
|
||||||
}
|
}
|
||||||
Ok(ret)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a signature -- returns an error that is currently just translated
|
/// Check a signature -- returns an error that is currently just translated
|
||||||
|
@ -2477,31 +2477,30 @@ impl Default for Script {
|
||||||
}
|
}
|
||||||
|
|
||||||
// User-facing serialization
|
// User-facing serialization
|
||||||
impl json::ToJson for Script {
|
impl serde::Serialize for Script {
|
||||||
// TODO: put this in a struct alongside an opcode decode
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
fn to_json(&self) -> json::Json {
|
where S: serde::Serializer,
|
||||||
|
{
|
||||||
let &Script(ref raw) = self;
|
let &Script(ref raw) = self;
|
||||||
let mut ret = String::new();
|
|
||||||
for dat in raw.iter() {
|
for dat in raw.iter() {
|
||||||
ret.push_char(from_digit((dat / 0x10) as usize, 16).unwrap());
|
serializer.visit_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 & 0x0f) as usize, 16).unwrap());
|
||||||
}
|
}
|
||||||
json::String(ret)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network serialization
|
// Network serialization
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Script {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for Script {
|
||||||
#[inline]
|
#[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;
|
let &Script(ref data) = self;
|
||||||
data.consensus_encode(s)
|
data.consensus_encode(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Script {
|
impl<D: SimpleDecoder> ConsensusDecodable<D> for Script {
|
||||||
#[inline]
|
#[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))))
|
Ok(Script(try!(ConsensusDecodable::consensus_decode(d))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use serialize::json;
|
use serde;
|
||||||
|
|
||||||
use util::hash::Sha256dHash;
|
use util::hash::Sha256dHash;
|
||||||
use blockdata::script::{self, Script, ScriptTrace, read_scriptbool};
|
use blockdata::script::{self, Script, ScriptTrace, read_scriptbool};
|
||||||
|
@ -123,9 +123,11 @@ pub enum Error {
|
||||||
InputNotFound(Sha256dHash, u32),
|
InputNotFound(Sha256dHash, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl json::ToJson for Error {
|
impl serde::Serialize for Error {
|
||||||
fn to_json(&self) -> json::Json {
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
json::String(self.to_string())
|
where S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.visit_str(&self.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,10 +142,6 @@ pub struct InputTrace {
|
||||||
error: Option<Error>
|
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
|
/// A trace of a transaction's execution
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct TransactionTrace {
|
pub struct TransactionTrace {
|
||||||
|
@ -151,8 +149,6 @@ pub struct TransactionTrace {
|
||||||
inputs: Vec<InputTrace>
|
inputs: Vec<InputTrace>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_json!(TransactionTrace, txid, inputs);
|
|
||||||
|
|
||||||
impl TxIn {
|
impl TxIn {
|
||||||
/// Check an input's script for validity
|
/// Check an input's script for validity
|
||||||
pub fn validate(&self,
|
pub fn validate(&self,
|
||||||
|
@ -304,12 +300,8 @@ impl BitcoinHash for Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_consensus_encoding!(TxIn, prev_hash, prev_index, script_sig, sequence);
|
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_consensus_encoding!(TxOut, value, script_pubkey);
|
||||||
impl_json!(TxOut, value, script_pubkey);
|
|
||||||
impl_consensus_encoding!(Transaction, version, input, output, lock_time);
|
impl_consensus_encoding!(Transaction, version, input, output, lock_time);
|
||||||
impl_json!(Transaction, version, input, output, lock_time);
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -74,7 +74,9 @@ pub struct UtxoIterator<'a> {
|
||||||
tx_index: u32
|
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)> {
|
fn next(&mut self) -> Option<(Sha256dHash, u32, &'a TxOut, u32)> {
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = &self.current.unwrap().outputs;
|
let current = &self.current.unwrap().outputs;
|
||||||
|
|
|
@ -14,17 +14,17 @@
|
||||||
|
|
||||||
macro_rules! impl_consensus_encoding {
|
macro_rules! impl_consensus_encoding {
|
||||||
($thing:ident, $($field:ident),+) => (
|
($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]
|
#[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)); )+
|
$( try!(self.$field.consensus_encode(s)); )+
|
||||||
Ok(())
|
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]
|
#[inline]
|
||||||
fn consensus_decode(d: &mut D) -> Result<$thing, E> {
|
fn consensus_decode(d: &mut D) -> Result<$thing, D::Error> {
|
||||||
use network::encodable::ConsensusDecodable;
|
use network::encodable::ConsensusDecodable;
|
||||||
Ok($thing {
|
Ok($thing {
|
||||||
$( $field: try!(ConsensusDecodable::consensus_decode(d)), )+
|
$( $field: try!(ConsensusDecodable::consensus_decode(d)), )+
|
||||||
|
@ -36,37 +36,23 @@ macro_rules! impl_consensus_encoding {
|
||||||
|
|
||||||
macro_rules! impl_newtype_consensus_encoding {
|
macro_rules! impl_newtype_consensus_encoding {
|
||||||
($thing:ident) => (
|
($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]
|
#[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;
|
let &$thing(ref data) = self;
|
||||||
data.consensus_encode(s)
|
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]
|
#[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))))
|
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 {
|
macro_rules! impl_array_newtype {
|
||||||
($thing:ident, $ty:ty, $len:expr) => {
|
($thing:ident, $ty:ty, $len:expr) => {
|
||||||
impl $thing {
|
impl $thing {
|
||||||
|
@ -201,32 +187,46 @@ macro_rules! impl_array_newtype {
|
||||||
|
|
||||||
macro_rules! impl_array_newtype_encodable {
|
macro_rules! impl_array_newtype_encodable {
|
||||||
($thing:ident, $ty:ty, $len:expr) => {
|
($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| {
|
#[inline]
|
||||||
if len != $len {
|
fn visit_seq<V>(&mut self, mut v: V) -> Result<$thing, V::Error>
|
||||||
Err(d.error("Invalid length"))
|
where V: ::serde::de::SeqVisitor
|
||||||
} else {
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
let mut ret: [$ty; $len] = mem::uninitialized();
|
let mut ret: [$ty; $len] = mem::uninitialized();
|
||||||
for i in 0..len {
|
for i in 0..$len {
|
||||||
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
|
ret[i] = try!(v.visit());
|
||||||
}
|
}
|
||||||
Ok($thing(ret))
|
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 {
|
impl ::serde::Serialize for $thing {
|
||||||
fn encode(&self, e: &mut E) -> Result<(), S> {
|
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
|
||||||
self.as_slice().encode(e)
|
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 {
|
impl ::serde::Deserialize for $name {
|
||||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
#[inline]
|
||||||
s.emit_str(self.to_string().as_slice())
|
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()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.visit(Visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $name {
|
impl ::serde::Serialize for $name {
|
||||||
fn decode(d: &mut D) -> Result<$name, E> {
|
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
|
||||||
let s = try!(d.read_str());
|
where S: ::serde::Serializer
|
||||||
$( if s.as_slice() == $txt { Ok($name::$elem) } )else*
|
{
|
||||||
else { Err(d.error(format!("unknown `{}`", s).as_slice())) }
|
s.visit_str(&self.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -33,9 +33,9 @@ pub struct Address {
|
||||||
pub port: u16
|
pub port: u16
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Address {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for Address {
|
||||||
#[inline]
|
#[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.services.consensus_encode(s));
|
||||||
try!(self.address.consensus_encode(s));
|
try!(self.address.consensus_encode(s));
|
||||||
// Explicitly code the port since it needs to be big-endian
|
// 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]
|
#[inline]
|
||||||
fn consensus_decode(d: &mut D) -> Result<Address, E> {
|
fn consensus_decode(d: &mut D) -> Result<Address, D::Error> {
|
||||||
Ok(Address {
|
Ok(Address {
|
||||||
services: try!(ConsensusDecodable::consensus_decode(d)),
|
services: try!(ConsensusDecodable::consensus_decode(d)),
|
||||||
address: 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]
|
#[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)
|
magic(*self).consensus_encode(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Network {
|
impl<D: SimpleDecoder> ConsensusDecodable<D> for Network {
|
||||||
#[inline]
|
#[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));
|
let magic: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
match magic {
|
match magic {
|
||||||
0xD9B4BEF9 => Ok(Network::Bitcoin),
|
0xD9B4BEF9 => Ok(Network::Bitcoin),
|
||||||
|
|
|
@ -38,15 +38,15 @@ use util::hash::Sha256dHash;
|
||||||
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
||||||
|
|
||||||
/// Data which can be encoded in a consensus-consistent way
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// A variable-length unsigned integer
|
||||||
|
@ -58,39 +58,39 @@ pub struct VarInt(pub u64);
|
||||||
pub struct CheckedData(pub Vec<u8>);
|
pub struct CheckedData(pub Vec<u8>);
|
||||||
|
|
||||||
// Primitive types
|
// Primitive types
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u8 {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for u8 {
|
||||||
#[inline]
|
#[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]
|
#[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]
|
#[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]
|
#[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]
|
#[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]
|
#[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]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
let &VarInt(n) = self;
|
let &VarInt(n) = self;
|
||||||
match n {
|
match n {
|
||||||
0...0xFC => { (n as u8).consensus_encode(s) }
|
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]
|
#[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]
|
#[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]
|
#[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]
|
#[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]
|
#[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]
|
#[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]
|
#[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());
|
let n = try!(d.read_u8());
|
||||||
match n {
|
match n {
|
||||||
0xFF => d.read_u64().map(|n| VarInt(u64::from_le(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
|
// Booleans
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for bool {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for bool {
|
||||||
#[inline]
|
#[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]
|
#[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
|
// Strings
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for String {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for String {
|
||||||
#[inline]
|
#[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)
|
self.as_bytes().consensus_encode(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for String {
|
impl<D: SimpleDecoder> ConsensusDecodable<D> for String {
|
||||||
#[inline]
|
#[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"))
|
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
|
// Arrays
|
||||||
macro_rules! impl_array {
|
macro_rules! impl_array {
|
||||||
( $size:expr ) => (
|
( $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]
|
#[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)); }
|
for i in self.iter() { try!(i.consensus_encode(s)); }
|
||||||
Ok(())
|
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]
|
#[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
|
// Set everything to the first decode
|
||||||
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size];
|
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size];
|
||||||
// Set the rest
|
// Set the rest
|
||||||
|
@ -202,9 +202,9 @@ impl_array!(12);
|
||||||
impl_array!(16);
|
impl_array!(16);
|
||||||
impl_array!(32);
|
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]
|
#[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));
|
try!(VarInt(self.len() as u64).consensus_encode(s));
|
||||||
for c in self.iter() { try!(c.consensus_encode(s)); }
|
for c in self.iter() { try!(c.consensus_encode(s)); }
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -214,14 +214,14 @@ impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S
|
||||||
// Cannot decode a slice
|
// Cannot decode a slice
|
||||||
|
|
||||||
// Vectors
|
// 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]
|
#[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]
|
#[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 VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
let mut ret = Vec::with_capacity(len as usize);
|
let mut ret = Vec::with_capacity(len as usize);
|
||||||
for _ in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); }
|
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]
|
#[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]
|
#[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));
|
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
unsafe {
|
unsafe {
|
||||||
let len = len as usize;
|
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)
|
// 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]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
Some(ref data) => {
|
Some(ref data) => {
|
||||||
try!(1u8.consensus_encode(s));
|
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]
|
#[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));
|
let bit: u8 = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
Ok(if bit != 0 {
|
Ok(if bit != 0 {
|
||||||
Some(try!(ConsensusDecodable::consensus_decode(d)))
|
Some(try!(ConsensusDecodable::consensus_decode(d)))
|
||||||
|
@ -282,9 +282,9 @@ fn sha2_checksum(data: &[u8]) -> [u8; 4] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checked data
|
// Checked data
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CheckedData {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for CheckedData {
|
||||||
#[inline]
|
#[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;
|
let &CheckedData(ref data) = self;
|
||||||
try!((data.len() as u32).consensus_encode(s));
|
try!((data.len() as u32).consensus_encode(s));
|
||||||
try!(sha2_checksum(data.as_slice()).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]
|
#[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 len: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d));
|
let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
let mut ret = Vec::with_capacity(len as usize);
|
let mut ret = Vec::with_capacity(len as usize);
|
||||||
|
@ -315,53 +315,53 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
|
||||||
// Tuples
|
// Tuples
|
||||||
macro_rules! tuple_encode {
|
macro_rules! tuple_encode {
|
||||||
($($x:ident),*) => (
|
($($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]
|
#[inline]
|
||||||
#[allow(non_snake_case)]
|
#[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;
|
let &($(ref $x),*) = self;
|
||||||
$( try!($x.consensus_encode(s)); )*
|
$( try!($x.consensus_encode(s)); )*
|
||||||
Ok(())
|
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]
|
#[inline]
|
||||||
#[allow(non_snake_case)]
|
#[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 })),*))
|
Ok(($(try!({let $x = ConsensusDecodable::consensus_decode(d); $x })),*))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple_encode!(A, B);
|
tuple_encode!(T0, T1);
|
||||||
tuple_encode!(A, B, C, D);
|
tuple_encode!(T0, T1, T2, T3);
|
||||||
tuple_encode!(A, B, C, D, E, F);
|
tuple_encode!(T0, T1, T2, T3, T4, T5);
|
||||||
tuple_encode!(A, B, C, D, E, F, G, H);
|
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
|
||||||
|
|
||||||
|
|
||||||
// References
|
// 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]
|
#[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]
|
#[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))
|
ConsensusDecodable::consensus_decode(d).map(|res| Box::new(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HashMap
|
// HashMap
|
||||||
impl<S:SimpleEncoder<E>, E, T,
|
impl<S, K, V, H> ConsensusEncodable<S> for HashMap<K, V, H>
|
||||||
K:ConsensusEncodable<S,E>+Eq+Hash<T>,
|
where S: SimpleEncoder,
|
||||||
V:ConsensusEncodable<S,E>,
|
H: Hasher + Default,
|
||||||
H:Hasher<T>+Default> ConsensusEncodable<S, E> for HashMap<K, V, H> {
|
K: ConsensusEncodable<S> + Eq + Hash,
|
||||||
|
V: ConsensusEncodable<S>
|
||||||
|
{
|
||||||
#[inline]
|
#[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));
|
try!(VarInt(self.len() as u64).consensus_encode(s));
|
||||||
for (key, value) in self.iter() {
|
for (key, value) in self.iter() {
|
||||||
try!(key.consensus_encode(s));
|
try!(key.consensus_encode(s));
|
||||||
|
@ -371,12 +371,14 @@ impl<S:SimpleEncoder<E>, E, T,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D:SimpleDecoder<E>, E, T,
|
impl<D, K, V, H> ConsensusDecodable<D> for HashMap<K, V, H>
|
||||||
K:ConsensusDecodable<D,E>+Eq+Hash<T>,
|
where D: SimpleDecoder,
|
||||||
V:ConsensusDecodable<D,E>,
|
H: Hasher + Default,
|
||||||
H:Hasher<T>+Default> ConsensusDecodable<D, E> for HashMap<K, V, H> {
|
K: ConsensusDecodable<D> + Eq + Hash,
|
||||||
|
V: ConsensusDecodable<D>
|
||||||
|
{
|
||||||
#[inline]
|
#[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 VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
|
|
||||||
let mut ret = HashMap::with_capacity_and_hasher(len as usize, Default::default());
|
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)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct CommandString(pub String);
|
pub struct CommandString(pub String);
|
||||||
|
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for CommandString {
|
||||||
#[inline]
|
#[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 &CommandString(ref inner_str) = self;
|
||||||
let mut rawbytes = [0u8; 12];
|
let mut rawbytes = [0u8; 12];
|
||||||
rawbytes.clone_from_slice(inner_str.as_bytes().as_slice());
|
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]
|
#[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 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 }));
|
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None }));
|
||||||
Ok(CommandString(rv))
|
Ok(CommandString(rv))
|
||||||
|
@ -133,8 +133,8 @@ impl RawNetworkMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for RawNetworkMessage {
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for RawNetworkMessage {
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
try!(self.magic.consensus_encode(s));
|
try!(self.magic.consensus_encode(s));
|
||||||
try!(CommandString(self.command()).consensus_encode(s));
|
try!(CommandString(self.command()).consensus_encode(s));
|
||||||
try!(CheckedData(match self.payload {
|
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> {
|
fn consensus_decode(d: &mut D) -> io::Result<RawNetworkMessage> {
|
||||||
let magic = try!(ConsensusDecodable::consensus_decode(d));
|
let magic = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
let CommandString(cmd): CommandString= 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_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]
|
#[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 {
|
try!(match self.inv_type {
|
||||||
InvType::Error => 0u32,
|
InvType::Error => 0u32,
|
||||||
InvType::Transaction => 1,
|
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]
|
#[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));
|
let int_type: u32 = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
Ok(Inventory {
|
Ok(Inventory {
|
||||||
inv_type: match int_type {
|
inv_type: match int_type {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
//! capabilities
|
//! capabilities
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::io::Result;
|
use std::io;
|
||||||
|
|
||||||
use network::constants;
|
use network::constants;
|
||||||
use network::address::Address;
|
use network::address::Address;
|
||||||
|
@ -54,7 +54,7 @@ pub struct VersionMessage {
|
||||||
impl VersionMessage {
|
impl VersionMessage {
|
||||||
// TODO: we have fixed services and relay to 0
|
// TODO: we have fixed services and relay to 0
|
||||||
/// Constructs a new `version` message
|
/// 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 recv_addr = socket.receiver_address();
|
||||||
let send_addr = socket.sender_address();
|
let send_addr = socket.sender_address();
|
||||||
// If we are not connected, we might not be able to get these address.s
|
// 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 {
|
mod tests {
|
||||||
use super::VersionMessage;
|
use super::VersionMessage;
|
||||||
|
|
||||||
use std::io::Result;
|
use std::io;
|
||||||
use serialize::hex::FromHex;
|
use serialize::hex::FromHex;
|
||||||
|
|
||||||
use network::serialize::{deserialize, serialize};
|
use network::serialize::{deserialize, serialize};
|
||||||
|
@ -98,7 +98,7 @@ mod tests {
|
||||||
// This message is from my satoshi node, morning of May 27 2014
|
// This message is from my satoshi node, morning of May 27 2014
|
||||||
let from_sat = "721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001".from_hex().unwrap();
|
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());
|
assert!(decode.is_ok());
|
||||||
let real_decode = decode.unwrap();
|
let real_decode = decode.unwrap();
|
||||||
assert_eq!(real_decode.version, 70002);
|
assert_eq!(real_decode.version, 70002);
|
||||||
|
|
|
@ -39,20 +39,20 @@ impl BitcoinHash for Vec<u8> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode an object into a vector
|
/// 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![]));
|
let mut encoder = RawEncoder::new(Cursor::new(vec![]));
|
||||||
try!(obj.consensus_encode(&mut encoder));
|
try!(obj.consensus_encode(&mut encoder));
|
||||||
Ok(encoder.unwrap().unwrap())
|
Ok(encoder.unwrap().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode an object into a hex-encoded string
|
/// 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));
|
let serial = try!(serialize(obj));
|
||||||
Ok(serial.as_slice().to_hex())
|
Ok(serial.as_slice().to_hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize an object from a vector
|
/// 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));
|
let mut decoder = RawDecoder::new(Cursor::new(data));
|
||||||
ConsensusDecodable::consensus_decode(&mut decoder)
|
ConsensusDecodable::consensus_decode(&mut decoder)
|
||||||
}
|
}
|
||||||
|
@ -92,59 +92,65 @@ impl<R:Read> RawDecoder<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A simple Encoder trait
|
/// A simple Encoder trait
|
||||||
pub trait SimpleEncoder<E> {
|
pub trait SimpleEncoder {
|
||||||
|
type Error;
|
||||||
|
|
||||||
/// Output a 64-bit uint
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// A simple Decoder trait
|
||||||
pub trait SimpleDecoder<E> {
|
pub trait SimpleDecoder {
|
||||||
|
type Error;
|
||||||
|
|
||||||
/// Read a 64-bit uint
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// Read a boolean
|
||||||
fn read_bool(&mut self) -> Result<bool, E>;
|
fn read_bool(&mut self) -> Result<bool, Self::Error>;
|
||||||
|
|
||||||
/// Signal a decoding 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
|
// 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]
|
#[inline]
|
||||||
fn emit_u64(&mut self, v: u64) -> io::Result<()> { self.writer.write_le_u64(v) }
|
fn emit_u64(&mut self, v: u64) -> io::Result<()> { self.writer.write_le_u64(v) }
|
||||||
#[inline]
|
#[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}) }
|
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]
|
#[inline]
|
||||||
fn read_u64(&mut self) -> io::Result<u64> { self.reader.read_le_u64() }
|
fn read_u64(&mut self) -> io::Result<u64> { self.reader.read_le_u64() }
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
|
||||||
use std::string;
|
use std::str;
|
||||||
|
|
||||||
use util::hash::Sha256dHash;
|
use util::hash::Sha256dHash;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ pub fn base58_encode_slice(data: &[u8]) -> String {
|
||||||
// Unsafely translate the bytes to a utf8 string
|
// Unsafely translate the bytes to a utf8 string
|
||||||
unsafe {
|
unsafe {
|
||||||
// Copy leading zeroes directly
|
// 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])
|
.map(|_| BASE58_CHARS[0])
|
||||||
.collect());
|
.collect());
|
||||||
// Copy rest of string
|
// Copy rest of string
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
/// A success/failure return value
|
|
||||||
pub type Result<T> = Result<T, Error>;
|
|
||||||
|
|
||||||
/// A general error code
|
/// A general error code
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
|
@ -22,7 +22,7 @@ use std::fmt;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use std::hash;
|
use std::hash;
|
||||||
use serialize::json::{self, ToJson};
|
use serde;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
|
@ -160,37 +160,48 @@ impl Sha256dHash {
|
||||||
// used only for user-facing stuff. Internal and network serialization is
|
// used only for user-facing stuff. Internal and network serialization is
|
||||||
// little-endian and should be done using the consensus `encodable::ConsensusEncodable`
|
// little-endian and should be done using the consensus `encodable::ConsensusEncodable`
|
||||||
// interface.
|
// interface.
|
||||||
impl ToJson for Sha256dHash {
|
impl serde::Serialize for Sha256dHash {
|
||||||
#[inline]
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
fn to_json(&self) -> json::Json {
|
where S: serde::Serializer,
|
||||||
json::String(self.be_hex_string())
|
{
|
||||||
|
serializer.visit_str(&self.be_hex_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-consensus encoding (big-endian hex string)
|
impl serde::Deserialize for Sha256dHash {
|
||||||
impl<S: ::serialize::Encoder<E>, E> ::serialize::Encodable<S, E> for Sha256dHash {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
fn deserialize<D>(d: &mut D) -> Result<Sha256dHash, D::Error>
|
||||||
s.emit_str(self.be_hex_string().as_slice())
|
where D: serde::Deserializer
|
||||||
}
|
{
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for Sha256dHash {
|
|
||||||
#[inline]
|
|
||||||
fn decode(d: &mut D) -> Result<Sha256dHash, E> {
|
|
||||||
use serialize::hex::FromHex;
|
use serialize::hex::FromHex;
|
||||||
|
|
||||||
let hex_str = try!(d.read_str());
|
struct Sha256dHashVisitor;
|
||||||
if hex_str.len() != 64 {
|
impl serde::de::Visitor for Sha256dHashVisitor {
|
||||||
d.error("incorrect hash length");
|
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 {
|
||||||
|
return Err(serde::de::Error::syntax_error());
|
||||||
|
}
|
||||||
|
let raw_str = try!(hex_str.as_slice().from_hex()
|
||||||
|
.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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let raw_str = try!(hex_str.as_slice().from_hex()
|
|
||||||
.map_err(|_| d.error("non-hexadecimal hash string")));
|
d.visit(Sha256dHashVisitor)
|
||||||
let mut ret = [0u8; 32];
|
|
||||||
for i in 0..32 {
|
|
||||||
ret[i] = raw_str[31 - i];
|
|
||||||
}
|
|
||||||
Ok(Sha256dHash(ret))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,18 @@
|
||||||
//! standard library.
|
//! standard library.
|
||||||
|
|
||||||
/// An iterator that returns pairs of elements
|
/// An iterator that returns pairs of elements
|
||||||
pub struct Pair<A, I> {
|
pub struct Pair<I>
|
||||||
|
where I: Iterator
|
||||||
|
{
|
||||||
iter: I,
|
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]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<(A, A)> {
|
fn next(&mut self) -> Option<(I::Item, I::Item)> {
|
||||||
let elem1 = self.iter.next();
|
let elem1 = self.iter.next();
|
||||||
if elem1.is_none() {
|
if elem1.is_none() {
|
||||||
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
|
/// Returns the last element of the iterator if there were an odd
|
||||||
/// number of elements remaining before it was Pair-ified.
|
/// number of elements remaining before it was Pair-ified.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn remainder(self) -> Option<A> {
|
pub fn remainder(self) -> Option<I::Item> {
|
||||||
self.last_elem
|
self.last_elem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that returns elements of the original iterator 2 at a time
|
/// 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
|
/// 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
|
/// Creates an iterator that yields pairs ef elements from the underlying
|
||||||
/// iterator, yielding `None` when there are fewer than two elements to
|
/// iterator, yielding `None` when there are fewer than two elements to
|
||||||
/// return.
|
/// return.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pair(self) -> Pair<A, I> {
|
fn pair(self) -> Pair<I> {
|
||||||
Pair{iter: self, last_elem: None}
|
Pair {iter: self, last_elem: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,9 @@ pub struct PatriciaTree<K, V> {
|
||||||
skip_len: u8
|
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
|
/// Constructs a new Patricia tree
|
||||||
pub fn new() -> PatriciaTree<K, V> {
|
pub fn new() -> PatriciaTree<K, V> {
|
||||||
PatriciaTree {
|
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> {
|
pub fn delete(&mut self, key: &K, key_len: usize) -> Option<V> {
|
||||||
/// Return value is (deletable, actual return value), where `deletable` is true
|
/// 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)
|
/// 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
|
// If the search key is shorter than the node prefix, there is no
|
||||||
// way we can match, so fail.
|
// way we can match, so fail.
|
||||||
if key_len < tree.skip_len as usize {
|
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> {
|
impl<S, K, V> ConsensusEncodable<S> for PatriciaTree<K, V>
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
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
|
// Depth-first serialization: serialize self, then children
|
||||||
try!(self.skip_prefix.consensus_encode(s));
|
try!(self.skip_prefix.consensus_encode(s));
|
||||||
try!(self.skip_len.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> {
|
impl<D, K, V> ConsensusDecodable<D> for PatriciaTree<K, V>
|
||||||
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, E> {
|
where D: SimpleDecoder,
|
||||||
|
K: ConsensusDecodable<D>,
|
||||||
|
V: ConsensusDecodable<D>
|
||||||
|
{
|
||||||
|
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, D::Error> {
|
||||||
Ok(PatriciaTree {
|
Ok(PatriciaTree {
|
||||||
skip_prefix: try!(ConsensusDecodable::consensus_decode(d)),
|
skip_prefix: try!(ConsensusDecodable::consensus_decode(d)),
|
||||||
skip_len: 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>>
|
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 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>> {
|
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)
|
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 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> {
|
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> {
|
||||||
match *opt_ptr {
|
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 {
|
fn add(&self, other: &$name) -> $name {
|
||||||
let &$name(ref me) = self;
|
let &$name(ref me) = self;
|
||||||
let &$name(ref you) = other;
|
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]
|
#[inline]
|
||||||
fn sub(&self, other: &$name) -> $name {
|
fn sub(&self, other: &$name) -> $name {
|
||||||
*self + !*other + One::one()
|
*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 {
|
fn mul(&self, other: &$name) -> $name {
|
||||||
let mut me = *self;
|
let mut me = *self;
|
||||||
// TODO: be more efficient about this
|
// 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 {
|
fn div(&self, other: &$name) -> $name {
|
||||||
let mut sub_copy = *self;
|
let mut sub_copy = *self;
|
||||||
let mut shift_copy = *other;
|
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]
|
#[inline]
|
||||||
fn bitand(&self, other: &$name) -> $name {
|
fn bitand(&self, other: &$name) -> $name {
|
||||||
let &$name(ref arr1) = self;
|
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]
|
#[inline]
|
||||||
fn bitxor(&self, other: &$name) -> $name {
|
fn bitxor(&self, other: &$name) -> $name {
|
||||||
let &$name(ref arr1) = self;
|
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]
|
#[inline]
|
||||||
fn bitor(&self, other: &$name) -> $name {
|
fn bitor(&self, other: &$name) -> $name {
|
||||||
let &$name(ref arr1) = self;
|
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]
|
#[inline]
|
||||||
fn not(&self) -> $name {
|
fn not(&self) -> $name {
|
||||||
let &$name(ref arr) = self;
|
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 {
|
fn shl(&self, shift: &usize) -> $name {
|
||||||
let &$name(ref original) = self;
|
let &$name(ref original) = self;
|
||||||
let mut ret = [0u64; $n_words];
|
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)]
|
#[allow(unsigned_negate)]
|
||||||
fn shr(&self, shift: &usize) -> $name {
|
fn shr(&self, shift: &usize) -> $name {
|
||||||
let &$name(ref original) = self;
|
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]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
use network::encodable::ConsensusEncodable;
|
use network::encodable::ConsensusEncodable;
|
||||||
let &$name(ref data) = self;
|
let &$name(ref data) = self;
|
||||||
for word in data.iter() { try!(word.consensus_encode(s)); }
|
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 {
|
impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $name {
|
||||||
fn consensus_decode(d: &mut D) -> Result<$name, E> {
|
fn consensus_decode(d: &mut D) -> Result<$name, D::Error> {
|
||||||
use network::encodable::ConsensusDecodable;
|
use network::encodable::ConsensusDecodable;
|
||||||
let ret: [u64; $n_words] = try!(ConsensusDecodable::consensus_decode(d));
|
let ret: [u64; $n_words] = try!(ConsensusDecodable::consensus_decode(d));
|
||||||
Ok($name(ret))
|
Ok($name(ret))
|
||||||
|
|
Loading…
Reference in New Issue