Giant collection of fixes ... we are into lifetime errors now :)

This commit is contained in:
Andrew Poelstra 2015-04-05 19:10:37 -05:00
parent 7b89c15ed5
commit 811df8a713
21 changed files with 399 additions and 316 deletions

View File

@ -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);

View File

@ -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> {

View File

@ -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,24 +602,26 @@ 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())
}
}
/// Empty stack is also FALSE
@ -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())
}
}

View File

@ -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> {
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); }
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 {
ret += (data[i] as usize) << (i * 8);
}
Ok(ret)
}
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))))
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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)
}
}
}

View File

@ -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()) }
}
}
d.visit(Visitor)
}
}
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())) }
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())
}
}
);

View File

@ -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)),

View File

@ -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),

View File

@ -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());

View File

@ -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));

View File

@ -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 {

View File

@ -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);

View File

@ -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]

View File

@ -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

View File

@ -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 {

View File

@ -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,37 +160,48 @@ 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());
if hex_str.len() != 64 {
d.error("incorrect hash length");
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 {
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")));
let mut ret = [0u8; 32];
for i in 0..32 {
ret[i] = raw_str[31 - i];
}
Ok(Sha256dHash(ret))
d.visit(Sha256dHashVisitor)
}
}

View File

@ -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 }
}
}

View File

@ -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 {

View File

@ -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))