Implement ToJson for BlockHeader

I think this is what I want to do for everything json-visible...perhaps
I will not be able to keep the macro for it though, since there are
some clever variations on it (e.g. blocks should have their header's
hash as a field, txes should appear as txids unless vebose output is
requested, etc.)
This commit is contained in:
Andrew Poelstra 2014-07-28 20:12:10 -07:00
parent 1938959017
commit a34f2642f1
5 changed files with 50 additions and 0 deletions

View File

@ -118,6 +118,7 @@ impl BlockHeader {
} }
impl_serializable!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce) impl_serializable!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce)
impl_json!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce)
impl_serializable!(Block, header, txdata) impl_serializable!(Block, header, txdata)
impl_serializable!(LoneBlockHeader, header, tx_count) impl_serializable!(LoneBlockHeader, header, tx_count)

View File

@ -24,7 +24,9 @@
//! This module provides the structures and functions needed to support scripts. //! This module provides the structures and functions needed to support scripts.
//! //!
use std::char::from_digit;
use std::io::IoResult; use std::io::IoResult;
use serialize::{Encoder, Encodable};
use network::serialize::Serializable; use network::serialize::Serializable;
use blockdata::opcodes; use blockdata::opcodes;
@ -119,6 +121,21 @@ impl Script {
} }
} }
// User-facing serialization
impl<S:Encoder<E>, E> Encodable<S, E> for Script {
// TODO: put this in a struct alongside an opcode decode
fn encode(&self, s: &mut S) -> Result<(), E> {
let &Script(ref raw) = self;
let mut ret = String::new();
for dat in raw.iter() {
ret.push_char(from_digit((dat / 0x10) as uint, 16).unwrap());
ret.push_char(from_digit((dat & 0x0f) as uint, 16).unwrap());
}
s.emit_str(ret.as_slice())
}
}
// Network serialization
impl Serializable for Script { impl Serializable for Script {
fn serialize(&self) -> Vec<u8> { fn serialize(&self) -> Vec<u8> {
let &Script(ref data) = self; let &Script(ref data) = self;

View File

@ -43,3 +43,17 @@ macro_rules! impl_serializable(
); );
) )
macro_rules! impl_json(
($thing:ident, $($field:ident),+) => (
impl ::serialize::json::ToJson for $thing {
fn to_json(&self) -> ::serialize::json::Json {
use std::collections::TreeMap;
use serialize::json::{ToJson, Object};
let mut ret = TreeMap::new();
$( ret.insert(stringify!($field).to_string(), self.$field.to_json()); )+
Object(ret)
}
}
);
)

View File

@ -29,6 +29,7 @@ use std::io::{BufferedReader, BufferedWriter, File, Truncate, Write};
use std::io::fs::rename; use std::io::fs::rename;
use std::mem::transmute; use std::mem::transmute;
use std::u32; use std::u32;
use serialize::{Encoder, Encodable};
use util::iter::{FixedTake, FixedTakeable, NullIterator}; use util::iter::{FixedTake, FixedTakeable, NullIterator};
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
@ -152,6 +153,12 @@ pub enum VarInt {
VarU64(u64) VarU64(u64)
} }
impl<S:Encoder<E>, E> Encodable<S, E> for VarInt {
fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_u64(varint_to_u64(*self))
}
}
// Utility functions // Utility functions
/// Convert a Rust uint to a Bitcoin network Varint /// Convert a Rust uint to a Bitcoin network Varint
pub fn u64_to_varint(n: u64) -> VarInt { pub fn u64_to_varint(n: u64) -> VarInt {

View File

@ -23,6 +23,7 @@ use std::fmt;
use std::io::{IoResult, IoError, InvalidInput}; use std::io::{IoResult, IoError, InvalidInput};
use std::mem::transmute; use std::mem::transmute;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use serialize::json::{mod, ToJson};
use crypto::digest::Digest; use crypto::digest::Digest;
use crypto::sha2; use crypto::sha2;
@ -155,6 +156,16 @@ impl PartialEq for Sha256dHash {
impl Eq for Sha256dHash {} impl Eq for Sha256dHash {}
// Note that this outputs hashes as big endian hex numbers, so this should be
// used only for user-facing stuff. Internal and network serialization is
// little-endian and should be done using the consensus `network::serialize`
// interface.
impl ToJson for Sha256dHash {
fn to_json(&self) -> json::Json {
json::String(self.le_hex_string())
}
}
impl Serializable for Sha256dHash { impl Serializable for Sha256dHash {
fn serialize(&self) -> Vec<u8> { fn serialize(&self) -> Vec<u8> {
let &Sha256dHash(ref data) = self; let &Sha256dHash(ref data) = self;