diff --git a/Cargo.lock b/Cargo.lock index 1d44e501bbc512aa87f34fe71a9eb8b4430a323b..0b4444798383eaf1f6a355dd8a39fe9f28e7cdfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,12 +34,12 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bitflags" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -49,7 +49,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -67,7 +67,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -80,7 +80,7 @@ name = "crossbeam-utils" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -90,6 +90,7 @@ dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -101,8 +102,9 @@ dependencies = [ "duniter-crypto 0.1.2", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -112,8 +114,8 @@ dependencies = [ "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -126,7 +128,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -183,7 +185,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -194,7 +196,7 @@ name = "quote" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -245,19 +247,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -292,35 +294,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.43" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.43" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive_internals" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.13.1" +version = "0.13.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -397,9 +389,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" "checksum bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a6301db0b49fb63551bc15b5ae348147101cdf323242b93ec7546d5002ff1af" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" +"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" @@ -414,23 +406,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118" +"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" -"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb" +"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "0c855d888276f20d140223bd06515e5bf1647fd6d02593cb5792466d9a8ec2d0" -"checksum serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "aa113e5fc4b008a626ba2bbd41330b56c9987d667f79f7b243e5a2d03d91ed1c" -"checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794" -"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" +"checksum serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "428d3d818cb94ee037a17bf4f2200db2552e19b1825d33df2196624290716f92" +"checksum serde_derive 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "ee76093b16868c4c9c8e5329c3d30745833e35390624019738472bd13e996e79" +"checksum syn 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "61b8f1b737f929c6516ba46a3133fd6d5215ad8a62f66760f851f7048aebedfb" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index eb02b40032768fac856cc3ecc744fe9f4e223be6..3cb39c12d4eb7e7fcfc80f160c6285ea26559ce8 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" base58 = "0.1.0" base64 = "0.8.0" rust-crypto = "0.2.36" +serde = "1.0.24" [features] # Treat warnings as a build error. diff --git a/crypto/keys/ed25519.rs b/crypto/keys/ed25519.rs index 0446123d96a381193f82b0b897b7e15716ebb720..9fe98d04b8ecb5c2f280bc4510a01e45977ce8dc 100644 --- a/crypto/keys/ed25519.rs +++ b/crypto/keys/ed25519.rs @@ -19,6 +19,8 @@ //! //! [`KeyPairGenerator`]: struct.KeyPairGenerator.html +extern crate serde; + use std::collections::hash_map::DefaultHasher; use std::fmt::Debug; use std::fmt::Display; @@ -26,6 +28,7 @@ use std::fmt::Error; use std::fmt::Formatter; use std::hash::{Hash, Hasher}; +use self::serde::ser::{Serialize, Serializer}; use base58::{FromBase58, FromBase58Error, ToBase58}; use base64; use base64::DecodeError; @@ -123,6 +126,15 @@ impl Debug for PublicKey { } } +impl Serialize for PublicKey { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&format!("{}", self)) + } +} + impl super::PublicKey for PublicKey { type Signature = Signature; diff --git a/documents/Cargo.toml b/documents/Cargo.toml index de28ba5ffb6f71c5b8f200a0b9aed21e7b33a34a..cc0e5620497b6697d20bf9e23ebfbea93510f16a 100644 --- a/documents/Cargo.toml +++ b/documents/Cargo.toml @@ -12,13 +12,14 @@ license = "AGPL-3.0" path = "lib.rs" [dependencies] -rust-crypto = "0.2.36" -linked-hash-map = "0.5.0" base58 = "0.1.0" base64 = "0.8.0" +duniter-crypto = { path = "../crypto" } lazy_static = "1.0.0" +linked-hash-map = "0.5.0" regex = "0.2" -duniter-crypto = { path = "../crypto" } +rust-crypto = "0.2.36" +serde = "1.0.24" [features] # Treat warnings as a build error. diff --git a/documents/blockchain/mod.rs b/documents/blockchain/mod.rs index dee4005a95245c05687b01dc9189c7c10ab5a20d..ff070ebabeaab0aa48fb8feec7057bde65684026 100644 --- a/documents/blockchain/mod.rs +++ b/documents/blockchain/mod.rs @@ -19,6 +19,8 @@ use std::fmt::Debug; use duniter_crypto::keys::{PrivateKey, PublicKey}; +use super::Blockstamp; + pub mod v10; /// List of blockchain protocol versions. @@ -48,6 +50,9 @@ pub trait Document: Debug + Clone { /// Get document currency. fn currency(&self) -> &Self::CurrencyType; + /// Get document blockstamp + fn blockstamp(&self) -> Blockstamp; + /// Iterate over document issuers. fn issuers(&self) -> &Vec<Self::PublicKey>; @@ -160,6 +165,10 @@ mod tests { unimplemented!() } + fn blockstamp(&self) -> Blockstamp { + unimplemented!() + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } diff --git a/documents/blockchain/v10/documents/block.rs b/documents/blockchain/v10/documents/block.rs index 1473d4ae3b119038ec8013a2cb3bd39562b12533..0305af99761abe685cafcc3d3c8d1f2c839398b5 100644 --- a/documents/blockchain/v10/documents/block.rs +++ b/documents/blockchain/v10/documents/block.rs @@ -81,78 +81,75 @@ pub struct BlockParameters { #[derive(Debug, Clone)] pub struct BlockDocument { /// Nonce - nonce: u64, + pub nonce: u64, /// number - number: BlockId, + pub number: BlockId, /// Minimal proof of work difficulty - pow_min: usize, + pub pow_min: usize, /// Local time of the block issuer - time: u64, + pub time: u64, /// Average time - median_time: u64, + pub median_time: u64, /// Members count - members_count: usize, + pub members_count: usize, /// Monetary mass - monetary_mass: usize, + pub monetary_mass: usize, /// Unit base (power of ten) - unit_base: usize, + pub unit_base: usize, /// Number of compute members in the current frame - issuers_count: usize, + pub issuers_count: usize, /// Current frame size (in blocks) - issuers_frame: isize, + pub issuers_frame: isize, /// Current frame variation buffer - issuers_frame_var: isize, + pub issuers_frame_var: isize, /// Currency. - currency: String, + pub currency: String, /// Document issuer (there should be only one). - issuers: Vec<ed25519::PublicKey>, + pub issuers: Vec<ed25519::PublicKey>, /// Document signature (there should be only one). /// This vector is empty, when the block is generated but the proof of work has not yet started - signatures: Vec<ed25519::Signature>, + pub signatures: Vec<ed25519::Signature>, /// The hash is None, when the block is generated but the proof of work has not yet started - hash: Option<BlockHash>, + pub hash: Option<BlockHash>, /// Currency parameters (only in genesis block) - parameters: Option<BlockParameters>, + pub parameters: Option<BlockParameters>, /// Hash of the previous block - previous_hash: Option<Hash>, + pub previous_hash: Hash, /// Issuer of the previous block - previous_issuer: Option<ed25519::PublicKey>, + pub previous_issuer: Option<ed25519::PublicKey>, /// Hash of the deterministic content of the block - inner_hash: Option<Hash>, + pub inner_hash: Option<Hash>, /// Amount of new dividend created at this block, None if no dividend is created at this block - dividend: Option<usize>, + pub dividend: Option<usize>, /// Identities - identities: Vec<IdentityDocument>, + pub identities: Vec<IdentityDocument>, /// joiners - joiners: Vec<MembershipDocument>, + pub joiners: Vec<MembershipDocument>, /// Actives (=renewals) - actives: Vec<MembershipDocument>, + pub actives: Vec<MembershipDocument>, /// Leavers - leavers: Vec<MembershipDocument>, + pub leavers: Vec<MembershipDocument>, /// Revokeds - revoked: Vec<RevocationDocument>, + pub revoked: Vec<RevocationDocument>, /// Excludeds - excluded: Vec<ed25519::PublicKey>, + pub excluded: Vec<ed25519::PublicKey>, /// Certifications - certifications: Vec<CertificationDocument>, + pub certifications: Vec<CertificationDocument>, /// Transactions - transactions: Vec<TransactionDocument>, + pub transactions: Vec<TransactionDocument>, /// Part to sign - inner_hash_and_nonce_str: String, + pub inner_hash_and_nonce_str: String, } impl BlockDocument { - /// Return blockstamp - pub fn blockstamp(&self) -> Blockstamp { - Blockstamp { - id: self.number, - hash: self.hash.unwrap(), - } - } /// Compute inner hash pub fn compute_inner_hash(&mut self) { let mut sha256 = Sha256::new(); - sha256.input_str(&self.generate_compact_inner_text()); + let inner_text = self.generate_compact_inner_text(); + /*if self.number.0 == 46473 { + println!("#46473 raw_format=\"{}\"", inner_text); + }*/ + sha256.input_str(&inner_text); self.inner_hash = Some(Hash::from_hex(&sha256.result_str()).unwrap()); } /// Change nonce @@ -269,7 +266,7 @@ Transactions:{transactions} issuers_frame = self.issuers_frame, issuers_frame_var = self.issuers_frame_var, issuers_count = self.issuers_count, - previous_hash = self.previous_hash.unwrap(), + previous_hash = self.previous_hash, previous_issuer = self.previous_issuer.unwrap(), members_count = self.members_count, identities = identities_str, @@ -296,6 +293,13 @@ impl Document for BlockDocument { &self.currency } + fn blockstamp(&self) -> Blockstamp { + Blockstamp { + id: self.number, + hash: self.hash.unwrap(), + } + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } @@ -357,7 +361,7 @@ mod tests { signatures: vec![ed25519::Signature::from_base64("FsRxB+NOiL+8zTr2d3B2j2KBItDuCa0KjFMF6hXmdQzfqXAs9g3m7DlGgYLcqzqe6JXjx/Lyzqze1HBR4cS0Aw==").unwrap()], hash: None, parameters: None, - previous_hash: Some(Hash::from_hex("0000001F8AACF6764135F3E5D0D4E8358A3CBE537A4BF71152A00CC442EFD136").expect("fail to parse previous_hash")), + previous_hash: Hash::from_hex("0000001F8AACF6764135F3E5D0D4E8358A3CBE537A4BF71152A00CC442EFD136").expect("fail to parse previous_hash"), previous_issuer: Some(ed25519::PublicKey::from_base58("38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE").unwrap()), inner_hash: None, dividend: None, @@ -492,7 +496,7 @@ a9PHPuSfw7jW8FRQHXFsGi/bnLjbtDnTYvEVgUC9u0WlR7GVofa+Xb+l5iy6NwuEXiwvueAkf08wPVY8 signatures: vec![ed25519::Signature::from_base64("92id58VmkhgVNee4LDqBGSm8u/ooHzAD67JM6fhAE/CV8LCz7XrMF1DvRl+eRpmlaVkp6I+Iy8gmZ1WUM5C8BA==").unwrap()], hash: None, parameters: None, - previous_hash: Some(Hash::from_hex("000001144968D0C3516BE6225E4662F182E28956AF46DD7FB228E3D0F9413FEB").expect("fail to parse previous_hash")), + previous_hash: Hash::from_hex("000001144968D0C3516BE6225E4662F182E28956AF46DD7FB228E3D0F9413FEB").expect("fail to parse previous_hash"), previous_issuer: Some(ed25519::PublicKey::from_base58("D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH").unwrap()), inner_hash: None, dividend: None, diff --git a/documents/blockchain/v10/documents/certification.rs b/documents/blockchain/v10/documents/certification.rs index 10286adf7bb66a3d182d746eeba762a4f26ba1c3..b3e8857ccbe90c902b1e7d8bc307cb61e780aec3 100644 --- a/documents/blockchain/v10/documents/certification.rs +++ b/documents/blockchain/v10/documents/certification.rs @@ -15,11 +15,16 @@ //! Wrappers around Certification documents. +extern crate serde; + +use self::serde::ser::{Serialize, Serializer}; use duniter_crypto::keys::{ed25519, PublicKey, Signature}; use regex::Regex; -use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder, - V10Document, V10DocumentParsingError}; +use blockchain::v10::documents::{ + StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document, + V10DocumentParsingError, +}; use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument}; use Blockstamp; @@ -86,6 +91,10 @@ impl Document for CertificationDocument { &self.currency } + fn blockstamp(&self) -> Blockstamp { + self.blockstamp + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } @@ -115,6 +124,15 @@ impl TextDocument for CertificationDocument { } } +impl Serialize for CertificationDocument { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.generate_compact_text()) + } +} + impl IntoSpecializedDocument<BlockchainProtocol> for CertificationDocument { fn into_specialized(self) -> BlockchainProtocol { BlockchainProtocol::V10(Box::new(V10Document::Certification(Box::new(self)))) diff --git a/documents/blockchain/v10/documents/identity.rs b/documents/blockchain/v10/documents/identity.rs index 9eb9417791b6253f6e899807e8ad05e509b57919..6e986565b04dc04222ff93ed31b3509b7fb4b7be 100644 --- a/documents/blockchain/v10/documents/identity.rs +++ b/documents/blockchain/v10/documents/identity.rs @@ -15,11 +15,16 @@ //! Wrappers around Identity documents. +extern crate serde; + +use self::serde::ser::{Serialize, Serializer}; use duniter_crypto::keys::{ed25519, PublicKey}; use regex::Regex; -use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder, - V10Document, V10DocumentParsingError}; +use blockchain::v10::documents::{ + StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document, + V10DocumentParsingError, +}; use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument}; use Blockstamp; @@ -71,6 +76,10 @@ impl Document for IdentityDocument { &self.currency } + fn blockstamp(&self) -> Blockstamp { + self.blockstamp + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } @@ -100,6 +109,15 @@ impl TextDocument for IdentityDocument { } } +impl Serialize for IdentityDocument { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.generate_compact_text()) + } +} + impl IntoSpecializedDocument<BlockchainProtocol> for IdentityDocument { fn into_specialized(self) -> BlockchainProtocol { BlockchainProtocol::V10(Box::new(V10Document::Identity(self))) diff --git a/documents/blockchain/v10/documents/membership.rs b/documents/blockchain/v10/documents/membership.rs index f56937b2055212295ebae95bcc0d03d66dce4089..0cc53d51b5521471a4aa2719963e94a18704dbdf 100644 --- a/documents/blockchain/v10/documents/membership.rs +++ b/documents/blockchain/v10/documents/membership.rs @@ -15,11 +15,16 @@ //! Wrappers around Membership documents. +extern crate serde; + +use self::serde::ser::{Serialize, Serializer}; use duniter_crypto::keys::{ed25519, PublicKey}; use regex::Regex; -use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder, - V10Document, V10DocumentParsingError}; +use blockchain::v10::documents::{ + StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document, + V10DocumentParsingError, +}; use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument}; use Blockstamp; @@ -92,6 +97,10 @@ impl Document for MembershipDocument { &self.currency } + fn blockstamp(&self) -> Blockstamp { + self.blockstamp + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } @@ -122,6 +131,15 @@ impl TextDocument for MembershipDocument { } } +impl Serialize for MembershipDocument { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.generate_compact_text()) + } +} + impl IntoSpecializedDocument<BlockchainProtocol> for MembershipDocument { fn into_specialized(self) -> BlockchainProtocol { BlockchainProtocol::V10(Box::new(V10Document::Membership(self))) diff --git a/documents/blockchain/v10/documents/mod.rs b/documents/blockchain/v10/documents/mod.rs index bf8658d5d4aa5475934833d96355af5891b9e919..3557543aabb1be765eb61f36933a895a55c5eba1 100644 --- a/documents/blockchain/v10/documents/mod.rs +++ b/documents/blockchain/v10/documents/mod.rs @@ -32,13 +32,15 @@ pub mod revocation; pub mod transaction; pub use blockchain::v10::documents::block::BlockDocument; -pub use blockchain::v10::documents::certification::{CertificationDocument, - CertificationDocumentParser}; +pub use blockchain::v10::documents::certification::{ + CertificationDocument, CertificationDocumentParser, +}; pub use blockchain::v10::documents::identity::{IdentityDocument, IdentityDocumentBuilder}; pub use blockchain::v10::documents::membership::{MembershipDocument, MembershipDocumentParser}; pub use blockchain::v10::documents::revocation::{RevocationDocument, RevocationDocumentParser}; -pub use blockchain::v10::documents::transaction::{TransactionDocument, TransactionDocumentBuilder, - TransactionDocumentParser}; +pub use blockchain::v10::documents::transaction::{ + TransactionDocument, TransactionDocumentBuilder, TransactionDocumentParser, +}; // Use of lazy_static so the regex is only compiled at first use. lazy_static! { diff --git a/documents/blockchain/v10/documents/revocation.rs b/documents/blockchain/v10/documents/revocation.rs index 7568a35560420d73f0b8b6a9573274a3b2dd1ab9..b954ae13b2ead8be53710732e66daadf3ae3eb26 100644 --- a/documents/blockchain/v10/documents/revocation.rs +++ b/documents/blockchain/v10/documents/revocation.rs @@ -15,11 +15,16 @@ //! Wrappers around Revocation documents. +extern crate serde; + +use self::serde::ser::{Serialize, Serializer}; use duniter_crypto::keys::{ed25519, PublicKey, Signature}; use regex::Regex; -use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder, - V10Document, V10DocumentParsingError}; +use blockchain::v10::documents::{ + StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document, + V10DocumentParsingError, +}; use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument}; use Blockstamp; @@ -75,6 +80,10 @@ impl Document for RevocationDocument { &self.currency } + fn blockstamp(&self) -> Blockstamp { + unimplemented!() + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } @@ -102,6 +111,15 @@ impl TextDocument for RevocationDocument { } } +impl Serialize for RevocationDocument { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.generate_compact_text()) + } +} + impl IntoSpecializedDocument<BlockchainProtocol> for RevocationDocument { fn into_specialized(self) -> BlockchainProtocol { BlockchainProtocol::V10(Box::new(V10Document::Revocation(Box::new(self)))) diff --git a/documents/blockchain/v10/documents/transaction.rs b/documents/blockchain/v10/documents/transaction.rs index 5e0a117b638a68ff43772a87ebb38540d3995763..efcf04a7e1252862277bde9898b73b450bf415ee 100644 --- a/documents/blockchain/v10/documents/transaction.rs +++ b/documents/blockchain/v10/documents/transaction.rs @@ -15,14 +15,20 @@ //! Wrappers around Transaction documents. +extern crate serde; + use std::ops::Deref; use duniter_crypto::keys::{ed25519, PublicKey}; use regex::Regex; use regex::RegexBuilder; -use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder, - V10Document, V10DocumentParsingError}; +use self::serde::ser::{Serialize, Serializer}; + +use blockchain::v10::documents::{ + StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document, + V10DocumentParsingError, +}; use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument}; use Blockstamp; @@ -357,7 +363,7 @@ impl ToString for TransactionOutput { } impl TransactionOutput { - /// Parse Transaction Ouput from string. + /// Parse Transaction Output from string. pub fn parse_from_str(source: &str) -> Result<TransactionOutput, V10DocumentParsingError> { if let Some(caps) = OUTPUT_REGEX.captures(source) { let amount = caps["amount"].parse().expect("fail to parse output amount"); @@ -419,6 +425,10 @@ impl Document for TransactionDocument { &self.currency } + fn blockstamp(&self) -> Blockstamp { + self.blockstamp + } + fn issuers(&self) -> &Vec<ed25519::PublicKey> { &self.issuers } @@ -458,11 +468,17 @@ impl TextDocument for TransactionDocument { outputs_str.push_str("\n"); outputs_str.push_str(&output.to_string()); } + let mut comment_str = self.comment.clone(); + if !comment_str.is_empty() { + comment_str.push_str("\n"); + } let mut signatures_str = String::from(""); for sig in self.signatures.clone() { - signatures_str.push_str("\n"); signatures_str.push_str(&sig.to_string()); + signatures_str.push_str("\n"); } + // Remove end line step + signatures_str.pop(); format!( "TX:10:{issuers_count}:{inputs_count}:{unlocks_count}:{outputs_count}:{has_comment}:{locktime} {blockstamp}{issuers}{inputs}{unlocks}{outputs}\n{comment}{signatures}", @@ -477,12 +493,22 @@ impl TextDocument for TransactionDocument { inputs = inputs_str, unlocks = unlocks_str, outputs = outputs_str, - comment = self.comment, + comment = comment_str, signatures = signatures_str, ) } } +impl Serialize for TransactionDocument { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let compact_text = self.generate_compact_text(); + serializer.serialize_str(&compact_text.replace("\n", "$")) + } +} + impl IntoSpecializedDocument<BlockchainProtocol> for TransactionDocument { fn into_specialized(self) -> BlockchainProtocol { BlockchainProtocol::V10(Box::new(V10Document::Transaction(Box::new(self)))) diff --git a/documents/lib.rs b/documents/lib.rs index 7b360c1bc061797119d80bb00c1d51e1200ab302..f80ced520879f3dfb3e6e3a488513ae7fba74699 100644 --- a/documents/lib.rs +++ b/documents/lib.rs @@ -30,15 +30,18 @@ extern crate duniter_crypto; extern crate lazy_static; extern crate linked_hash_map; extern crate regex; +extern crate serde; +use std::cmp::Ordering; use std::fmt::{Debug, Display, Error, Formatter}; +use self::serde::ser::{Serialize, Serializer}; use duniter_crypto::keys::BaseConvertionError; pub mod blockchain; /// A block Id. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, Ord, PartialEq, PartialOrd, Eq, Hash)] pub struct BlockId(pub u32); impl Display for BlockId { @@ -50,7 +53,7 @@ impl Display for BlockId { /// A hash wrapper. /// /// A hash is often provided as string composed of 64 hexadecimal character (0 to 9 then A to F). -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd, Hash)] pub struct Hash(pub [u8; 32]); impl Display for Hash { @@ -119,8 +122,8 @@ impl Hash { } /// Wrapper of a block hash. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct BlockHash(Hash); +#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd, Hash)] +pub struct BlockHash(pub Hash); impl Display for BlockHash { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -186,6 +189,31 @@ impl Default for Blockstamp { } } +impl Serialize for Blockstamp { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&format!("{}-{}", self.id, self.hash)) + } +} + +impl PartialOrd for Blockstamp { + fn partial_cmp(&self, other: &Blockstamp) -> Option<Ordering> { + Some(self.cmp(other)) + } +} + +impl Ord for Blockstamp { + fn cmp(&self, other: &Blockstamp) -> Ordering { + if self.id == other.id { + self.hash.cmp(&other.hash) + } else { + self.id.cmp(&other.id) + } + } +} + impl Blockstamp { /// Create a `BlockUId` from a text. pub fn from_string(src: &str) -> Result<Blockstamp, BlockUIdParseError> {