Skip to content

Commit

Permalink
Merge 574d484 into 28da5de
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisMacNaughton committed Oct 2, 2017
2 parents 28da5de + 574d484 commit 139ee61
Show file tree
Hide file tree
Showing 23 changed files with 697 additions and 127 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ opt-level = 3
default = []

[workspace]
members = [ "bitcrustd", "monitor", "net"]
members = [ "bitcrustd", "monitor", "net", "encode-derive"]

2 changes: 1 addition & 1 deletion bitcrustd/src/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,10 @@ impl Peer {
Message::Inv(_inv) => {}
Message::BitcrustPeerCountRequest(msg) => {
if msg.valid(&self.config.key()) {
debug!("Self: {:?}", self);
let count = self.peers_connected;
let _ = self.send(Message::BitcrustPeerCount(count));
} else {
warn!("Message: {:?}", msg);
warn!("Invalid authenticated request!");
self.closed = true;
}
Expand Down
11 changes: 11 additions & 0 deletions encode-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "encode-derive"
version = "0.1.0"
authors = ["Chris MacNaughton <chris@centaurisolutions.nl>"]

[dependencies]
syn = "0.11.11"
quote = "0.3.15"

[lib]
proc-macro = true
56 changes: 56 additions & 0 deletions encode-derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;

#[proc_macro_derive(Encode, attributes(count))]
pub fn derive_encode(input: TokenStream) -> TokenStream {
// Construct a string representation of the type definition
let s = input.to_string();

// Parse the string representation
let ast = syn::parse_derive_input(&s).unwrap();

// Build the impl
let gen = impl_encode(&ast);

// Return the generated impl
gen.parse().unwrap()
}

fn impl_encode(ast: &syn::DeriveInput) -> quote::Tokens {
let name = &ast.ident;
let fields = match ast.body {
syn::Body::Struct(ref data) => data.fields(),
syn::Body::Enum(_) => panic!("#[derive(Encode)] can only be used with structs"),
};
let fields = generate_fields(&fields);
quote! {
impl Encode for #name {
fn encode(&self, mut buff: &mut Vec<u8>) -> Result<(), ::std::io::Error> {
#(#fields)*
Ok(())
}
}
}

}

fn generate_fields(fields: &[syn::Field]) -> Vec<quote::Tokens> {
let mut result = Vec::new();
for field in fields {
let ident = &field.ident;
if field.attrs.iter().any(|f| f.value.name() == "count") {
result.push(quote!{
VarInt::new(self.#ident.len() as u64).encode(&mut buff)?;
});
}
result.push(quote!{
self.#ident.encode(&mut buff)?;
});
}
result
}
1 change: 1 addition & 0 deletions net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ regex = "*"
ring = "0.12"
rusqlite = "~0.11"
sha2 = "0.5"
encode-derive = {path = "../encode-derive"}

[dependencies.nom]
version = "^2.2"
Expand Down
17 changes: 1 addition & 16 deletions net/src/block_header.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::io;

use Encode;
use VarInt;

#[derive(Debug, PartialEq)]
#[derive(Debug, Encode, PartialEq)]
/// 4 version int32_t Block version information (note, this is signed)
/// 32 prev_block char[32] The hash value of the previous block this particular block references
/// 32 merkle_root char[32] The reference to a Merkle tree collection which is a hash of all transactions related to this block
Expand All @@ -21,16 +19,3 @@ pub struct BlockHeader {
/// txn_count is a var_int on the wire
pub txn_count: VarInt,
}

impl Encode for BlockHeader {
fn encode(&self, mut buff: &mut Vec<u8>) -> Result<(), io::Error> {
self.version.encode(&mut buff)?;
self.prev_block.encode(&mut buff)?;
self.merkle_root.encode(&mut buff)?;
self.timestamp.encode(&mut buff)?;
self.bits.encode(&mut buff)?;
self.nonce.encode(&mut buff)?;
self.txn_count.encode(&mut buff)?;
Ok(())
}
}
15 changes: 12 additions & 3 deletions net/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,21 +152,30 @@ impl Encode for Ipv6Addr {

impl Encode for [u8] {
fn encode(&self, buff: &mut Vec<u8>) -> Result<(), io::Error> {
buff.extend(self);
for byte in self {
buff.write_u8(*byte)?;
}
// buff.extend(self);
Ok(())
}
}

impl Encode for [u8; 8] {
fn encode(&self, buff: &mut Vec<u8>) -> Result<(), io::Error> {
buff.extend(self);
for byte in self {
buff.write_u8(*byte)?;
}
// buff.extend(self);
Ok(())
}
}

impl Encode for [u8; 32] {
fn encode(&self, buff: &mut Vec<u8>) -> Result<(), io::Error> {
buff.extend(self);
for byte in self {
buff.write_u8(*byte)?;
}
// buff.extend(self);
Ok(())
}
}
Expand Down
13 changes: 2 additions & 11 deletions net/src/inventory_vector.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::io;
use Encode;

#[derive(Debug, PartialEq)]
#[derive(Debug, Encode, PartialEq)]
pub struct InventoryVector {
flags: InvFlags,
pub hash: [u8; 32],
}

bitflags! {
#[derive(Encode)]
flags InvFlags: u32 {
const ERROR = 0b0,
const MSG_TX = 0b00000001,
Expand All @@ -28,12 +28,3 @@ impl InventoryVector {
}
}
}

impl Encode for InventoryVector {
fn encode(&self, mut v: &mut Vec<u8>) -> Result<(), io::Error> {
// let mut v: Vec<u8> = Vec::with_capacity(36);
self.flags.bits.encode(&mut v)?;
self.hash.encode(&mut v)?;
Ok(())
}
}
6 changes: 5 additions & 1 deletion net/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ extern crate regex;
extern crate rusqlite;
extern crate sha2;

#[macro_use]
extern crate encode_derive;

pub mod bitcoin_network_connection;
mod block_header;
mod encode;
Expand All @@ -24,6 +27,7 @@ mod message;
mod inventory_vector;
mod net_addr;
mod services;
mod transactions;
mod var_int;

use encode::Encode;
Expand All @@ -33,4 +37,4 @@ pub use net_addr::NetAddr;
pub use bitcoin_network_connection::{BitcoinNetworkConnection, BitcoinNetworkError};
pub use block_header::BlockHeader;
pub use services::Services;
pub use var_int::VarInt;
pub use var_int::VarInt;
67 changes: 56 additions & 11 deletions net/src/message/addr_message.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,65 @@
use std::io;

use net_addr::NetAddr;
use Encode;
use VarInt;

#[cfg(test)]
mod tests {
use super::*;
use ::Services;

#[test]
fn it_encodes_an_addr_message() {
let input = vec![
// Payload:
0x01, // 1 address in this message
// Address:
0xE2,
0x15,
0x10,
0x4D, // Mon Dec 20 21:50:10 EST 2010 (only when version is >= 31402)
0x01,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, // 1 (NODE_NETWORK service - see version message)
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xFF,
0xFF,
0x0A,
0x00,
0x00,
0x01, // IPv4: 10.0.0.1, IPv6: ::ffff:10.0.0.1 (IPv4-mapped IPv6 address)
0x20,
0x8D];
let addr = AddrMessage {
addrs: vec![
NetAddr {
time: Some(1292899810),
services: Services::from(1),
ip: "::ffff:10.0.0.1".parse().unwrap(),
port: 8333 }] };
let mut encoded = vec![];
addr.encode(&mut encoded).expect("Failed to encode Addr");
assert_eq!(input, encoded);
}
}

/// addr message
#[derive(Debug, PartialEq)]
#[derive(Debug, Encode, PartialEq)]
pub struct AddrMessage {
#[count]
pub addrs: Vec<NetAddr>,
}

Expand All @@ -20,12 +73,4 @@ impl AddrMessage {
pub fn name(&self) -> &'static str {
"addr"
}
}

impl Encode for AddrMessage {
fn encode(&self, mut buff: &mut Vec<u8>) -> Result<(), io::Error> {
let _ = VarInt::new(self.addrs.len() as u64).encode(&mut buff);
let _ = self.addrs.encode(&mut buff);
Ok(())
}
}
19 changes: 6 additions & 13 deletions net/src/message/bitcrust/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use std::io;

use rand::{self, Rng};
use ring::hmac;

use Encode;

#[derive(Debug, PartialEq)]
#[derive(Debug, Encode, PartialEq)]
pub struct AuthenticatedBitcrustMessage {
signature: [u8; 32],
nonce: [u8; 8],
signature: [u8; 32],
}

impl AuthenticatedBitcrustMessage {
Expand Down Expand Up @@ -40,14 +38,9 @@ impl AuthenticatedBitcrustMessage {
pub fn len(&self) -> usize {
40
}
}

impl Encode for AuthenticatedBitcrustMessage {
fn encode(&self, mut buff: &mut Vec<u8>) -> Result<(), io::Error> {
// let mut v = Vec::with_capacity(40);

let _ = self.nonce.encode(&mut buff);
let _ = self.signature.encode(&mut buff);
Ok(())
#[inline]
pub fn name(&self) -> &'static str {
"bcr_pcr"
}
}
}
53 changes: 53 additions & 0 deletions net/src/message/block_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use Encode;
use VarInt;
use super::TransactionMessage;

#[derive(Debug, Encode, PartialEq)]
pub struct BlockMessage {
pub version: i32,
pub previous_block: [u8; 32],
pub merkle_root: [u8; 32],
pub timestamp: u32,
pub bits: u32,
pub nonce: u32,
#[count]
pub transactions: Vec<TransactionMessage>
}

impl BlockMessage {
#[inline]
pub fn len(&self) -> usize {
4usize + // version
32usize + // previous block
32usize + // merkle root
4usize + // timestamp
4usize + // bits
4usize + // nonce
4usize + // count of transactions
self.transactions.iter().map(|i| i.len()).sum::<usize>() // transactions
}

#[inline]
pub fn name(&self) -> &'static str {
"block"
}

pub fn new(version: i32, prev_block: &[u8], merkle_root: &[u8], timestamp: u32,
bits: u32, nonce: u32, transactions: Vec<TransactionMessage>) -> BlockMessage {
debug_assert!(prev_block.len() == 32);
let mut a: [u8; 32] = Default::default();
a.copy_from_slice(&prev_block);
debug_assert!(merkle_root.len() == 32);
let mut b: [u8; 32] = Default::default();
b.copy_from_slice(&merkle_root);
BlockMessage {
version: version,
previous_block: a,
merkle_root: b,
timestamp: timestamp,
bits: bits,
nonce: nonce,
transactions: transactions,
}
}
}
Loading

0 comments on commit 139ee61

Please sign in to comment.