"]
5 |
6 | [dependencies]
7 | log = "0.4"
8 | primitives = { path = "../primitives" }
9 | chain = { path = "../chain" }
10 | serialization = { path = "../serialization" }
11 |
--------------------------------------------------------------------------------
/import/src/blk.rs:
--------------------------------------------------------------------------------
1 | use std::{io, fs, path};
2 | use std::collections::BTreeSet;
3 | use ser::{ReadIterator, deserialize_iterator, Error as ReaderError};
4 | use block::Block;
5 | use fs::read_blk_dir;
6 |
7 | pub fn open_blk_file(path: P) -> Result where P: AsRef {
8 | trace!("Opening blk file: {:?}", path.as_ref());
9 | let file = try!(fs::File::open(path));
10 | let blk_file = BlkFile {
11 | reader: deserialize_iterator(file),
12 | };
13 | Ok(blk_file)
14 | }
15 |
16 | pub struct BlkFile {
17 | reader: ReadIterator,
18 | }
19 |
20 | impl Iterator for BlkFile {
21 | type Item = Result;
22 |
23 | fn next(&mut self) -> Option {
24 | self.reader.next()
25 | }
26 | }
27 |
28 | /// Creates iterator over bitcoind database blocks
29 | pub fn open_blk_dir(path: P) -> Result where P: AsRef {
30 | let files = read_blk_dir(path)?.collect::, _>>()?;
31 |
32 | let iter = files.into_iter()
33 | // flatten results...
34 | .flat_map(|file| open_blk_file(file.path))
35 | // flat iterators over each block in each file
36 | .flat_map(|file| file);
37 |
38 | let blk_dir = BlkDir {
39 | iter: Box::new(iter),
40 | };
41 |
42 | Ok(blk_dir)
43 | }
44 |
45 | /// Bitcoind database blocks iterator
46 | pub struct BlkDir {
47 | iter: Box>>,
48 | }
49 |
50 | impl Iterator for BlkDir {
51 | type Item = Result;
52 |
53 | fn next(&mut self) -> Option {
54 | self.iter.next()
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/import/src/block.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use hash::H32;
3 | use ser::{Deserializable, Reader, Error as ReaderError};
4 | use chain::IndexedBlock;
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct Block {
8 | pub magic: H32,
9 | pub block_size: u32,
10 | pub block: IndexedBlock,
11 | }
12 |
13 | impl Deserializable for Block {
14 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
15 | let block = Block {
16 | magic: try!(reader.read()),
17 | block_size: try!(reader.read()),
18 | block: try!(reader.read()),
19 | };
20 |
21 | Ok(block)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/import/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! Bitcoind blockchain database importer
2 |
3 | #[macro_use]
4 | extern crate log;
5 | extern crate primitives;
6 | extern crate serialization as ser;
7 | extern crate chain;
8 |
9 | mod blk;
10 | mod block;
11 | mod fs;
12 |
13 | pub use primitives::{hash, bytes};
14 |
15 | pub use blk::{open_blk_dir, BlkDir};
16 |
--------------------------------------------------------------------------------
/key/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "key"
3 | version = "0.1.0"
4 | authors = ["gguoss "]
5 |
6 | [dependencies]
7 | keys = { path = "../keys" }
8 |
--------------------------------------------------------------------------------
/key/src/main.rs:
--------------------------------------------------------------------------------
1 | extern crate keys;
2 |
3 | use keys::generator::Generator;
4 | use keys::{Private, KeyPair};
5 |
6 | fn main() {
7 | let random = keys::generator::Random::new(keys::Network::Testnet);
8 | let key = random.generate().unwrap();
9 | println!("{:?}", key);
10 | let private = key.private();
11 | let compressed_private = Private{
12 | network: private.network.clone(),
13 | secret: private.secret.clone(),
14 | compressed: true,
15 | };
16 | let compressed = KeyPair::from_private(compressed_private).unwrap();
17 | println!("compressed public key: {}",compressed.public());
18 | println!("address:{:?}", key.address().to_string());
19 | }
20 |
--------------------------------------------------------------------------------
/keys/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "keys"
3 | version = "0.1.0"
4 | authors = ["debris "]
5 |
6 | [dependencies]
7 | sr-std = { git = "https://github.com/chainx-org/sr-std", default-features = false }
8 | rand = { version = "0.4", optional = true }
9 | rustc-hex = { version = "2", optional = true }
10 | base58 = { version = "0.1", optional = true }
11 | libsecp256k1 = "0.2.2"
12 | bitcrypto = { path = "../crypto", default-features = false }
13 | primitives = { path = "../primitives", default-features = false }
14 | parity-codec = { version = "3.0", default-features = false }
15 | parity-codec-derive = { version = "3.0", default-features = false }
16 | serde_bytes = { git = "https://github.com/serde-rs/bytes", optional = true }
17 | serialization = { path = "../serialization", default-features = false }
18 | serde = { version = "1.0", optional = true }
19 | serde_derive = { version = "1.0", optional = true }
20 |
21 | [features]
22 | default = ["std"]
23 | std = [
24 | "sr-std/std",
25 | "rand",
26 | "rustc-hex",
27 | "base58",
28 | "bitcrypto/std",
29 | "parity-codec/std",
30 | "parity-codec-derive/std",
31 | "primitives/std",
32 | "serialization/std",
33 | "serde_bytes",
34 | "serde_derive",
35 | "serde"
36 | ]
37 |
--------------------------------------------------------------------------------
/keys/src/display.rs:
--------------------------------------------------------------------------------
1 | use rstd::ops::Deref;
2 | use Error;
3 |
4 | pub trait DisplayLayout {
5 | type Target: Deref;
6 |
7 | fn layout(&self) -> Self::Target;
8 |
9 | fn from_layout(data: &[u8]) -> Result where Self: Sized;
10 | }
11 |
--------------------------------------------------------------------------------
/keys/src/error.rs:
--------------------------------------------------------------------------------
1 | #[cfg(feature = "std")]
2 | use std::fmt;
3 | use secp256k1::Error as SecpError;
4 |
5 | #[cfg_attr(feature = "std", derive(Debug))]
6 | #[derive(PartialEq)]
7 | pub enum Error {
8 | InvalidPublic,
9 | InvalidSecret,
10 | InvalidMessage,
11 | InvalidSignature,
12 | InvalidNetwork,
13 | InvalidChecksum,
14 | InvalidPrivate,
15 | InvalidAddress,
16 | FailedKeyGeneration,
17 | }
18 |
19 | #[cfg(feature = "std")]
20 | impl fmt::Display for Error {
21 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 | let msg = match *self {
23 | Error::InvalidPublic => "Invalid Public",
24 | Error::InvalidSecret => "Invalid Secret",
25 | Error::InvalidMessage => "Invalid Message",
26 | Error::InvalidSignature => "Invalid Signature",
27 | Error::InvalidNetwork => "Invalid Network",
28 | Error::InvalidChecksum => "Invalid Checksum",
29 | Error::InvalidPrivate => "Invalid Private",
30 | Error::InvalidAddress => "Invalid Address",
31 | Error::FailedKeyGeneration => "Key generation failed",
32 | };
33 |
34 | msg.fmt(f)
35 | }
36 | }
37 |
38 | impl From for Error {
39 | fn from(e: SecpError) -> Self {
40 | match e {
41 | SecpError::InvalidPublicKey => Error::InvalidPublic,
42 | SecpError::InvalidSecretKey => Error::InvalidSecret,
43 | SecpError::InvalidMessage => Error::InvalidMessage,
44 | _ => Error::InvalidSignature,
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/keys/src/generator.rs:
--------------------------------------------------------------------------------
1 | #[cfg(feature = "std")]
2 | use rand::os::OsRng;
3 | use network::Network;
4 | use secp256k1::{PublicKey, SecretKey};
5 | use {KeyPair, Error};
6 |
7 | #[cfg(feature = "std")]
8 | pub trait Generator {
9 | fn generate(&self) -> Result;
10 | }
11 |
12 | pub struct Random {
13 | network: Network
14 | }
15 |
16 | impl Random {
17 | pub fn new(network: Network) -> Self {
18 | Random {
19 | network: network,
20 | }
21 | }
22 | }
23 |
24 | #[cfg(feature = "std")]
25 | impl Generator for Random {
26 | fn generate(&self) -> Result {
27 | let mut rng = OsRng::new().map_err(|_| Error::FailedKeyGeneration)?;
28 | let secret = SecretKey::random(&mut rng);
29 | let public = PublicKey::from_secret_key(&secret);
30 | Ok(KeyPair::from_keypair(secret, public, self.network))
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/keys/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! Bitcoin keys.
2 |
3 | #![cfg_attr(not(feature = "std"), no_std)]
4 | #[cfg(feature = "std")]
5 | extern crate rand;
6 | #[cfg(feature = "std")]
7 | extern crate rustc_hex as hex;
8 | #[cfg(feature = "std")]
9 | extern crate base58;
10 | extern crate secp256k1;
11 | extern crate bitcrypto as crypto;
12 | extern crate primitives;
13 | extern crate sr_std as rstd;
14 | #[macro_use]
15 | extern crate parity_codec_derive;
16 | extern crate parity_codec as codec;
17 | extern crate serialization as ser;
18 | #[cfg(feature = "std")]
19 | extern crate serde_bytes;
20 | #[cfg(feature = "std")]
21 | #[macro_use]
22 | extern crate serde_derive;
23 |
24 | pub mod generator;
25 | mod address;
26 | mod display;
27 | mod keypair;
28 | mod error;
29 | mod network;
30 | mod private;
31 | mod public;
32 | mod signature;
33 |
34 | pub use primitives::{hash, bytes};
35 |
36 | pub use address::{Type, Address};
37 | pub use display::DisplayLayout;
38 | pub use keypair::KeyPair;
39 | pub use error::Error;
40 | pub use private::Private;
41 | pub use public::Public;
42 | pub use signature::{Signature, CompactSignature};
43 | pub use network::Network;
44 |
45 | use hash::{H160, H256};
46 |
47 | /// 20 bytes long hash derived from public `ripemd160(sha256(public))`
48 | pub type AddressHash = H160;
49 | /// 32 bytes long secret key
50 | pub type Secret = H256;
51 | /// 32 bytes long signable message
52 | pub type Message = H256;
53 |
54 |
--------------------------------------------------------------------------------
/keys/src/network.rs:
--------------------------------------------------------------------------------
1 | // Copyright 2018 Chainpool
2 | use ser::{serialize, deserialize, Serializable, Stream, Reader, Deserializable};
3 | use primitives::io;
4 |
5 | #[cfg_attr(feature = "std", derive(Debug))]
6 | #[derive(PartialEq, Clone, Copy, Encode, Decode)]
7 | pub enum Network {
8 | Mainnet = 0,
9 | Testnet = 1,
10 | }
11 |
12 | impl Default for Network {
13 | fn default() -> Network {
14 | Network::Mainnet
15 | }
16 | }
17 |
18 | impl Network {
19 | pub fn from_u32(v: u32) -> Option {
20 | match v {
21 | 0 => Some(Network::Mainnet),
22 | 1 => Some(Network::Testnet),
23 | _ => None
24 | }
25 | }
26 | }
27 |
28 | impl Serializable for Network {
29 | fn serialize(&self, stream: &mut Stream) {
30 | match *self{
31 | Network::Mainnet => stream.append(&Network::Mainnet),
32 | Network::Testnet => stream.append(&Network::Testnet),
33 | };
34 | }
35 | }
36 |
37 | impl Deserializable for Network {
38 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
39 | let t: u32 = try!(reader.read());
40 | Network::from_u32(t).ok_or(io::ErrorKind::MalformedData)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/logs/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "logs"
3 | version = "0.1.0"
4 | authors = ["debris "]
5 |
6 | [dependencies]
7 | ansi_term = "0.9"
8 | log = "0.4"
9 | env_logger = "0.5"
10 | time = "0.1"
11 |
--------------------------------------------------------------------------------
/logs/src/lib.rs:
--------------------------------------------------------------------------------
1 | extern crate ansi_term;
2 | extern crate log;
3 | extern crate env_logger;
4 | extern crate time;
5 |
6 | use std::env;
7 | use ansi_term::Colour as Color;
8 | use log::{Record, Level};
9 | use env_logger::Builder;
10 | use std::io::Write;
11 |
12 | fn strftime() -> String {
13 | time::strftime("%Y-%m-%d %H:%M:%S %Z", &time::now()).expect("Time is incorrectly formatted")
14 | }
15 |
16 | pub trait LogFormatter: Send + Sync + 'static {
17 | fn format(&self, log_record: &Record) -> String;
18 | }
19 |
20 | pub struct DateLogFormatter;
21 |
22 | impl LogFormatter for DateLogFormatter {
23 | fn format(&self, record: &Record) -> String {
24 | let timestamp = strftime();
25 | format!("{} {} {} {}", timestamp, record.level(), record.target(), record.args())
26 | }
27 | }
28 |
29 | pub struct DateAndColorLogFormatter;
30 |
31 | impl LogFormatter for DateAndColorLogFormatter {
32 | fn format(&self, record: &Record) -> String {
33 | let timestamp = strftime();
34 | let log_level = match record.level() {
35 | Level::Error => Color::Fixed(9).bold().paint(record.level().to_string()),
36 | Level::Warn => Color::Fixed(11).bold().paint(record.level().to_string()),
37 | Level::Info => Color::Fixed(10).paint(record.level().to_string()),
38 | Level::Debug => Color::Fixed(14).paint(record.level().to_string()),
39 | Level::Trace => Color::Fixed(12).paint(record.level().to_string()),
40 | };
41 | format!("{} {} {} {}"
42 | , Color::Fixed(8).bold().paint(timestamp)
43 | , log_level
44 | , Color::Fixed(8).paint(record.target())
45 | , record.args())
46 | }
47 | }
48 |
49 | pub fn init(filters: &str, formatter: T) where T: LogFormatter {
50 | let mut builder = Builder::new();
51 |
52 | let filters = match env::var("RUST_LOG") {
53 | Ok(env_filters) => format!("{},{}", filters, env_filters),
54 | Err(_) => filters.into(),
55 | };
56 |
57 | builder.parse(&filters);
58 | builder.format(move |buf, record| {
59 | writeln!(buf, "{}", formatter.format(record))
60 | });
61 |
62 | builder.init();
63 | }
64 |
--------------------------------------------------------------------------------
/message/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "message"
3 | version = "0.1.0"
4 | authors = ["debris "]
5 |
6 | [dependencies]
7 | byteorder = "1.0"
8 |
9 | bitcrypto = { path = "../crypto" }
10 | chain = { path = "../chain" }
11 | primitives = { path = "../primitives" }
12 | serialization = { path = "../serialization" }
13 | serialization_derive = { path = "../serialization_derive" }
14 | network = { path = "../network" }
15 |
--------------------------------------------------------------------------------
/message/src/common/address.rs:
--------------------------------------------------------------------------------
1 | use bytes::Bytes;
2 | use ser::deserialize;
3 | use common::{Port, IpAddress, Services};
4 |
5 | #[derive(Debug, Default, PartialEq, Clone, Serializable, Deserializable)]
6 | pub struct NetAddress {
7 | pub services: Services,
8 | pub address: IpAddress,
9 | pub port: Port,
10 | }
11 |
12 | impl From<&'static str> for NetAddress {
13 | fn from(s: &'static str) -> Self {
14 | let bytes: Bytes = s.into();
15 | deserialize(bytes.as_ref()).unwrap()
16 | }
17 | }
18 |
19 | #[cfg(test)]
20 | mod tests {
21 | use ser::{serialize, deserialize};
22 | use common::Services;
23 | use super::NetAddress;
24 |
25 | #[test]
26 | fn test_net_address_serialize() {
27 | let expected = vec![
28 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01,
30 | 0x20, 0x8d
31 | ].into();
32 |
33 | let address = NetAddress {
34 | services: Services::default().with_network(true),
35 | address: "::ffff:a00:1".into(),
36 | port: 8333.into(),
37 | };
38 |
39 | assert_eq!(serialize(&address), expected);
40 | }
41 |
42 | #[test]
43 | fn test_net_address_deserialize() {
44 | let bytes = vec![
45 | 0x01u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01,
47 | 0x20, 0x8d
48 | ];
49 |
50 | let expected = NetAddress {
51 | services: Services::default().with_network(true),
52 | address: "::ffff:a00:1".into(),
53 | port: 8333.into(),
54 | };
55 |
56 | assert_eq!(expected, deserialize(&bytes as &[u8]).unwrap());
57 | }
58 |
59 | #[test]
60 | fn test_net_address_from_static_str() {
61 | let expected = NetAddress {
62 | services: Services::default().with_network(true),
63 | address: "::ffff:a00:1".into(),
64 | port: 8333.into(),
65 |
66 | };
67 | let s = "010000000000000000000000000000000000ffff0a000001208d";
68 | assert_eq!(expected, s.into());
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/message/src/common/block_header_and_ids.rs:
--------------------------------------------------------------------------------
1 | use chain::{BlockHeader, ShortTransactionID};
2 | use common::PrefilledTransaction;
3 |
4 | #[derive(Debug, PartialEq, Serializable, Deserializable)]
5 | pub struct BlockHeaderAndIDs {
6 | pub header: BlockHeader,
7 | pub nonce: u64,
8 | pub short_ids: Vec,
9 | pub prefilled_transactions: Vec,
10 | }
11 |
--------------------------------------------------------------------------------
/message/src/common/block_transactions.rs:
--------------------------------------------------------------------------------
1 | use hash::H256;
2 | use chain::Transaction;
3 |
4 | #[derive(Debug, PartialEq, Serializable, Deserializable)]
5 | pub struct BlockTransactions {
6 | pub blockhash: H256,
7 | pub transactions: Vec,
8 | }
9 |
--------------------------------------------------------------------------------
/message/src/common/block_transactions_request.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use hash::H256;
3 | use ser::{
4 | Serializable, Stream, CompactInteger,
5 | Deserializable, Reader, Error as ReaderError,
6 | };
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct BlockTransactionsRequest {
10 | pub blockhash: H256,
11 | pub indexes: Vec,
12 | }
13 |
14 | impl Serializable for BlockTransactionsRequest {
15 | fn serialize(&self, stream: &mut Stream) {
16 | let indexes: Vec = self.indexes
17 | .iter()
18 | .map(|x| (*x).into())
19 | .collect();
20 |
21 | stream
22 | .append(&self.blockhash)
23 | .append_list(&indexes);
24 | }
25 | }
26 |
27 | impl Deserializable for BlockTransactionsRequest {
28 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
29 | let blockhash = try!(reader.read());
30 | let indexes: Vec = try!(reader.read_list());
31 |
32 | let request = BlockTransactionsRequest {
33 | blockhash: blockhash,
34 | indexes: indexes.into_iter().map(Into::into).collect(),
35 | };
36 |
37 | Ok(request)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/message/src/common/mod.rs:
--------------------------------------------------------------------------------
1 | mod address;
2 | mod block_header_and_ids;
3 | mod block_transactions;
4 | mod block_transactions_request;
5 | mod command;
6 | mod inventory;
7 | mod ip;
8 | mod port;
9 | mod prefilled_transaction;
10 | mod service;
11 |
12 | pub use self::address::NetAddress;
13 | pub use self::block_header_and_ids::BlockHeaderAndIDs;
14 | pub use self::block_transactions::BlockTransactions;
15 | pub use self::block_transactions_request::BlockTransactionsRequest;
16 | pub use self::command::Command;
17 | pub use self::inventory::{InventoryVector, InventoryType};
18 | pub use self::ip::IpAddress;
19 | pub use self::port::Port;
20 | pub use self::prefilled_transaction::PrefilledTransaction;
21 | pub use self::service::Services;
22 |
--------------------------------------------------------------------------------
/message/src/common/port.rs:
--------------------------------------------------------------------------------
1 |
2 | use primitives::io;
3 | use primitives::io::{Read, Write};
4 | use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
5 | use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
6 |
7 | #[derive(Debug, Default, PartialEq, Clone, Copy)]
8 | pub struct Port(u16);
9 |
10 | impl From for Port {
11 | fn from(port: u16) -> Self {
12 | Port(port)
13 | }
14 | }
15 |
16 | impl From for u16 {
17 | fn from(port: Port) -> Self {
18 | port.0
19 | }
20 | }
21 |
22 | impl Serializable for Port {
23 | fn serialize(&self, stream: &mut Stream) {
24 | stream.write_u16::(self.0).unwrap();
25 | }
26 | }
27 |
28 | impl Deserializable for Port {
29 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
30 | Ok(try!(reader.read_u16::().map(Port)))
31 | }
32 | }
33 |
34 | #[cfg(test)]
35 | mod tests {
36 | use ser::{serialize, deserialize};
37 | use super::Port;
38 |
39 | #[test]
40 | fn test_port_serialize() {
41 | assert_eq!(serialize(&Port::from(1)), "0001".into());
42 | assert_eq!(serialize(&Port::from(0x1234)), "1234".into());
43 | }
44 |
45 | #[test]
46 | fn test_port_deserialize() {
47 | assert_eq!(Port::from(1), deserialize(&[0x00u8, 0x01] as &[u8]).unwrap());
48 | assert_eq!(Port::from(0x1234), deserialize(&[0x12u8, 0x34] as &[u8]).unwrap());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/message/src/common/prefilled_transaction.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{
3 | Serializable, Stream, CompactInteger,
4 | Deserializable, Reader, Error as ReaderError
5 | };
6 | use chain::Transaction;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct PrefilledTransaction {
10 | pub index: usize,
11 | pub transaction: Transaction,
12 | }
13 |
14 | impl Serializable for PrefilledTransaction {
15 | fn serialize(&self, stream: &mut Stream) {
16 | stream
17 | .append(&CompactInteger::from(self.index))
18 | .append(&self.transaction);
19 | }
20 | }
21 |
22 | impl Deserializable for PrefilledTransaction {
23 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
24 | let compact: CompactInteger = try!(reader.read());
25 | let tx = PrefilledTransaction {
26 | index: compact.into(),
27 | transaction: try!(reader.read()),
28 | };
29 |
30 | Ok(tx)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/message/src/common/service.rs:
--------------------------------------------------------------------------------
1 | #[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Serializable, Deserializable)]
2 | pub struct Services(u64);
3 |
4 | impl From for u64 {
5 | fn from(s: Services) -> Self {
6 | s.0
7 | }
8 | }
9 |
10 | impl From for Services {
11 | fn from(v: u64) -> Self {
12 | Services(v)
13 | }
14 | }
15 |
16 | impl Services {
17 | pub fn network(&self) -> bool {
18 | self.bit_at(0)
19 | }
20 |
21 | pub fn with_network(mut self, v: bool) -> Self {
22 | self.set_bit(0, v);
23 | self
24 | }
25 |
26 | pub fn getutxo(&self) -> bool {
27 | self.bit_at(1)
28 | }
29 |
30 | pub fn with_getutxo(mut self, v: bool) -> Self {
31 | self.set_bit(1, v);
32 | self
33 | }
34 |
35 | pub fn bloom(&self) -> bool {
36 | self.bit_at(2)
37 | }
38 |
39 | pub fn with_bloom(mut self, v: bool) -> Self {
40 | self.set_bit(2, v);
41 | self
42 | }
43 |
44 | pub fn witness(&self) -> bool {
45 | self.bit_at(3)
46 | }
47 |
48 | pub fn with_witness(mut self, v: bool) -> Self {
49 | self.set_bit(3, v);
50 | self
51 | }
52 |
53 | pub fn xthin(&self) -> bool {
54 | self.bit_at(4)
55 | }
56 |
57 | pub fn with_xthin(mut self, v: bool) -> Self {
58 | self.set_bit(4, v);
59 | self
60 | }
61 |
62 | pub fn bitcoin_cash(&self) -> bool {
63 | self.bit_at(5)
64 | }
65 |
66 | pub fn with_bitcoin_cash(mut self, v: bool) -> Self {
67 | self.set_bit(5, v);
68 | self
69 | }
70 |
71 | pub fn includes(&self, other: &Self) -> bool {
72 | self.0 & other.0 == other.0
73 | }
74 |
75 | fn set_bit(&mut self, bit: usize, bit_value: bool) {
76 | if bit_value {
77 | self.0 |= 1 << bit
78 | } else {
79 | self.0 &= !(1 << bit)
80 | }
81 | }
82 |
83 | fn bit_at(&self, bit: usize) -> bool {
84 | self.0 & (1 << bit) != 0
85 | }
86 | }
87 |
88 | #[cfg(test)]
89 | mod test {
90 | use super::Services;
91 |
92 | #[test]
93 | fn test_serivces_includes() {
94 | let s1 = Services::default()
95 | .with_witness(true)
96 | .with_xthin(true);
97 | let s2 = Services::default()
98 | .with_witness(true);
99 |
100 | assert!(s1.witness());
101 | assert!(s1.xthin());
102 | assert!(s2.witness());
103 | assert!(!s2.xthin());
104 | assert!(s1.includes(&s2));
105 | assert!(!s2.includes(&s1));
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/message/src/error.rs:
--------------------------------------------------------------------------------
1 | use std::{fmt, error};
2 | use ser::Error as ReaderError;
3 |
4 | pub type MessageResult = Result;
5 |
6 | #[derive(Debug, PartialEq, Clone)]
7 | pub enum Error {
8 | /// Deserialization failed.
9 | Deserialize,
10 | /// Command has wrong format or is unsupported.
11 | InvalidCommand,
12 | /// Network magic comes from different network.
13 | InvalidMagic,
14 | /// Invalid checksum.
15 | InvalidChecksum,
16 | /// Invalid version.
17 | InvalidVersion,
18 | }
19 |
20 | impl From for Error {
21 | fn from(_: ReaderError) -> Self {
22 | Error::Deserialize
23 | }
24 | }
25 |
26 | impl fmt::Display for Error {
27 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 | f.write_str(error::Error::description(self))
29 | }
30 | }
31 |
32 | impl error::Error for Error {
33 | fn description(&self) -> &str {
34 | match *self {
35 | Error::Deserialize => "Message Deserialization Error",
36 | Error::InvalidCommand => "Invalid Message Command",
37 | Error::InvalidMagic => "Invalid Network Magic",
38 | Error::InvalidChecksum => "Invalid message chacksum",
39 | Error::InvalidVersion => "Unsupported protocol version",
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/message/src/lib.rs:
--------------------------------------------------------------------------------
1 | extern crate byteorder;
2 | extern crate bitcrypto as crypto;
3 | extern crate chain;
4 | extern crate primitives;
5 | extern crate serialization as ser;
6 | #[macro_use]
7 | extern crate serialization_derive;
8 | extern crate network;
9 |
10 | pub mod common;
11 | mod message;
12 | mod serialization;
13 | pub mod types;
14 | mod error;
15 |
16 | pub use primitives::{hash, bytes};
17 |
18 | pub use common::{Command, Services};
19 | pub use message::{Message, MessageHeader, Payload, to_raw_message};
20 | pub use serialization::{serialize_payload, deserialize_payload};
21 | pub use error::{MessageResult, Error};
22 |
--------------------------------------------------------------------------------
/message/src/message/message.rs:
--------------------------------------------------------------------------------
1 | use ser::Stream;
2 | use bytes::{TaggedBytes, Bytes};
3 | use network::Magic;
4 | use common::Command;
5 | use serialization::serialize_payload_with_flags;
6 | use {Payload, MessageResult, MessageHeader};
7 |
8 | pub fn to_raw_message(magic: Magic, command: Command, payload: &Bytes) -> Bytes {
9 | let header = MessageHeader::for_data(magic, command, payload);
10 | let mut stream = Stream::default();
11 | stream.append(&header);
12 | stream.append_slice(payload);
13 | stream.out()
14 | }
15 |
16 | pub struct Message {
17 | bytes: TaggedBytes,
18 | }
19 |
20 | impl Message where T: Payload {
21 | pub fn new(magic: Magic, version: u32, payload: &T) -> MessageResult {
22 | Self::with_flags(magic, version, payload, 0)
23 | }
24 |
25 | pub fn with_flags(magic: Magic, version: u32, payload: &T, serialization_flags: u32) -> MessageResult {
26 | let serialized = try!(serialize_payload_with_flags(payload, version, serialization_flags));
27 |
28 | let message = Message {
29 | bytes: TaggedBytes::new(to_raw_message(magic, T::command().into(), &serialized)),
30 | };
31 |
32 | Ok(message)
33 | }
34 |
35 | pub fn len(&self) -> usize {
36 | self.bytes.len()
37 | }
38 | }
39 |
40 | impl AsRef<[u8]> for Message {
41 | fn as_ref(&self) -> &[u8] {
42 | self.bytes.as_ref()
43 | }
44 | }
45 |
46 | impl From> for Bytes {
47 | fn from(m: Message) -> Self {
48 | m.bytes.into_raw()
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/message/src/message/message_header.rs:
--------------------------------------------------------------------------------
1 | use hash::H32;
2 | use ser::{Serializable, Stream, Reader};
3 | use crypto::checksum;
4 | use network::Magic;
5 | use common::Command;
6 | use Error;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct MessageHeader {
10 | pub magic: Magic,
11 | pub command: Command,
12 | pub len: u32,
13 | pub checksum: H32,
14 | }
15 |
16 | impl MessageHeader {
17 | pub fn for_data(magic: Magic, command: Command, data: &[u8]) -> Self {
18 | MessageHeader {
19 | magic: magic,
20 | command: command,
21 | len: data.len() as u32,
22 | checksum: checksum(data),
23 | }
24 | }
25 | }
26 |
27 | impl MessageHeader {
28 | pub fn deserialize(data: &[u8], expected: Magic) -> Result {
29 | if data.len() != 24 {
30 | return Err(Error::Deserialize);
31 | }
32 |
33 | let mut reader = Reader::new(data);
34 | let magic: u32 = try!(reader.read());
35 | let magic = Magic::from(magic);
36 | if expected != magic {
37 | return Err(Error::InvalidMagic);
38 | }
39 |
40 | let header = MessageHeader {
41 | magic: magic,
42 | command: try!(reader.read()),
43 | len: try!(reader.read()),
44 | checksum: try!(reader.read()),
45 | };
46 |
47 | Ok(header)
48 | }
49 | }
50 |
51 | impl Serializable for MessageHeader {
52 | fn serialize(&self, stream: &mut Stream) {
53 | stream
54 | .append(&self.magic)
55 | .append(&self.command)
56 | .append(&self.len)
57 | .append(&self.checksum);
58 | }
59 | }
60 |
61 | #[cfg(test)]
62 | mod tests {
63 | use bytes::Bytes;
64 | use ser::serialize;
65 | use network::{Network, ConsensusFork};
66 | use super::MessageHeader;
67 |
68 | #[test]
69 | fn test_message_header_serialization() {
70 | let expected = "f9beb4d96164647200000000000000001f000000ed52399b".into();
71 | let header = MessageHeader {
72 | magic: Network::Mainnet.magic(&ConsensusFork::BitcoinCore),
73 | command: "addr".into(),
74 | len: 0x1f,
75 | checksum: "ed52399b".into(),
76 | };
77 |
78 | assert_eq!(serialize(&header), expected);
79 | }
80 |
81 | #[test]
82 | fn test_message_header_deserialization() {
83 | let raw: Bytes = "f9beb4d96164647200000000000000001f000000ed52399b".into();
84 | let expected = MessageHeader {
85 | magic: Network::Mainnet.magic(&ConsensusFork::BitcoinCore),
86 | command: "addr".into(),
87 | len: 0x1f,
88 | checksum: "ed52399b".into(),
89 | };
90 |
91 | assert_eq!(expected, MessageHeader::deserialize(&raw, Network::Mainnet.magic(&ConsensusFork::BitcoinCore)).unwrap());
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/message/src/message/mod.rs:
--------------------------------------------------------------------------------
1 | mod message;
2 | mod message_header;
3 | pub mod payload;
4 |
5 | pub use self::message::{Message, to_raw_message};
6 | pub use self::message_header::MessageHeader;
7 | pub use self::payload::Payload;
8 |
--------------------------------------------------------------------------------
/message/src/message/payload.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Reader, Stream};
3 | use MessageResult;
4 |
5 | pub trait Payload: Send + 'static {
6 | fn version() -> u32;
7 | fn command() -> &'static str;
8 | fn deserialize_payload(reader: &mut Reader, version: u32) -> MessageResult where Self: Sized, T: io::Read;
9 | fn serialize_payload(&self, stream: &mut Stream, version: u32) -> MessageResult<()>;
10 | }
11 |
--------------------------------------------------------------------------------
/message/src/serialization/mod.rs:
--------------------------------------------------------------------------------
1 | mod stream;
2 | mod reader;
3 |
4 | pub use self::stream::{serialize_payload, serialize_payload_with_flags};
5 | pub use self::reader::deserialize_payload;
6 |
--------------------------------------------------------------------------------
/message/src/serialization/reader.rs:
--------------------------------------------------------------------------------
1 |
2 | use primitives::io;
3 | use ser::Reader;
4 | use Payload;
5 | use Error;
6 |
7 | pub fn deserialize_payload(buffer: &[u8], version: u32) -> Result where T: Payload {
8 | let mut reader = PayloadReader::new(buffer, version);
9 | let result = try!(reader.read());
10 | if !reader.is_finished() {
11 | return Err(Error::Deserialize);
12 | }
13 |
14 | Ok(result)
15 | }
16 |
17 | pub struct PayloadReader {
18 | reader: Reader,
19 | version: u32,
20 | }
21 |
22 | impl<'a> PayloadReader<&'a [u8]> {
23 | pub fn new(buffer: &'a [u8], version: u32) -> Self {
24 | PayloadReader {
25 | reader: Reader::new(buffer),
26 | version: version,
27 | }
28 | }
29 |
30 | pub fn read(&mut self) -> Result where T: Payload {
31 | if T::version() > self.version {
32 | return Err(Error::InvalidVersion);
33 | }
34 |
35 | T::deserialize_payload(&mut self.reader, self.version)
36 | }
37 |
38 | pub fn is_finished(&mut self) -> bool {
39 | self.reader.is_finished()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/message/src/serialization/stream.rs:
--------------------------------------------------------------------------------
1 | use bytes::Bytes;
2 | use ser::Stream;
3 | use {Payload, Error, MessageResult};
4 |
5 | pub fn serialize_payload(t: &T, version: u32) -> MessageResult where T: Payload {
6 | serialize_payload_with_flags(t, version, 0)
7 | }
8 |
9 | pub fn serialize_payload_with_flags(t: &T, version: u32, serialization_flags: u32) -> MessageResult where T: Payload {
10 | let mut stream = PayloadStream::new(version, serialization_flags);
11 | try!(stream.append(t));
12 | Ok(stream.out())
13 | }
14 |
15 | pub struct PayloadStream {
16 | stream: Stream,
17 | version: u32,
18 | }
19 |
20 | impl PayloadStream {
21 | pub fn new(version: u32, serialization_flags: u32) -> Self {
22 | PayloadStream {
23 | stream: Stream::with_flags(serialization_flags),
24 | version: version,
25 | }
26 | }
27 |
28 | pub fn append(&mut self, t: &T) -> MessageResult<()> where T: Payload {
29 | if T::version() > self.version {
30 | return Err(Error::InvalidVersion);
31 | }
32 |
33 | t.serialize_payload(&mut self.stream, self.version)
34 | }
35 |
36 | pub fn out(self) -> Bytes {
37 | self.stream.out()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/message/src/types/block.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use chain::Block as ChainBlock;
4 | use {Payload, MessageResult};
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct Block {
8 | pub block: ChainBlock,
9 | }
10 |
11 | impl Block {
12 | pub fn with_block(block: ChainBlock) -> Self {
13 | Block {
14 | block: block,
15 | }
16 | }
17 | }
18 |
19 | impl Payload for Block {
20 | fn version() -> u32 {
21 | 0
22 | }
23 |
24 | fn command() -> &'static str {
25 | "block"
26 | }
27 |
28 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
29 | let tx = Block {
30 | block: try!(reader.read()),
31 | };
32 |
33 | Ok(tx)
34 | }
35 |
36 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
37 | stream.append(&self.block);
38 | Ok(())
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/message/src/types/blocktxn.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use common::BlockTransactions;
4 | use {MessageResult, Payload};
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct BlockTxn {
8 | pub request: BlockTransactions,
9 | }
10 |
11 | impl Payload for BlockTxn {
12 | fn version() -> u32 {
13 | 70014
14 | }
15 |
16 | fn command() -> &'static str {
17 | "blocktxn"
18 | }
19 |
20 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
21 | let block = BlockTxn {
22 | request: try!(reader.read()),
23 | };
24 |
25 | Ok(block)
26 | }
27 |
28 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
29 | stream.append(&self.request);
30 | Ok(())
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/message/src/types/compactblock.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use common::BlockHeaderAndIDs;
4 | use {Payload, MessageResult};
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct CompactBlock {
8 | pub header: BlockHeaderAndIDs,
9 | }
10 |
11 | impl Payload for CompactBlock {
12 | fn version() -> u32 {
13 | 70014
14 | }
15 |
16 | fn command() -> &'static str {
17 | "cmpctblock"
18 | }
19 |
20 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
21 | let block = CompactBlock {
22 | header: try!(reader.read()),
23 | };
24 |
25 | Ok(block)
26 | }
27 |
28 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
29 | stream.append(&self.header);
30 | Ok(())
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/message/src/types/feefilter.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct FeeFilter {
7 | pub fee_rate: u64,
8 | }
9 |
10 | impl FeeFilter {
11 | pub fn with_fee_rate(fee_rate: u64) -> Self {
12 | FeeFilter {
13 | fee_rate: fee_rate,
14 | }
15 | }
16 | }
17 |
18 | impl Payload for FeeFilter {
19 | fn version() -> u32 {
20 | 70013
21 | }
22 |
23 | fn command() -> &'static str {
24 | "feefilter"
25 | }
26 |
27 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
28 | let fee_filter = FeeFilter {
29 | fee_rate: try!(reader.read()),
30 | };
31 |
32 | Ok(fee_filter)
33 | }
34 |
35 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
36 | stream.append(&self.fee_rate);
37 | Ok(())
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/message/src/types/filteradd.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use bytes::Bytes;
3 | use ser::{Stream, Reader};
4 | use {Payload, MessageResult};
5 |
6 | pub const FILTERADD_MAX_DATA_LEN: usize = 520;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct FilterAdd {
10 | // TODO: check how this should be serialized
11 | pub data: Bytes,
12 | }
13 |
14 | impl Payload for FilterAdd {
15 | fn version() -> u32 {
16 | 70001
17 | }
18 |
19 | fn command() -> &'static str {
20 | "filteradd"
21 | }
22 |
23 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
24 | let filteradd = FilterAdd {
25 | data: try!(reader.read()),
26 | };
27 |
28 | Ok(filteradd)
29 | }
30 |
31 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
32 | stream.append(&self.data);
33 | Ok(())
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/message/src/types/filterclear.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct FilterClear;
7 |
8 | impl Payload for FilterClear {
9 | fn version() -> u32 {
10 | 70001
11 | }
12 |
13 | fn command() -> &'static str {
14 | "filterclear"
15 | }
16 |
17 | fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
18 | Ok(FilterClear)
19 | }
20 |
21 | fn serialize_payload(&self, _stream: &mut Stream, _version: u32) -> MessageResult<()> {
22 | Ok(())
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/message/src/types/getaddr.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct GetAddr;
7 |
8 | impl Payload for GetAddr {
9 | fn version() -> u32 {
10 | 0
11 | }
12 |
13 | fn command() -> &'static str {
14 | "getaddr"
15 | }
16 |
17 | fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
18 | Ok(GetAddr)
19 | }
20 |
21 | fn serialize_payload(&self, _stream: &mut Stream, _version: u32) -> MessageResult<()> {
22 | Ok(())
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/message/src/types/getblocks.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use hash::H256;
3 | use ser::{Stream, Reader};
4 | use {Payload, MessageResult};
5 |
6 | pub const GETBLOCKS_MAX_RESPONSE_HASHES: usize = 500;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct GetBlocks {
10 | pub version: u32,
11 | pub block_locator_hashes: Vec,
12 | pub hash_stop: H256,
13 | }
14 |
15 | impl Payload for GetBlocks {
16 | fn version() -> u32 {
17 | 0
18 | }
19 |
20 | fn command() -> &'static str {
21 | "getblocks"
22 | }
23 |
24 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
25 | let get_blocks = GetBlocks {
26 | version: try!(reader.read()),
27 | block_locator_hashes: try!(reader.read_list_max(500)),
28 | hash_stop: try!(reader.read()),
29 | };
30 |
31 | Ok(get_blocks)
32 | }
33 |
34 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
35 | stream
36 | .append(&self.version)
37 | .append_list(&self.block_locator_hashes)
38 | .append(&self.hash_stop);
39 | Ok(())
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/message/src/types/getblocktxn.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use common::BlockTransactionsRequest;
4 | use {Payload, MessageResult};
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct GetBlockTxn {
8 | pub request: BlockTransactionsRequest,
9 | }
10 |
11 | impl Payload for GetBlockTxn {
12 | fn version() -> u32 {
13 | 70014
14 | }
15 |
16 | fn command() -> &'static str {
17 | "getblocktxn"
18 | }
19 |
20 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
21 | let get_block = GetBlockTxn {
22 | request: try!(reader.read()),
23 | };
24 |
25 | Ok(get_block)
26 | }
27 |
28 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
29 | stream.append(&self.request);
30 | Ok(())
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/message/src/types/getdata.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use common::InventoryVector;
4 | use {Payload, MessageResult};
5 |
6 | pub const GETDATA_MAX_INVENTORY_LEN: usize = 50_000;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct GetData {
10 | pub inventory: Vec,
11 | }
12 |
13 | impl GetData {
14 | pub fn with_inventory(inventory: Vec) -> Self {
15 | GetData {
16 | inventory: inventory,
17 | }
18 | }
19 | }
20 |
21 | impl Payload for GetData {
22 | fn version() -> u32 {
23 | 0
24 | }
25 |
26 | fn command() -> &'static str {
27 | "getdata"
28 | }
29 |
30 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
31 | let inv = GetData {
32 | inventory: try!(reader.read_list_max(50_000)),
33 | };
34 |
35 | Ok(inv)
36 | }
37 |
38 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
39 | stream.append_list(&self.inventory);
40 | Ok(())
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/message/src/types/getheaders.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use hash::H256;
3 | use ser::{Stream, Reader};
4 | use {Payload, MessageResult};
5 |
6 | pub const GETHEADERS_MAX_RESPONSE_HEADERS: usize = 2_000;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct GetHeaders {
10 | pub version: u32,
11 | pub block_locator_hashes: Vec,
12 | pub hash_stop: H256,
13 | }
14 |
15 | impl GetHeaders {
16 | pub fn with_block_locator_hashes(block_locator_hashes: Vec) -> Self {
17 | GetHeaders {
18 | version: 0, // this field is ignored by implementations
19 | block_locator_hashes: block_locator_hashes,
20 | hash_stop: H256::default(),
21 | }
22 | }
23 | }
24 |
25 | impl Payload for GetHeaders {
26 | fn version() -> u32 {
27 | 0
28 | }
29 |
30 | fn command() -> &'static str {
31 | "getheaders"
32 | }
33 |
34 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
35 | let get_blocks = GetHeaders {
36 | version: try!(reader.read()),
37 | block_locator_hashes: try!(reader.read_list_max(2000)),
38 | hash_stop: try!(reader.read()),
39 | };
40 |
41 | Ok(get_blocks)
42 | }
43 |
44 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
45 | stream
46 | .append(&self.version)
47 | .append_list(&self.block_locator_hashes)
48 | .append(&self.hash_stop);
49 | Ok(())
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/message/src/types/headers.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use chain::BlockHeader;
3 | use ser::{Stream, Reader, Serializable, Deserializable, CompactInteger, Error as ReaderError};
4 | use {Payload, MessageResult};
5 |
6 | pub const HEADERS_MAX_HEADERS_LEN: usize = 2000;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct Headers {
10 | pub headers: Vec,
11 | }
12 |
13 | impl Headers {
14 | pub fn with_headers(headers: Vec) -> Self {
15 | Headers {
16 | headers: headers,
17 | }
18 | }
19 | }
20 |
21 | #[derive(Debug, PartialEq)]
22 | struct HeaderWithTxnCount {
23 | header: BlockHeader,
24 | }
25 |
26 | impl From for BlockHeader {
27 | fn from(header: HeaderWithTxnCount) -> BlockHeader {
28 | header.header
29 | }
30 | }
31 |
32 | #[derive(Debug, PartialEq)]
33 | struct HeaderWithTxnCountRef<'a> {
34 | header: &'a BlockHeader,
35 | }
36 |
37 | impl<'a> From<&'a BlockHeader> for HeaderWithTxnCountRef<'a> {
38 | fn from(header: &'a BlockHeader) -> Self {
39 | HeaderWithTxnCountRef {
40 | header: header,
41 | }
42 | }
43 | }
44 |
45 | impl Payload for Headers {
46 | fn version() -> u32 {
47 | 0
48 | }
49 |
50 | fn command() -> &'static str {
51 | "headers"
52 | }
53 |
54 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
55 | let headers_with_txn_count: Vec = try!(reader.read_list());
56 | let headers = Headers {
57 | headers: headers_with_txn_count.into_iter().map(Into::into).collect(),
58 | };
59 |
60 | Ok(headers)
61 | }
62 |
63 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
64 | let headers_with_txn_count: Vec = self.headers.iter().map(Into::into).collect();
65 | stream.append_list(&headers_with_txn_count);
66 | Ok(())
67 | }
68 | }
69 |
70 | impl<'a> Serializable for HeaderWithTxnCountRef<'a> {
71 | fn serialize(&self, stream: &mut Stream) {
72 | stream
73 | .append(self.header)
74 | .append(&CompactInteger::from(0u32));
75 | }
76 | }
77 |
78 | impl Deserializable for HeaderWithTxnCount {
79 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
80 | let header = HeaderWithTxnCount {
81 | header: try!(reader.read()),
82 | };
83 |
84 | let txn_count: CompactInteger = try!(reader.read());
85 | if txn_count != 0u32.into() {
86 | return Err(io::ErrorKind::MalformedData);
87 | }
88 |
89 | Ok(header)
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/message/src/types/inv.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use common::InventoryVector;
4 | use {Payload, MessageResult};
5 |
6 | pub const INV_MAX_INVENTORY_LEN: usize = 50_000;
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct Inv {
10 | pub inventory: Vec,
11 | }
12 |
13 | impl Inv {
14 | pub fn with_inventory(inventory: Vec) -> Self {
15 | Inv {
16 | inventory: inventory,
17 | }
18 | }
19 | }
20 |
21 | impl Payload for Inv {
22 | fn version() -> u32 {
23 | 0
24 | }
25 |
26 | fn command() -> &'static str {
27 | "inv"
28 | }
29 |
30 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
31 | let inv = Inv {
32 | inventory: try!(reader.read_list_max(50_000)),
33 | };
34 |
35 | Ok(inv)
36 | }
37 |
38 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
39 | stream.append_list(&self.inventory);
40 | Ok(())
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/message/src/types/mempool.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct MemPool;
7 |
8 | impl Payload for MemPool {
9 | fn version() -> u32 {
10 | 60002
11 | }
12 |
13 | fn command() -> &'static str {
14 | "mempool"
15 | }
16 |
17 | fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
18 | Ok(MemPool)
19 | }
20 |
21 | fn serialize_payload(&self, _stream: &mut Stream, _version: u32) -> MessageResult<()> {
22 | Ok(())
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/message/src/types/merkle_block.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use hash::H256;
3 | use bytes::Bytes;
4 | use ser::{Stream, Reader};
5 | use chain::BlockHeader;
6 | use {Payload, MessageResult};
7 |
8 | #[derive(Debug, PartialEq)]
9 | pub struct MerkleBlock {
10 | pub block_header: BlockHeader,
11 | pub total_transactions: u32,
12 | pub hashes: Vec,
13 | pub flags: Bytes,
14 | }
15 |
16 | impl Payload for MerkleBlock {
17 | fn version() -> u32 {
18 | 70014
19 | }
20 |
21 | fn command() -> &'static str {
22 | "merkleblock"
23 | }
24 |
25 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
26 | let merkle_block = MerkleBlock {
27 | block_header: try!(reader.read()),
28 | total_transactions: try!(reader.read()),
29 | hashes: try!(reader.read_list()),
30 | flags: try!(reader.read()),
31 | };
32 |
33 | Ok(merkle_block)
34 | }
35 |
36 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
37 | stream
38 | .append(&self.block_header)
39 | .append(&self.total_transactions)
40 | .append_list(&self.hashes)
41 | .append(&self.flags);
42 | Ok(())
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/message/src/types/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod addr;
2 | mod block;
3 | mod blocktxn;
4 | mod compactblock;
5 | mod feefilter;
6 | mod filteradd;
7 | mod filterclear;
8 | mod filterload;
9 | mod getaddr;
10 | mod getblocks;
11 | mod getblocktxn;
12 | mod getdata;
13 | mod getheaders;
14 | mod headers;
15 | mod inv;
16 | mod mempool;
17 | mod merkle_block;
18 | mod notfound;
19 | mod ping;
20 | mod pong;
21 | pub mod reject;
22 | mod sendcompact;
23 | mod sendheaders;
24 | mod tx;
25 | mod verack;
26 | pub mod version;
27 |
28 | pub use self::addr::Addr;
29 | pub use self::block::Block;
30 | pub use self::blocktxn::BlockTxn;
31 | pub use self::compactblock::CompactBlock;
32 | pub use self::feefilter::FeeFilter;
33 | pub use self::filterload::{FilterLoad, FILTERLOAD_MAX_FILTER_LEN, FILTERLOAD_MAX_HASH_FUNCS};
34 | pub use self::filterload::FilterFlags;
35 | pub use self::filterclear::FilterClear;
36 | pub use self::filteradd::{FilterAdd, FILTERADD_MAX_DATA_LEN};
37 | pub use self::getaddr::GetAddr;
38 | pub use self::getblocks::{GetBlocks, GETBLOCKS_MAX_RESPONSE_HASHES};
39 | pub use self::getblocktxn::GetBlockTxn;
40 | pub use self::getdata::{GetData, GETDATA_MAX_INVENTORY_LEN};
41 | pub use self::getheaders::{GetHeaders, GETHEADERS_MAX_RESPONSE_HEADERS};
42 | pub use self::headers::{Headers, HEADERS_MAX_HEADERS_LEN};
43 | pub use self::inv::{Inv, INV_MAX_INVENTORY_LEN};
44 | pub use self::mempool::MemPool;
45 | pub use self::merkle_block::MerkleBlock;
46 | pub use self::notfound::NotFound;
47 | pub use self::ping::Ping;
48 | pub use self::pong::Pong;
49 | pub use self::reject::Reject;
50 | pub use self::sendcompact::SendCompact;
51 | pub use self::sendheaders::SendHeaders;
52 | pub use self::tx::Tx;
53 | pub use self::verack::Verack;
54 | pub use self::version::Version;
55 |
--------------------------------------------------------------------------------
/message/src/types/notfound.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use common::InventoryVector;
4 | use {Payload, MessageResult};
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct NotFound {
8 | pub inventory: Vec,
9 | }
10 |
11 | impl NotFound {
12 | pub fn with_inventory(inventory: Vec) -> Self {
13 | NotFound {
14 | inventory: inventory,
15 | }
16 | }
17 | }
18 |
19 | impl Payload for NotFound {
20 | fn version() -> u32 {
21 | 0
22 | }
23 |
24 | fn command() -> &'static str {
25 | "notfound"
26 | }
27 |
28 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
29 | let inv = NotFound {
30 | inventory: try!(reader.read_list_max(50_000)),
31 | };
32 |
33 | Ok(inv)
34 | }
35 |
36 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
37 | stream.append_list(&self.inventory);
38 | Ok(())
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/message/src/types/ping.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {MessageResult, Payload};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct Ping {
7 | pub nonce: u64,
8 | }
9 |
10 | impl Ping {
11 | pub fn new(nonce: u64) -> Self {
12 | Ping {
13 | nonce: nonce,
14 | }
15 | }
16 | }
17 |
18 | impl Payload for Ping {
19 | fn version() -> u32 {
20 | 0
21 | }
22 |
23 | fn command() -> &'static str {
24 | "ping"
25 | }
26 |
27 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
28 | let ping = Ping {
29 | nonce: try!(reader.read()),
30 | };
31 |
32 | Ok(ping)
33 | }
34 |
35 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
36 | stream.append(&self.nonce);
37 | Ok(())
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/message/src/types/pong.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct Pong {
7 | pub nonce: u64,
8 | }
9 |
10 | impl Pong {
11 | pub fn new(nonce: u64) -> Self {
12 | Pong {
13 | nonce: nonce,
14 | }
15 | }
16 | }
17 |
18 | impl Payload for Pong {
19 | fn version() -> u32 {
20 | 0
21 | }
22 |
23 | fn command() -> &'static str {
24 | "pong"
25 | }
26 |
27 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
28 | let pong = Pong {
29 | nonce: try!(reader.read()),
30 | };
31 |
32 | Ok(pong)
33 | }
34 |
35 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
36 | stream.append(&self.nonce);
37 | Ok(())
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/message/src/types/reject.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq, Clone, Copy)]
6 | #[repr(u8)]
7 | pub enum RejectCode {
8 | Malformed = 0x01,
9 | Invalid = 0x10,
10 | Obsolate = 0x11,
11 | Duplicate = 0x12,
12 | Nonstandard = 0x40,
13 | Dust = 0x41,
14 | InsuficientFee = 0x42,
15 | Checkpoint = 0x43,
16 | }
17 |
18 | impl From for u8 {
19 | fn from(c: RejectCode) -> Self {
20 | c as u8
21 | }
22 | }
23 |
24 | impl RejectCode {
25 | pub fn from_u8(v: u8) -> Option {
26 | let some = match v {
27 | 0x01 => RejectCode::Malformed,
28 | 0x10 => RejectCode::Invalid,
29 | 0x11 => RejectCode::Obsolate,
30 | 0x12 => RejectCode::Duplicate,
31 | 0x40 => RejectCode::Nonstandard,
32 | 0x41 => RejectCode::Dust,
33 | 0x42 => RejectCode::InsuficientFee,
34 | 0x43 => RejectCode::Checkpoint,
35 | _ => return None,
36 | };
37 |
38 | Some(some)
39 | }
40 | }
41 |
42 | impl Serializable for RejectCode {
43 | fn serialize(&self, stream: &mut Stream) {
44 | stream.append(&u8::from(*self));
45 | }
46 | }
47 |
48 | impl Deserializable for RejectCode {
49 | fn deserialize(reader: &mut Reader) -> Result where T: io::Read {
50 | let v: u8 = try!(reader.read());
51 | RejectCode::from_u8(v).ok_or_else(|| io::ErrorKind::MalformedData)
52 | }
53 | }
54 |
55 | #[derive(Debug, PartialEq)]
56 | pub struct Reject {
57 | pub message: String,
58 | pub code: RejectCode,
59 | pub reason: String,
60 | // TODO: data
61 | }
62 |
63 | impl Payload for Reject {
64 | fn version() -> u32 {
65 | 0
66 | }
67 |
68 | fn command() -> &'static str {
69 | "reject"
70 | }
71 |
72 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
73 | let reject = Reject {
74 | message: try!(reader.read()),
75 | code: try!(reader.read()),
76 | reason: try!(reader.read()),
77 | };
78 |
79 | Ok(reject)
80 | }
81 |
82 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
83 | stream
84 | .append(&self.message)
85 | .append(&self.code)
86 | .append(&self.reason);
87 | Ok(())
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/message/src/types/sendcompact.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct SendCompact {
7 | pub first: bool,
8 | pub second: u64,
9 | }
10 |
11 | impl Payload for SendCompact {
12 | fn version() -> u32 {
13 | 70014
14 | }
15 |
16 | fn command() -> &'static str {
17 | "sendcmpct"
18 | }
19 |
20 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
21 | let send_compact = SendCompact {
22 | first: try!(reader.read()),
23 | second: try!(reader.read()),
24 | };
25 |
26 | Ok(send_compact)
27 | }
28 |
29 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
30 | stream
31 | .append(&self.first)
32 | .append(&self.second);
33 | Ok(())
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/message/src/types/sendheaders.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct SendHeaders;
7 |
8 | impl Payload for SendHeaders {
9 | fn version() -> u32 {
10 | 70012
11 | }
12 |
13 | fn command() -> &'static str {
14 | "sendheaders"
15 | }
16 |
17 | fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
18 | Ok(SendHeaders)
19 | }
20 |
21 | fn serialize_payload(&self, _stream: &mut Stream, _version: u32) -> MessageResult<()> {
22 | Ok(())
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/message/src/types/tx.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use chain::Transaction;
4 | use {Payload, MessageResult};
5 |
6 | #[derive(Debug, PartialEq)]
7 | pub struct Tx {
8 | pub transaction: Transaction,
9 | }
10 |
11 | impl Tx {
12 | pub fn with_transaction(transaction: Transaction) -> Self {
13 | Tx {
14 | transaction: transaction,
15 | }
16 | }
17 | }
18 |
19 | impl Payload for Tx {
20 | fn version() -> u32 {
21 | 0
22 | }
23 |
24 | fn command() -> &'static str {
25 | "tx"
26 | }
27 |
28 | fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
29 | let tx = Tx {
30 | transaction: try!(reader.read()),
31 | };
32 |
33 | Ok(tx)
34 | }
35 |
36 | fn serialize_payload(&self, stream: &mut Stream, _version: u32) -> MessageResult<()> {
37 | stream.append(&self.transaction);
38 | Ok(())
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/message/src/types/verack.rs:
--------------------------------------------------------------------------------
1 | use primitives::io;
2 | use ser::{Stream, Reader};
3 | use {Payload, MessageResult};
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub struct Verack;
7 |
8 | impl Payload for Verack {
9 | fn version() -> u32 {
10 | 0
11 | }
12 |
13 | fn command() -> &'static str {
14 | "verack"
15 | }
16 |
17 | fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult where T: io::Read {
18 | Ok(Verack)
19 | }
20 |
21 | fn serialize_payload(&self, _stream: &mut Stream, _version: u32) -> MessageResult<()> {
22 | Ok(())
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/miner/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "miner"
3 | version = "0.1.0"
4 | authors = ["Ethcore "]
5 |
6 | [dependencies]
7 | byteorder = "1.0"
8 | heapsize = "0.4"
9 | bitcrypto = { path = "../crypto" }
10 | chain = { path = "../chain" }
11 | storage = { path = "../storage" }
12 | db = { path = "../db" }
13 | network = { path = "../network" }
14 | primitives = { path = "../primitives" }
15 | serialization = { path = "../serialization" }
16 | verification = { path = "../verification" }
17 | keys = { path = "../keys" }
18 | script = { path = "../script" }
19 | rand = "0.4"
20 | log = "0.4"
21 |
22 | [dev-dependencies]
23 | test-data = { path = "../test-data" }
24 |
--------------------------------------------------------------------------------
/miner/src/fee.rs:
--------------------------------------------------------------------------------
1 | use chain::Transaction;
2 | use ser::Serializable;
3 | use storage::TransactionProvider;
4 |
5 | pub fn transaction_fee(store: &TransactionProvider, transaction: &Transaction) -> u64 {
6 | let inputs_sum = transaction.inputs.iter().map(|input| {
7 | let input_transaction = store.transaction(&input.previous_output.hash)
8 | .expect("transaction must be verified by caller");
9 | input_transaction.outputs[input.previous_output.index as usize].value
10 | }).sum::();
11 | let outputs_sum = transaction.outputs.iter().map(|output| output.value).sum();
12 | inputs_sum.saturating_sub(outputs_sum)
13 | }
14 |
15 | pub fn transaction_fee_rate(store: &TransactionProvider, transaction: &Transaction) -> u64 {
16 | transaction_fee(store, transaction) / transaction.serialized_size() as u64
17 | }
18 |
19 | #[cfg(test)]
20 | mod tests {
21 | extern crate test_data;
22 |
23 | use std::sync::Arc;
24 | use storage::{AsSubstore};
25 | use db::BlockChainDatabase;
26 | use super::*;
27 |
28 | #[test]
29 | fn test_transaction_fee() {
30 | let b0 = test_data::block_builder().header().nonce(1).build()
31 | .transaction()
32 | .output().value(1_000_000).build()
33 | .output().value(2_000_000).build()
34 | .build()
35 | .build();
36 | let tx0 = b0.transactions[0].clone();
37 | let tx0_hash = tx0.hash();
38 | let b1 = test_data::block_builder().header().parent(b0.hash().clone()).nonce(2).build()
39 | .transaction()
40 | .input().hash(tx0_hash.clone()).index(0).build()
41 | .input().hash(tx0_hash).index(1).build()
42 | .output().value(2_500_000).build()
43 | .build()
44 | .build();
45 | let tx2 = b1.transactions[0].clone();
46 |
47 | let db = Arc::new(BlockChainDatabase::init_test_chain(vec![b0.into(), b1.into()]));
48 |
49 | assert_eq!(transaction_fee(db.as_transaction_provider(), &tx0), 0);
50 | assert_eq!(transaction_fee(db.as_transaction_provider(), &tx2), 500_000);
51 |
52 | assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx0), 0);
53 | assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx2), 4_901);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/miner/src/lib.rs:
--------------------------------------------------------------------------------
1 | extern crate byteorder;
2 | extern crate heapsize;
3 |
4 | extern crate bitcrypto as crypto;
5 | extern crate chain;
6 | extern crate storage;
7 | extern crate db;
8 | extern crate keys;
9 | extern crate script;
10 | extern crate network;
11 | extern crate primitives;
12 | extern crate serialization as ser;
13 | extern crate verification;
14 | extern crate rand;
15 | #[macro_use]
16 | extern crate log;
17 |
18 | mod block_assembler;
19 | mod cpu_miner;
20 | mod fee;
21 | mod memory_pool;
22 |
23 | pub use block_assembler::{BlockAssembler, BlockTemplate};
24 | pub use cpu_miner::{find_solution, CoinbaseTransactionBuilder};
25 | pub use memory_pool::{MemoryPool, HashedOutPoint, Information as MemoryPoolInformation,
26 | OrderingStrategy as MemoryPoolOrderingStrategy, DoubleSpendCheckResult, NonFinalDoubleSpendSet};
27 | pub use fee::{transaction_fee, transaction_fee_rate};
28 |
--------------------------------------------------------------------------------
/network/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "network"
3 | version = "0.1.0"
4 | authors = ["debris "]
5 |
6 | [dependencies]
7 | lazy_static = "1.0"
8 | chain = { path = "../chain" }
9 | primitives = { path = "../primitives" }
10 |
--------------------------------------------------------------------------------
/network/src/deployments.rs:
--------------------------------------------------------------------------------
1 | const VERSIONBITS_TOP_MASK: u32 = 0xe0000000;
2 | const VERSIONBITS_TOP_BITS: u32 = 0x20000000;
3 |
4 | #[derive(Debug, Clone, Copy)]
5 | pub struct Deployment {
6 | /// Deployment's name
7 | pub name: &'static str,
8 | /// Bit
9 | pub bit: u8,
10 | /// Start time
11 | pub start_time: u32,
12 | /// Timeout
13 | pub timeout: u32,
14 | /// Activation block number (if already activated)
15 | pub activation: Option,
16 | }
17 |
18 | impl Deployment {
19 | pub fn matches(&self, version: u32) -> bool {
20 | (version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS && (version & (1 << self.bit)) != 0
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/network/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate lazy_static;
3 |
4 | extern crate chain;
5 | extern crate primitives;
6 |
7 | mod consensus;
8 | mod deployments;
9 | mod network;
10 |
11 | pub use primitives::{hash, compact};
12 |
13 | pub use consensus::{ConsensusParams, ConsensusFork, BitcoinCashConsensusParams};
14 | pub use deployments::Deployment;
15 | pub use network::{Magic, Network};
16 |
--------------------------------------------------------------------------------
/node/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "node"
3 | version = "0.1.0"
4 | authors = ["Chainpool "]
5 |
6 | [dependencies]
7 | primitives = { path = "../primitives" }
8 | storage = { path = "../storage" }
9 | sync = { path = "../sync" }
10 | chain = { path = "../chain" }
11 | miner = { path = "../miner" }
12 | keys = { path = "../keys" }
13 | script = { path = "../script" }
14 | log = "0.4"
15 |
--------------------------------------------------------------------------------
/p2p/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "p2p"
3 | version = "0.1.0"
4 | authors = ["debris "]
5 |
6 | [dependencies]
7 | tokio-core = "0.1.6"
8 | tokio-io = "0.1.1"
9 | parking_lot = "0.4"
10 | futures = "0.1"
11 | futures-cpupool = "0.1"
12 | time = "0.1"
13 | rand = "0.4"
14 | log = "0.4"
15 | abstract-ns = "0.3"
16 | ns-dns-tokio = "0.3"
17 | csv = "1"
18 |
19 | primitives = { path = "../primitives" }
20 | bitcrypto = { path = "../crypto" }
21 | message = { path = "../message" }
22 | serialization = { path = "../serialization" }
23 | network = { path = "../network" }
24 |
--------------------------------------------------------------------------------
/p2p/src/config.rs:
--------------------------------------------------------------------------------
1 | use std::{net, path};
2 | use message::common::Services;
3 | use net::Config as NetConfig;
4 | use util::InternetProtocol;
5 |
6 | #[derive(Debug, Clone)]
7 | pub struct Config {
8 | /// Number of threads used by p2p thread pool.
9 | pub threads: usize,
10 | /// Number of inbound connections.
11 | pub inbound_connections: u32,
12 | /// Number of outbound connections.
13 | pub outbound_connections: u32,
14 | /// Configuration for every connection.
15 | pub connection: NetConfig,
16 | /// Connect only to these nodes.
17 | pub peers: Vec,
18 | /// Connect to these nodes to retrieve peer addresses, and disconnect.
19 | pub seeds: Vec,
20 | /// p2p/nodes.csv file path.
21 | pub node_table_path: path::PathBuf,
22 | /// Peers with this services will get a boost in node_table.
23 | pub preferable_services: Services,
24 | /// Internet protocol.
25 | pub internet_protocol: InternetProtocol,
26 | }
27 |
--------------------------------------------------------------------------------
/p2p/src/event_loop.rs:
--------------------------------------------------------------------------------
1 | use futures::{empty, Empty};
2 | use tokio_core::reactor::Core;
3 |
4 | pub fn event_loop() -> Core {
5 | Core::new().unwrap()
6 | }
7 |
8 | pub fn forever() -> Empty<(), ()> {
9 | empty()
10 | }
11 |
--------------------------------------------------------------------------------
/p2p/src/io/deadline.rs:
--------------------------------------------------------------------------------
1 | use std::io;
2 | use std::time::Duration;
3 | use futures::{Future, Select, Poll, Async};
4 | use tokio_core::reactor::{Handle, Timeout};
5 |
6 | type DeadlineBox = Box::Item>, Error = ::Error> + Send>;
7 |
8 | pub fn deadline(duration: Duration, handle: &Handle, future: F) -> Result, io::Error>
9 | where F: Future- + Send + 'static, T: 'static {
10 | let timeout: DeadlineBox