diff --git a/Cargo.lock b/Cargo.lock index 5d99c9f4d13aa98ee2b4342138805819a2946b1a..5946f25b43c02c20da42ce4c81211a2f21eda342 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,7 +211,7 @@ dependencies = [ "duniter-conf 0.1.0-a0.1", "duniter-crypto 0.2.0-a0.1", "duniter-dal 0.1.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-message 0.1.0-a0.1", "duniter-module 0.1.0-a0.1", "duniter-network 0.1.0-a0.1", @@ -233,7 +233,7 @@ version = "0.1.0-a0.1" dependencies = [ "dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "duniter-crypto 0.2.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-module 0.1.0-a0.1", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", @@ -280,7 +280,7 @@ name = "duniter-dal" version = "0.1.0-a0.1" dependencies = [ "duniter-crypto 0.2.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-module 0.1.0-a0.1", "duniter-network 0.1.0-a0.1", "durs-wot 0.8.0-a0.9", @@ -294,7 +294,7 @@ dependencies = [ [[package]] name = "duniter-documents" -version = "0.8.0-a0.1" +version = "0.9.0-b1" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -313,7 +313,7 @@ version = "0.1.0-a0.1" dependencies = [ "duniter-crypto 0.2.0-a0.1", "duniter-dal 0.1.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-module 0.1.0-a0.1", "duniter-network 0.1.0-a0.1", "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", @@ -326,7 +326,7 @@ name = "duniter-module" version = "0.1.0-a0.1" dependencies = [ "duniter-crypto 0.2.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -338,7 +338,7 @@ name = "duniter-network" version = "0.1.0-a0.1" dependencies = [ "duniter-crypto 0.2.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-module 0.1.0-a0.1", "durs-network-documents 0.1.0-a0.1", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -354,7 +354,7 @@ dependencies = [ "duniter-conf 0.1.0-a0.1", "duniter-crypto 0.2.0-a0.1", "duniter-dal 0.1.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-message 0.1.0-a0.1", "duniter-module 0.1.0-a0.1", "duniter-network 0.1.0-a0.1", @@ -385,7 +385,7 @@ dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "duniter-crypto 0.2.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -429,7 +429,7 @@ dependencies = [ "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "duniter-crypto 0.2.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "durs-network-documents 0.1.0-a0.1", "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -447,7 +447,7 @@ dependencies = [ "duniter-conf 0.1.0-a0.1", "duniter-crypto 0.2.0-a0.1", "duniter-dal 0.1.0-a0.1", - "duniter-documents 0.8.0-a0.1", + "duniter-documents 0.9.0-b1", "duniter-message 0.1.0-a0.1", "duniter-module 0.1.0-a0.1", "duniter-network 0.1.0-a0.1", diff --git a/blockchain/lib.rs b/blockchain/lib.rs index dd1009ee5b8dc5e17448e797ed2bd97fb4557920..65280e547255c3228bb250c3c5a987b0d7852eb1 100644 --- a/blockchain/lib.rs +++ b/blockchain/lib.rs @@ -72,7 +72,7 @@ use duniter_dal::writers::requests::BlocksDBsWriteQuery; use duniter_dal::*; use duniter_documents::v10::{BlockDocument, V10Document}; use duniter_documents::*; -use duniter_documents::{BlockchainProtocol, Document}; +use duniter_documents::{DUBPDocument, Document}; use duniter_message::*; use duniter_module::*; use duniter_network::{ @@ -378,7 +378,7 @@ impl BlockchainModule { "RefusedBlock({})", network_block.uncompleted_block_doc().number.0 ); - self.send_event(&DALEvent::RefusedPendingDoc(BlockchainProtocol::V10( + self.send_event(&DALEvent::RefusedPendingDoc(DUBPDocument::V10( Box::new(V10Document::Block(Box::new( network_block.uncompleted_block_doc().clone(), ))), @@ -387,23 +387,23 @@ impl BlockchainModule { } } BlockchainDocument::Identity(ref doc) => blockchain_documents.push( - BlockchainProtocol::V10(Box::new(V10Document::Identity(doc.deref().clone()))), + DUBPDocument::V10(Box::new(V10Document::Identity(doc.deref().clone()))), ), BlockchainDocument::Membership(ref doc) => blockchain_documents.push( - BlockchainProtocol::V10(Box::new(V10Document::Membership(doc.deref().clone()))), + DUBPDocument::V10(Box::new(V10Document::Membership(doc.deref().clone()))), ), BlockchainDocument::Certification(ref doc) => { - blockchain_documents.push(BlockchainProtocol::V10(Box::new( + blockchain_documents.push(DUBPDocument::V10(Box::new( V10Document::Certification(Box::new(doc.deref().clone())), ))) } BlockchainDocument::Revocation(ref doc) => { - blockchain_documents.push(BlockchainProtocol::V10(Box::new( - V10Document::Revocation(Box::new(doc.deref().clone())), - ))) + blockchain_documents.push(DUBPDocument::V10(Box::new(V10Document::Revocation( + Box::new(doc.deref().clone()), + )))) } BlockchainDocument::Transaction(ref doc) => { - blockchain_documents.push(BlockchainProtocol::V10(Box::new( + blockchain_documents.push(DUBPDocument::V10(Box::new( V10Document::Transaction(Box::new(doc.deref().clone())), ))) } @@ -424,12 +424,12 @@ impl BlockchainModule { } current_blockstamp } - fn receive_documents(&self, documents: &[BlockchainProtocol]) { + fn receive_documents(&self, documents: &[DUBPDocument]) { debug!("BlockchainModule : receive_documents()"); for document in documents { trace!("BlockchainModule : Treat one document."); match *document { - BlockchainProtocol::V10(ref doc_v10) => match doc_v10.deref() { + DUBPDocument::V10(ref doc_v10) => match doc_v10.deref() { _ => {} }, _ => self.send_event(&DALEvent::RefusedPendingDoc(document.clone())), diff --git a/dal/dal_event.rs b/dal/dal_event.rs index 9a487dee7ff9337a133e88a79eba1e9d07376f9f..19f2659f0cb382b96a93bace3f44e8002f365e4d 100644 --- a/dal/dal_event.rs +++ b/dal/dal_event.rs @@ -24,7 +24,7 @@ pub enum DALEvent { /// Revert blocks in local blockchain RevertBlocks(Vec<Box<BlockDocument>>), /// Receive new valid pending document - NewValidPendingDoc(BlockchainProtocol), + NewValidPendingDoc(DUBPDocument), /// Receive new refused pending document - RefusedPendingDoc(BlockchainProtocol), + RefusedPendingDoc(DUBPDocument), } diff --git a/documents/Cargo.toml b/documents/Cargo.toml index 529506c982e69090fff61e6c860f05385ede59ff..665682454880e6a8e44731b2451d88b681e3729a 100644 --- a/documents/Cargo.toml +++ b/documents/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "duniter-documents" -version = "0.8.0-a0.1" +version = "0.9.0-b1" authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@ifee.fr>"] -description = "Handles Duniter documents" +description = "Handles DUBP documents (DUBP: DUniter Blockhain Protocol)" repository = "https://git.duniter.org/nodes/rust/duniter-rs" readme = "README.md" keywords = ["duniter", "blockchain", "cryptocurrency", "document"] diff --git a/documents/src/documents_grammar.pest b/documents/src/documents_grammar.pest index cc509f5f63eb02674d7660f57081eff17e5b8dd4..aba4de05ba21ae2a0b0a1a1352b74f79a101280f 100644 --- a/documents/src/documents_grammar.pest +++ b/documents/src/documents_grammar.pest @@ -1,11 +1,14 @@ -nl = _{ "\n" } -hexa = { ASCII_DIGIT | 'A'..'F' } + + +WHITESPACE = _{ "" } // Prohibition of white spaces +nl = _{ "\n" } // Only one way to break a line is accepted + +hexa_upper = { ASCII_DIGIT | 'A'..'F' } base58 = { !("O" | "I" | "l") ~ ASCII_ALPHANUMERIC } base64 = { ASCII_ALPHANUMERIC | "+" | "/" } - integer = @{ "0" | ('1'..'9' ~ ASCII_DIGIT*) } -hash = @{ hexa{64} } +hash = @{ hexa_upper{64} } currency = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "-" | "_")* } pubkey = @{ base58{43,44} } uid = @{ ASCII_ALPHA+ } @@ -16,26 +19,25 @@ ed25519_sig = @{ base64{86,88} ~ "="{0,2} } v10 = _{ "Version: 10" } idty_v10 = ${ - v10 ~ nl ~ + SOI ~ v10 ~ nl ~ "Type: Identity" ~ nl ~ "Currency: " ~ currency ~ nl ~ "Issuer: " ~ pubkey ~ nl ~ "UniqueID: " ~ uid ~ nl ~ "Timestamp: " ~ blockstamp ~ nl ~ ed25519_sig? ~ nl* + ~ EOI } idty = ${ - SOI ~ - (&(v10 ~ nl) ~ idty_v10) - ~ EOI + (&(SOI ~ v10 ~ nl) ~ idty_v10) } membership_in = @{ "IN" } membership_out = @{ "OUT" } membership_v10 = ${ - v10 ~ nl ~ + SOI ~ v10 ~ nl ~ "Type: Membership" ~ nl ~ "Currency: " ~ currency ~ nl ~ "Issuer: " ~ pubkey ~ nl ~ @@ -44,12 +46,11 @@ membership_v10 = ${ "UserID: " ~ uid ~ nl ~ "CertTS: " ~ blockstamp ~ nl ~ ed25519_sig? ~ nl* + ~ EOI } membership = ${ - SOI ~ - (&("Version: 10" ~ nl) ~ membership_v10) - ~ EOI + (&(SOI ~ v10 ~ nl) ~ membership_v10) } cert_v10 = ${ @@ -63,16 +64,15 @@ cert_v10 = ${ "IdtySignature: " ~ ed25519_sig ~ nl ~ "CertTimestamp: " ~ blockstamp ~ nl ~ ed25519_sig? ~ nl* + ~ EOI } cert = ${ - SOI ~ - (&("Version: 10" ~ nl) ~ cert_v10) - ~ EOI + (&(SOI ~ v10 ~ nl) ~ cert_v10) } revoc_v10 = ${ - v10 ~ nl ~ + SOI ~ v10 ~ nl ~ "Type: Revocation" ~ nl ~ "Currency: " ~ currency ~ nl ~ "Issuer: " ~ pubkey ~ nl ~ @@ -80,12 +80,11 @@ revoc_v10 = ${ "IdtyTimestamp: " ~ blockstamp ~ nl ~ "IdtySignature: " ~ ed25519_sig ~ nl ~ ed25519_sig? ~ nl* + ~ EOI } revoc = ${ - SOI ~ - (&("Version: 10" ~ nl) ~ revoc_v10) - ~ EOI + (&(SOI ~ v10 ~ nl) ~ revoc_v10) } tx_locktime = @{ integer } @@ -125,7 +124,7 @@ tx_comment_char = { tx_comment = @{ tx_comment_char{0,255} } tx_v10 = ${ - "Version: 10" ~ nl ~ + SOI ~ v10 ~ nl ~ "Type: Transaction" ~ nl ~ "Currency: " ~ currency ~ nl ~ "Blockstamp: " ~ blockstamp ~ nl ~ @@ -137,26 +136,23 @@ tx_v10 = ${ "Comment: " ~ tx_comment ~ nl ~ (ed25519_sig ~ nl)* ~ // intermediate signatures (zero if the transaction has only one signature) ed25519_sig? ~ nl* // last signature + ~ EOI } tx = ${ - SOI ~ - (&("Version: 10" ~ nl) ~ tx_v10) - ~ EOI + (&(SOI ~ v10 ~ nl) ~ tx_v10) } document_v10 = ${ - SOI ~ + &(SOI ~ v10 ~ nl) ~ (&"Type: Identity" ~ idty_v10) | (&"Type: Membership" ~ membership_v10) | (&"Type: Certification" ~ cert_v10) | (&"Type: Revocation" ~ revoc_v10) | (&"Type: Transaction" ~ tx_v10) - ~ EOI } document = ${ - SOI ~ - (&("Version: 10" ~ nl) ~ document_v10) - ~ EOI + &SOI ~ + (&(v10 ~ nl) ~ document_v10) } diff --git a/documents/src/lib.rs b/documents/src/lib.rs index bff1cc7067ebbace124e75bf65e91296508d562b..cfb6ef31013cec2c07067d6eca4b457a97f41e8c 100644 --- a/documents/src/lib.rs +++ b/documents/src/lib.rs @@ -46,6 +46,8 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use currencies_codes::*; use duniter_crypto::hashs::Hash; use duniter_crypto::keys::*; +use pest::iterators::Pair; +use pest::Parser; use std::cmp::Ordering; use std::fmt::{Debug, Display, Error, Formatter}; use std::io::Cursor; @@ -58,15 +60,61 @@ pub use blockstamp::{Blockstamp, PreviousBlockstamp}; /// Parser for Documents struct DocumentsParser; -/// List of blockchain protocol versions. +trait TextDocumentParser { + /// Type of document generated by the parser + type DocumentType; + + /// Parse text document from raw format + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError>; + /// Parse text document from pest pairs + fn from_pest_pair(pairs: Pair<Rule>) -> Self::DocumentType; +} + +/// List of possible errors while parsing. +#[derive(Debug, Clone)] +pub enum TextDocumentParseError { + /// The given source don't have a valid specific document format (document type). + InvalidInnerFormat(&'static str), + /// Type fields contains an unknown document type. + UnknownDocumentType(String), + /// Error with pest parser + PestError(String), + /// Invalid currency + InvalidCurrency(), + /// UnexpectedVersion + UnexpectedVersion(String), +} + +/// Document of DUBP (DUniter Blockhain Protocol) #[derive(Debug, Clone)] -pub enum BlockchainProtocol { +pub enum DUBPDocument { /// Version 10. V10(Box<v10::V10Document>), /// Version 11. (not done yet, but defined for tests) V11(), } +impl TextDocumentParser for DUBPDocument { + type DocumentType = DUBPDocument; + + fn parse(doc: &str) -> Result<DUBPDocument, TextDocumentParseError> { + match DocumentsParser::parse(Rule::document, doc) { + Ok(mut root_ast) => Ok(DUBPDocument::from_pest_pair(root_ast.next().unwrap())), // get and unwrap the `document` rule; never fails + Err(pest_error) => Err(TextDocumentParseError::PestError(format!("{}", pest_error))), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> DUBPDocument { + let doc_vx_pair = pair.into_inner().next().unwrap(); // get and unwrap the `document_vX` rule; never fails + + match doc_vx_pair.as_rule() { + Rule::document_v10 => { + DUBPDocument::V10(Box::new(v10::V10Document::from_pest_pair(doc_vx_pair))) + } + _ => panic!("unexpected rule: {:?}", doc_vx_pair.as_rule()), // Grammar ensures that we never reach this line + } + } +} + /// Currency name #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, Hash)] pub struct CurrencyName(pub String); diff --git a/documents/src/v10/block.rs b/documents/src/v10/block.rs index b03e00f2d642692d654842d49335439292f0ac28..3ef2ad7e75ed420907bca5dad20414ed6877abf7 100644 --- a/documents/src/v10/block.rs +++ b/documents/src/v10/block.rs @@ -501,9 +501,9 @@ impl TextDocument for BlockDocument { } } -impl IntoSpecializedDocument<BlockchainProtocol> for BlockDocument { - fn into_specialized(self) -> BlockchainProtocol { - BlockchainProtocol::V10(Box::new(V10Document::Block(Box::new(self)))) +impl IntoSpecializedDocument<DUBPDocument> for BlockDocument { + fn into_specialized(self) -> DUBPDocument { + DUBPDocument::V10(Box::new(V10Document::Block(Box::new(self)))) } } @@ -512,7 +512,6 @@ mod tests { use super::certification::CertificationDocumentParser; use super::transaction::TransactionDocumentParser; use super::*; - use std::ops::Deref; use {Document, VerificationResult}; #[test] @@ -584,11 +583,7 @@ IdtyUniqueID: PascaleM IdtyTimestamp: 97401-0000003821911909F98519CC773D2D3E5CFE3D5DBB39F4F4FF33B96B4D41800E IdtySignature: QncUVXxZ2NfARjdJOn6luILvDuG1NuK9qSoaU4CST2Ij8z7oeVtEgryHl+EXOjSe6XniALsCT0gU8wtadcA/Cw== CertTimestamp: 106669-000003682E6FE38C44433DCE92E8B2A26C69B6D7867A2BAED231E788DDEF4251 -UmseG2XKNwKcY8RFi6gUCT91udGnnNmSh7se10J1jeRVlwf+O2Tyb2Cccot9Dt7BO4+Kx2P6vFJB3oVGGHMxBA==", "g1").expect("Fail to parse cert1"); - let cert1 = match cert1 { - V10Document::Certification(doc) => (*doc.deref()).clone(), - _ => panic!("Wrong document type"), - }; +UmseG2XKNwKcY8RFi6gUCT91udGnnNmSh7se10J1jeRVlwf+O2Tyb2Cccot9Dt7BO4+Kx2P6vFJB3oVGGHMxBA==").expect("Fail to parse cert1"); let tx1 = TransactionDocumentParser::parse("Version: 10 Type: Transaction @@ -604,11 +599,7 @@ Unlocks: Outputs: 1002:0:SIG(CitdnuQgZ45tNFCagay7Wh12gwwHM8VLej1sWmfHWnQX) Comment: DU symbolique pour demander le codage de nouvelles fonctionnalites cf. https://forum.monnaie-libre.fr/t/creer-de-nouvelles-fonctionnalites-dans-cesium-les-autres-applications/2025 Merci -T0LlCcbIn7xDFws48H8LboN6NxxwNXXTovG4PROLf7tkUAueHFWjfwZFKQXeZEHxfaL1eYs3QspGtLWUHPRVCQ==", "g1").expect("Fail to parse tx1"); - let tx1 = match tx1 { - V10Document::Transaction(doc) => (*doc.deref()).clone(), - _ => panic!("Wrong document type"), - }; +T0LlCcbIn7xDFws48H8LboN6NxxwNXXTovG4PROLf7tkUAueHFWjfwZFKQXeZEHxfaL1eYs3QspGtLWUHPRVCQ==").expect("Fail to parse tx1"); let tx2 = TransactionDocumentParser::parse("Version: 10 Type: Transaction @@ -624,11 +615,7 @@ Unlocks: Outputs: 1002:0:SIG(78ZwwgpgdH5uLZLbThUQH7LKwPgjMunYfLiCfUCySkM8) Comment: DU symbolique pour demander le codage de nouvelles fonctionnalites cf. https://forum.monnaie-libre.fr/t/creer-de-nouvelles-fonctionnalites-dans-cesium-les-autres-applications/2025 Merci -a9PHPuSfw7jW8FRQHXFsGi/bnLjbtDnTYvEVgUC9u0WlR7GVofa+Xb+l5iy6NwuEXiwvueAkf08wPVY8xrNcCg==", "g1").expect("Fail to parse tx2"); - let tx2 = match tx2 { - V10Document::Transaction(doc) => (*doc.deref()).clone(), - _ => panic!("Wrong document type"), - }; +a9PHPuSfw7jW8FRQHXFsGi/bnLjbtDnTYvEVgUC9u0WlR7GVofa+Xb+l5iy6NwuEXiwvueAkf08wPVY8xrNcCg==").expect("Fail to parse tx2"); let mut block = BlockDocument { nonce: 0, diff --git a/documents/src/v10/certification.rs b/documents/src/v10/certification.rs index 00ec4df88f087ec61f53eeda31862ac2d570fd84..bcb9d80164afb08ae995f6790f1f8735c2f20ac5 100644 --- a/documents/src/v10/certification.rs +++ b/documents/src/v10/certification.rs @@ -138,9 +138,9 @@ impl TextDocument for CertificationDocument { } } -impl IntoSpecializedDocument<BlockchainProtocol> for CertificationDocument { - fn into_specialized(self) -> BlockchainProtocol { - BlockchainProtocol::V10(Box::new(V10Document::Certification(Box::new(self)))) +impl IntoSpecializedDocument<DUBPDocument> for CertificationDocument { + fn into_specialized(self) -> DUBPDocument { + DUBPDocument::V10(Box::new(V10Document::Certification(Box::new(self)))) } } @@ -222,73 +222,70 @@ CertTimestamp: {blockstamp} pub struct CertificationDocumentParser; impl TextDocumentParser for CertificationDocumentParser { - fn parse(doc: &str, currency: &str) -> Result<V10Document, V10DocumentParsingError> { + type DocumentType = CertificationDocument; + + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError> { match DocumentsParser::parse(Rule::cert, doc) { - Ok(mut doc_ast) => { - let cert_ast = doc_ast.next().unwrap(); // get and unwrap the `cert` rule; never fails - let cert_vx_ast = cert_ast.into_inner().next().unwrap(); // get and unwrap the `cert_vX` rule; never fails - - match cert_vx_ast.as_rule() { - Rule::cert_v10 => { - let mut pubkeys = Vec::with_capacity(2); - let mut uid = ""; - let mut sigs = Vec::with_capacity(2); - let mut blockstamps = Vec::with_capacity(2); - for field in cert_vx_ast.into_inner() { - match field.as_rule() { - Rule::currency => { - if currency != field.as_str() { - return Err(V10DocumentParsingError::InvalidCurrency()); - } - } - Rule::pubkey => pubkeys.push(PubKey::Ed25519( - ed25519::PublicKey::from_base58(field.as_str()).unwrap(), // Grammar ensures that we have a base58 string. - )), - Rule::uid => { - uid = field.as_str(); - } - Rule::blockstamp => { - if blockstamps.len() > 1 { - return Err(V10DocumentParsingError::InvalidInnerFormat( - "Cert document must contain exactly two blockstamps !", - )); - } - let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } - - let block_id: &str = inner_rules.next().unwrap().as_str(); - let block_hash: &str = inner_rules.next().unwrap().as_str(); - blockstamps.push(Blockstamp { - id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. - hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. - }); - } - Rule::ed25519_sig => { - sigs.push(Sig::Ed25519( - ed25519::Signature::from_base64(field.as_str()).unwrap(), // Grammar ensures that we have a base64 string. - )); - } - Rule::EOI => (), - _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line - } - } - Ok(V10Document::Certification(Box::new( - CertificationDocument { - text: doc.to_owned(), - issuers: vec![pubkeys[0]], - currency: currency.to_owned(), - target: pubkeys[1], - identity_username: uid.to_owned(), - identity_blockstamp: blockstamps[0], - identity_sig: sigs[0], - blockstamp: blockstamps[1], - signatures: vec![sigs[1]], - }, - ))) - } - _ => Err(V10DocumentParsingError::UnexpectedVersion()), + Ok(mut cert_pairs) => { + let cert_pair = cert_pairs.next().unwrap(); // get and unwrap the `cert` rule; never fails + let cert_vx_pair = cert_pair.into_inner().next().unwrap(); // get and unwrap the `cert_vX` rule; never fails + + match cert_vx_pair.as_rule() { + Rule::cert_v10 => Ok(CertificationDocumentParser::from_pest_pair(cert_vx_pair)), + _ => Err(TextDocumentParseError::UnexpectedVersion(format!( + "{:#?}", + cert_vx_pair.as_rule() + ))), } } - Err(pest_error) => panic!("{}", pest_error), //Err(V10DocumentParsingError::PestError()), + Err(pest_error) => panic!("{}", pest_error), //Err(TextDocumentParseError::PestError()), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> Self::DocumentType { + let doc = pair.as_str(); + let mut currency = ""; + let mut pubkeys = Vec::with_capacity(2); + let mut uid = ""; + let mut sigs = Vec::with_capacity(2); + let mut blockstamps = Vec::with_capacity(2); + for field in pair.into_inner() { + match field.as_rule() { + Rule::currency => currency = field.as_str(), + Rule::pubkey => pubkeys.push(PubKey::Ed25519( + ed25519::PublicKey::from_base58(field.as_str()).unwrap(), // Grammar ensures that we have a base58 string. + )), + Rule::uid => { + uid = field.as_str(); + } + Rule::blockstamp => { + let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } + + let block_id: &str = inner_rules.next().unwrap().as_str(); + let block_hash: &str = inner_rules.next().unwrap().as_str(); + blockstamps.push(Blockstamp { + id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. + hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. + }); + } + Rule::ed25519_sig => { + sigs.push(Sig::Ed25519( + ed25519::Signature::from_base64(field.as_str()).unwrap(), // Grammar ensures that we have a base64 string. + )); + } + Rule::EOI => (), + _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line + } + } + CertificationDocument { + text: doc.to_owned(), + issuers: vec![pubkeys[0]], + currency: currency.to_owned(), + target: pubkeys[1], + identity_username: uid.to_owned(), + identity_blockstamp: blockstamps[0], + identity_sig: sigs[0], + blockstamp: blockstamps[1], + signatures: vec![sigs[1]], } } } @@ -367,20 +364,14 @@ IdtySignature: SmSweUD4lEMwiZfY8ux9maBjrQQDkC85oMNsin6oSQCPdXG8sFCZ4FisUaWqKsfOl CertTimestamp: 167884-0001DFCA28002A8C96575E53B8CEF8317453A7B0BA255542CCF0EC8AB5E99038 wqZxPEGxLrHGv8VdEIfUGvUcf+tDdNTMXjLzVRCQ4UhlhDRahOMjfcbP7byNYr5OfIl83S1MBxF7VJgu8YasCA=="; - let currency = "g1-test"; - - let doc = CertificationDocumentParser::parse(doc, currency).unwrap(); - if let V10Document::Certification(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()); + let doc = CertificationDocumentParser::parse(doc).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()); /*assert_eq!( doc.generate_compact_text(), "2sZF6j2PkxBDNAqUde7Dgo5x3crkerZpQ4rBqqJGn8QT:\ 7jzkd8GiFnpys4X7mP78w2Y3y3kwdK6fVSLEaojd3aH9:99956:\ Hkps1QU4HxIcNXKT8YmprYTVByBhPP1U2tIM7Z8wENzLKIWAvQClkAvBE7pW9dnVa18sJIJhVZUcRrPAZfmjBA==" );*/ - } else { - panic!("Wrong document type"); - } } } diff --git a/documents/src/v10/identity.rs b/documents/src/v10/identity.rs index fb228f5f65974f34712cab73a9482b6b50313495..83a840bffb354e0edbcd3beeabed5777aca45056 100644 --- a/documents/src/v10/identity.rs +++ b/documents/src/v10/identity.rs @@ -131,9 +131,9 @@ impl TextDocument for IdentityDocument { } } -impl IntoSpecializedDocument<BlockchainProtocol> for IdentityDocument { - fn into_specialized(self) -> BlockchainProtocol { - BlockchainProtocol::V10(Box::new(V10Document::Identity(self))) +impl IntoSpecializedDocument<DUBPDocument> for IdentityDocument { + fn into_specialized(self) -> DUBPDocument { + DUBPDocument::V10(Box::new(V10Document::Identity(self))) } } @@ -200,59 +200,63 @@ Timestamp: {blockstamp} pub struct IdentityDocumentParser; impl TextDocumentParser for IdentityDocumentParser { - fn parse(doc: &str, currency: &str) -> Result<V10Document, V10DocumentParsingError> { + type DocumentType = IdentityDocument; + + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError> { match DocumentsParser::parse(Rule::idty, doc) { - Ok(mut doc_ast) => { - let idty_ast = doc_ast.next().unwrap(); // get and unwrap the `idty` rule; never fails - let idty_vx_ast = idty_ast.into_inner().next().unwrap(); // get and unwrap the `idty_vX` rule; never fails - - match idty_vx_ast.as_rule() { - Rule::idty_v10 => { - let mut pubkey_str = ""; - let mut uid = ""; - let mut blockstamp = Blockstamp::default(); - let mut sig_str = ""; - for field in idty_vx_ast.into_inner() { - match field.as_rule() { - Rule::currency => { - if currency != field.as_str() { - return Err(V10DocumentParsingError::InvalidCurrency()); - } - } - Rule::pubkey => pubkey_str = field.as_str(), - Rule::uid => uid = field.as_str(), - Rule::blockstamp => { - let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } - - let block_id: &str = inner_rules.next().unwrap().as_str(); - let block_hash: &str = inner_rules.next().unwrap().as_str(); - blockstamp = Blockstamp { - id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. - hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. - }; - } - Rule::ed25519_sig => sig_str = field.as_str(), - Rule::EOI => (), - _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line - } - } - Ok(V10Document::Identity(IdentityDocument { - text: Some(doc.to_owned()), - currency: currency.to_owned(), - username: uid.to_owned(), - blockstamp, - issuers: vec![PubKey::Ed25519( - ed25519::PublicKey::from_base58(pubkey_str).unwrap(), - )], // Grammar ensures that we have a base58 string. - signatures: vec![Sig::Ed25519( - ed25519::Signature::from_base64(sig_str).unwrap(), - )], // Grammar ensures that we have a base64 string. - })) - } - _ => Err(V10DocumentParsingError::UnexpectedVersion()), + Ok(mut doc_pairs) => { + let mut idty_pair = doc_pairs.next().unwrap(); // get and unwrap the `idty` rule; never fails + let mut idty_vx_pair = idty_pair.into_inner().next().unwrap(); // get and unwrap the `idty_vx` rule; never fails + + match idty_vx_pair.as_rule() { + Rule::idty_v10 => Ok(IdentityDocumentParser::from_pest_pair(idty_vx_pair)), + _ => Err(TextDocumentParseError::UnexpectedVersion(format!( + "{:#?}", + idty_vx_pair.as_rule() + ))), + } + } + Err(pest_error) => Err(TextDocumentParseError::PestError(format!("{}", pest_error))), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> Self::DocumentType { + let doc = pair.as_str(); + let mut currency = ""; + let mut pubkey_str = ""; + let mut uid = ""; + let mut blockstamp = Blockstamp::default(); + let mut sig_str = ""; + for field in pair.into_inner() { + match field.as_rule() { + Rule::currency => currency = field.as_str(), + Rule::pubkey => pubkey_str = field.as_str(), + Rule::uid => uid = field.as_str(), + Rule::blockstamp => { + let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } + + let block_id: &str = inner_rules.next().unwrap().as_str(); + let block_hash: &str = inner_rules.next().unwrap().as_str(); + blockstamp = Blockstamp { + id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. + hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. + }; } + Rule::ed25519_sig => sig_str = field.as_str(), + Rule::EOI => (), + _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line } - Err(pest_error) => panic!("{}", pest_error), //Err(V10DocumentParsingError::PestError()), + } + IdentityDocument { + text: Some(doc.to_owned()), + currency: currency.to_owned(), + username: uid.to_owned(), + blockstamp, + issuers: vec![PubKey::Ed25519( + ed25519::PublicKey::from_base58(pubkey_str).unwrap(), + )], // Grammar ensures that we have a base58 string. + signatures: vec![Sig::Ed25519( + ed25519::Signature::from_base64(sig_str).unwrap(), + )], // Grammar ensures that we have a base64 string. } } } @@ -318,14 +322,8 @@ UniqueID: tic Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg=="; - let currency = "duniter_unit_test_currency"; - - let doc = IdentityDocumentParser::parse(doc, currency).expect("Fail to parse idty doc !"); - if let V10Document::Identity(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = IdentityDocumentParser::parse(doc).expect("Fail to parse idty doc !"); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } } diff --git a/documents/src/v10/membership.rs b/documents/src/v10/membership.rs index 55eb6e4606ff7a37fa41fcad35ca087a3e45e1ab..ac1a9dcd0b8e8b15b0a46adb2bbfcc18d847523c 100644 --- a/documents/src/v10/membership.rs +++ b/documents/src/v10/membership.rs @@ -167,9 +167,9 @@ impl TextDocument for MembershipDocument { } } -impl IntoSpecializedDocument<BlockchainProtocol> for MembershipDocument { - fn into_specialized(self) -> BlockchainProtocol { - BlockchainProtocol::V10(Box::new(V10Document::Membership(self))) +impl IntoSpecializedDocument<DUBPDocument> for MembershipDocument { + fn into_specialized(self) -> DUBPDocument { + DUBPDocument::V10(Box::new(V10Document::Membership(self))) } } @@ -249,67 +249,70 @@ CertTS: {ity_blockstamp} pub struct MembershipDocumentParser; impl TextDocumentParser for MembershipDocumentParser { - fn parse(doc: &str, currency: &str) -> Result<V10Document, V10DocumentParsingError> { + type DocumentType = MembershipDocument; + + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError> { match DocumentsParser::parse(Rule::membership, doc) { - Ok(mut doc_ast) => { - let membership_ast = doc_ast.next().unwrap(); // get and unwrap the `membership` rule; never fails - let membership_vx_ast = membership_ast.into_inner().next().unwrap(); // get and unwrap the `membership_vX` rule; never fails + Ok(mut ms_pairs) => { + let ms_pair = ms_pairs.next().unwrap(); // get and unwrap the `membership` rule; never fails + let ms_vx_pair = ms_pair.into_inner().next().unwrap(); // get and unwrap the `membership_vX` rule; never fails - match membership_vx_ast.as_rule() { + match ms_vx_pair.as_rule() { Rule::membership_v10 => { - let mut pubkey_str = ""; - let mut uid = ""; - let mut blockstamps = Vec::with_capacity(2); - let mut membership = MembershipType::In(); - let mut sig_str = ""; - for field in membership_vx_ast.into_inner() { - match field.as_rule() { - Rule::currency => { - if currency != field.as_str() { - return Err(V10DocumentParsingError::InvalidCurrency()); - } - } - Rule::pubkey => pubkey_str = field.as_str(), - Rule::uid => uid = field.as_str(), - Rule::membership_in => membership = MembershipType::In(), - Rule::membership_out => membership = MembershipType::Out(), - Rule::blockstamp => { - if blockstamps.len() > 1 { - return Err(V10DocumentParsingError::InvalidInnerFormat("Membership document must have exactly two blockstamps !")); - } - let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } - - let block_id: &str = inner_rules.next().unwrap().as_str(); - let block_hash: &str = inner_rules.next().unwrap().as_str(); - blockstamps.push(Blockstamp { - id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. - hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. - }); - } - Rule::ed25519_sig => sig_str = field.as_str(), - Rule::EOI => (), - _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line - } - } - Ok(V10Document::Membership(MembershipDocument { - text: Some(doc.to_owned()), - issuers: vec![PubKey::Ed25519( - ed25519::PublicKey::from_base58(pubkey_str).unwrap(), - )], // Grammar ensures that we have a base58 string. - currency: currency.to_owned(), - blockstamp: blockstamps[0], - membership, - identity_username: uid.to_owned(), - identity_blockstamp: blockstamps[1], - signatures: vec![Sig::Ed25519( - ed25519::Signature::from_base64(sig_str).unwrap(), - )], // Grammar ensures that we have a base64 string. - })) + Ok(MembershipDocumentParser::from_pest_pair(ms_vx_pair)) } - _ => Err(V10DocumentParsingError::UnexpectedVersion()), + _ => Err(TextDocumentParseError::UnexpectedVersion(format!( + "{:#?}", + ms_vx_pair.as_rule() + ))), } } - Err(pest_error) => panic!("{}", pest_error), //Err(V10DocumentParsingError::PestError()), + Err(pest_error) => Err(TextDocumentParseError::PestError(format!("{}", pest_error))), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> Self::DocumentType { + let doc = pair.as_str(); + let mut currency = ""; + let mut pubkey_str = ""; + let mut uid = ""; + let mut blockstamps = Vec::with_capacity(2); + let mut membership = MembershipType::In(); + let mut sig_str = ""; + for field in pair.into_inner() { + match field.as_rule() { + Rule::currency => currency = field.as_str(), + Rule::uid => uid = field.as_str(), + Rule::pubkey => pubkey_str = field.as_str(), + Rule::membership_in => membership = MembershipType::In(), + Rule::membership_out => membership = MembershipType::Out(), + Rule::blockstamp => { + let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } + + let block_id: &str = inner_rules.next().unwrap().as_str(); + let block_hash: &str = inner_rules.next().unwrap().as_str(); + blockstamps.push(Blockstamp { + id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. + hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. + }); + } + Rule::ed25519_sig => sig_str = field.as_str(), + Rule::EOI => (), + _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line + } + } + MembershipDocument { + text: Some(doc.to_owned()), + issuers: vec![PubKey::Ed25519( + ed25519::PublicKey::from_base58(pubkey_str).unwrap(), + )], // Grammar ensures that we have a base58 string. + currency: currency.to_owned(), + blockstamp: blockstamps[0], + membership, + identity_username: uid.to_owned(), + identity_blockstamp: blockstamps[1], + signatures: vec![Sig::Ed25519( + ed25519::Signature::from_base64(sig_str).unwrap(), + )], // Grammar ensures that we have a base64 string. } } } @@ -379,13 +382,10 @@ UserID: tic CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw=="; - let currency = "duniter_unit_test_currency"; - - let doc = MembershipDocumentParser::parse(doc, currency).unwrap(); - if let V10Document::Membership(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()); - assert_eq!( + let doc = MembershipDocumentParser::parse(doc).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()); + assert_eq!( doc.generate_compact_text(), "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:\ s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==:\ @@ -393,8 +393,5 @@ s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrD 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:\ tic" ); - } else { - panic!("Wrong document type"); - } } } diff --git a/documents/src/v10/mod.rs b/documents/src/v10/mod.rs index 0cefad227a7d6a59f717ae1cecbac6b9721997dc..cc2240d15798d1847dc3bc58c27ac05044fef305 100644 --- a/documents/src/v10/mod.rs +++ b/documents/src/v10/mod.rs @@ -24,6 +24,7 @@ pub mod transaction; use crypto::digest::Digest; use duniter_crypto::keys::PrivateKey; +use pest::Parser; pub use v10::block::BlockDocument; use v10::certification::*; @@ -53,8 +54,6 @@ impl<D: TextDocument> TextDocumentFormat<D> { } /// List of wrapped document types. -/// -/// > TODO Add wrapped types in enum variants. #[derive(Debug, Clone)] pub enum V10Document { /// Block document. @@ -76,6 +75,41 @@ pub enum V10Document { Revocation(Box<RevocationDocument>), } +impl TextDocumentParser for V10Document { + type DocumentType = V10Document; + + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError> { + match DocumentsParser::parse(Rule::document_v10, doc) { + Ok(mut document_v10_pairs) => Ok(V10Document::from_pest_pair( + document_v10_pairs.next().unwrap(), + )), // get and unwrap the `document_v10` rule; never fails + Err(pest_error) => Err(TextDocumentParseError::PestError(format!("{}", pest_error))), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> Self::DocumentType { + let doc_type_v10_pair = pair.into_inner().next().unwrap(); // get and unwrap the `{DOC_TYPE}_v10` rule; never fails + + match doc_type_v10_pair.as_rule() { + Rule::idty_v10 => V10Document::Identity( + identity::IdentityDocumentParser::from_pest_pair(doc_type_v10_pair), + ), + Rule::membership_v10 => V10Document::Membership( + membership::MembershipDocumentParser::from_pest_pair(doc_type_v10_pair), + ), + Rule::cert_v10 => V10Document::Certification(Box::new( + certification::CertificationDocumentParser::from_pest_pair(doc_type_v10_pair), + )), + Rule::revoc_v10 => V10Document::Revocation(Box::new( + revocation::RevocationDocumentParser::from_pest_pair(doc_type_v10_pair), + )), + Rule::tx_v10 => V10Document::Transaction(Box::new( + transaction::TransactionDocumentParser::from_pest_pair(doc_type_v10_pair), + )), + _ => panic!("unexpected rule: {:?}", doc_type_v10_pair.as_rule()), // Grammar ensures that we never reach this line + } + } +} + /// Trait for a compact V10 document. pub trait CompactTextDocument: Sized + Clone { /// Generate document compact text. @@ -176,23 +210,6 @@ pub trait TextDocumentBuilder: DocumentBuilder { } } -/// List of possible errors while parsing. -#[derive(Debug, Clone)] -pub enum V10DocumentParsingError { - /// The given source don't have a valid document format. - InvalidWrapperFormat(), - /// The given source don't have a valid specific document format (document type). - InvalidInnerFormat(&'static str), - /// Type fields contains an unknown document type. - UnknownDocumentType(String), - /// Error with pest parser - PestError(), - /// Invalid currency - InvalidCurrency(), - /// UnexpectedVersion - UnexpectedVersion(), -} - /// V10 Documents in separated parts #[derive(Debug, Clone)] pub struct V10DocumentParts { @@ -206,16 +223,12 @@ pub struct V10DocumentParts { pub signatures: Vec<Sig>, } -trait TextDocumentParser { - fn parse(doc: &str, currency: &str) -> Result<V10Document, V10DocumentParsingError>; -} - /*/// A V10 document parser. #[derive(Debug, Clone, Copy)] pub struct V10DocumentParser; -impl<'a> DocumentParser<&'a str, V10Document, V10DocumentParsingError> for V10DocumentParser { - fn parse(source: &'a str) -> Result<V10Document, V10DocumentParsingError> { +impl<'a> DocumentParser<&'a str, V10Document, TextDocumentParseError> for V10DocumentParser { + fn parse(source: &'a str) -> Result<V10Document, TextDocumentParseError> { /*match DocumentsParser::parse(Rule::document_v10, source) { Ok(mut source_ast) => { let doc_v10_ast = source_ast.next().unwrap(); // get and unwrap the `document_v10` rule; never fails @@ -229,7 +242,7 @@ impl<'a> DocumentParser<&'a str, V10Document, V10DocumentParsingError> for V10Do Rule::tx_v10 => TransactionDocumentParser::parse_standard(doc_type_v10_ast.as_str(), "", currency, vec![]), } } - Err(_) => Err(V10DocumentParsingError::InvalidWrapperFormat()), + Err(_) => Err(TextDocumentParseError::InvalidWrapperFormat()), }*/ if let Some(caps) = DOCUMENT_REGEX.captures(source) { let doctype = &caps["type"]; @@ -243,12 +256,12 @@ match doctype { "Certification" => CertificationDocumentParser::parse_standard(source, currency), "Revocation" => RevocationDocumentParser::parse_standard(source, currency), "Transaction" => TransactionDocumentParser::parse_standard(source, currency), -_ => Err(V10DocumentParsingError::UnknownDocumentType( +_ => Err(TextDocumentParseError::UnknownDocumentType( doctype.to_string(), )), } } else { -Err(V10DocumentParsingError::InvalidWrapperFormat()) +Err(TextDocumentParseError::InvalidWrapperFormat()) } } }*/ @@ -398,13 +411,9 @@ UniqueID: elois Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 Ydnclvw76/JHcKSmU9kl9Ie0ne5/X8NYOqPqbGnufIK3eEPRYYdEYaQh+zffuFhbtIRjv6m/DkVLH5cLy/IyAg=="; - let doc = IdentityDocumentParser::parse(text, "g1").unwrap(); - if let V10Document::Identity(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = IdentityDocumentParser::parse(text).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } #[test] @@ -419,13 +428,9 @@ UserID: elois CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg=="; - let doc = MembershipDocumentParser::parse(text, "g1").unwrap(); - if let V10Document::Membership(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = MembershipDocumentParser::parse(text).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } #[test] @@ -441,13 +446,9 @@ IdtySignature: DjeipIeb/RF0tpVCnVnuw6mH1iLJHIsDfPGLR90Twy3PeoaDz6Yzhc/UjLWqHCi5Y CertTimestamp: 99956-00000472758331FDA8388E30E50CA04736CBFD3B7C21F34E74707107794B56DD Hkps1QU4HxIcNXKT8YmprYTVByBhPP1U2tIM7Z8wENzLKIWAvQClkAvBE7pW9dnVa18sJIJhVZUcRrPAZfmjBA=="; - let doc = CertificationDocumentParser::parse(text, "g1").unwrap(); - if let V10Document::Certification(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = CertificationDocumentParser::parse(text).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } #[test] @@ -461,13 +462,9 @@ IdtyTimestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B85 IdtySignature: 1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg== XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ=="; - let doc = RevocationDocumentParser::parse(text, "g1").unwrap(); - if let V10Document::Revocation(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = RevocationDocumentParser::parse(text).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } #[test] @@ -490,12 +487,8 @@ Outputs: Comment: c est pour 2 mois d adhesion ressourcerie lnpuFsIymgz7qhKF/GsZ3n3W8ZauAAfWmT4W0iJQBLKJK2GFkesLWeMj/+GBfjD6kdkjreg9M6VfkwIZH+hCCQ=="; - let doc = TransactionDocumentParser::parse(text, "g1").unwrap(); - if let V10Document::Transaction(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = TransactionDocumentParser::parse(text).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } } diff --git a/documents/src/v10/revocation.rs b/documents/src/v10/revocation.rs index d4ca1983cd9918576f982d9f82201ac168d52dcd..607a648372bc29cf056e548212edb85cea3745ae 100644 --- a/documents/src/v10/revocation.rs +++ b/documents/src/v10/revocation.rs @@ -116,9 +116,9 @@ impl TextDocument for RevocationDocument { } } -impl IntoSpecializedDocument<BlockchainProtocol> for RevocationDocument { - fn into_specialized(self) -> BlockchainProtocol { - BlockchainProtocol::V10(Box::new(V10Document::Revocation(Box::new(self)))) +impl IntoSpecializedDocument<DUBPDocument> for RevocationDocument { + fn into_specialized(self) -> DUBPDocument { + DUBPDocument::V10(Box::new(V10Document::Revocation(Box::new(self)))) } } @@ -190,103 +190,69 @@ IdtySignature: {idty_sig} pub struct RevocationDocumentParser; impl TextDocumentParser for RevocationDocumentParser { - fn parse(doc: &str, currency: &str) -> Result<V10Document, V10DocumentParsingError> { + type DocumentType = RevocationDocument; + + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError> { match DocumentsParser::parse(Rule::revoc, doc) { - Ok(mut doc_ast) => { - let revoc_ast = doc_ast.next().unwrap(); // get and unwrap the `revoc` rule; never fails - let revoc_vx_ast = revoc_ast.into_inner().next().unwrap(); // get and unwrap the `revoc_vX` rule; never fails - - match revoc_vx_ast.as_rule() { - Rule::revoc_v10 => { - let mut pubkeys = Vec::with_capacity(1); - let mut uid = ""; - let mut sigs = Vec::with_capacity(2); - let mut blockstamps = Vec::with_capacity(1); - for field in revoc_vx_ast.into_inner() { - match field.as_rule() { - Rule::currency => { - if currency != field.as_str() { - return Err(V10DocumentParsingError::InvalidCurrency()); - } - } - Rule::pubkey => { - if !pubkeys.is_empty() { - return Err(V10DocumentParsingError::InvalidInnerFormat( - "Revocation document must contain exactly one pubkey !", - )); - } - pubkeys.push(PubKey::Ed25519( - ed25519::PublicKey::from_base58(field.as_str()).unwrap(), // Grammar ensures that we have a base58 string. - )); - } - Rule::uid => { - uid = field.as_str(); - } - Rule::blockstamp => { - if blockstamps.len() > 1 { - return Err(V10DocumentParsingError::InvalidInnerFormat( - "Revocation document must contain exactly one blockstamp !", - )); - } - let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } - - let block_id: &str = inner_rules.next().unwrap().as_str(); - let block_hash: &str = inner_rules.next().unwrap().as_str(); - blockstamps.push(Blockstamp { - id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. - hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. - }); - } - Rule::ed25519_sig => { - sigs.push(Sig::Ed25519( - ed25519::Signature::from_base64(field.as_str()).unwrap(), // Grammar ensures that we have a base64 string. - )); - } - Rule::EOI => (), - _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line - } - } - Ok(V10Document::Revocation(Box::new(RevocationDocument { - text: doc.to_owned(), - issuers: vec![pubkeys[0]], - currency: currency.to_owned(), - identity_username: uid.to_owned(), - identity_blockstamp: blockstamps[0], - identity_sig: sigs[0], - signatures: vec![sigs[1]], - }))) - } - _ => Err(V10DocumentParsingError::UnexpectedVersion()), + Ok(mut revoc_pairs) => { + let revoc_pair = revoc_pairs.next().unwrap(); // get and unwrap the `revoc` rule; never fails + let revoc_vx_pair = revoc_pair.into_inner().next().unwrap(); // get and unwrap the `revoc_vX` rule; never fails + + match revoc_vx_pair.as_rule() { + Rule::revoc_v10 => Ok(RevocationDocumentParser::from_pest_pair(revoc_vx_pair)), + _ => Err(TextDocumentParseError::UnexpectedVersion(format!( + "{:#?}", + revoc_vx_pair.as_rule() + ))), } } - Err(pest_error) => panic!("{}", pest_error), //Err(V10DocumentParsingError::PestError()), + Err(pest_error) => Err(TextDocumentParseError::PestError(format!("{}", pest_error))), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> Self::DocumentType { + let doc = pair.as_str(); + let mut currency = ""; + let mut pubkeys = Vec::with_capacity(1); + let mut uid = ""; + let mut sigs = Vec::with_capacity(2); + let mut blockstamps = Vec::with_capacity(1); + for field in pair.into_inner() { + match field.as_rule() { + Rule::currency => currency = field.as_str(), + Rule::pubkey => pubkeys.push(PubKey::Ed25519( + ed25519::PublicKey::from_base58(field.as_str()).unwrap(), // Grammar ensures that we have a base58 string. + )), + Rule::uid => { + uid = field.as_str(); + } + Rule::blockstamp => { + let mut inner_rules = field.into_inner(); // { integer ~ "-" ~ hash } + + let block_id: &str = inner_rules.next().unwrap().as_str(); + let block_hash: &str = inner_rules.next().unwrap().as_str(); + blockstamps.push(Blockstamp { + id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. + hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. + }); + } + Rule::ed25519_sig => { + sigs.push(Sig::Ed25519( + ed25519::Signature::from_base64(field.as_str()).unwrap(), // Grammar ensures that we have a base64 string. + )); + } + Rule::EOI => (), + _ => panic!("unexpected rule"), // Grammar ensures that we never reach this line + } + } + RevocationDocument { + text: doc.to_owned(), + issuers: vec![pubkeys[0]], + currency: currency.to_owned(), + identity_username: uid.to_owned(), + identity_blockstamp: blockstamps[0], + identity_sig: sigs[0], + signatures: vec![sigs[1]], } - - /*if let Some(caps) = REVOCATION_REGEX.captures(body) { - let issuer = &caps["issuer"]; - let identity_username = &caps["idty_uid"]; - let identity_blockstamp = &caps["idty_blockstamp"]; - let identity_sig = &caps["idty_sig"]; - - // Regex match so should not fail. - // TODO : Test it anyway - let issuer = PubKey::Ed25519(ed25519::PublicKey::from_base58(issuer).unwrap()); - let identity_username = String::from(identity_username); - let identity_blockstamp = Blockstamp::from_string(identity_blockstamp).unwrap(); - let identity_sig = Sig::Ed25519(Signature::from_base64(identity_sig).unwrap()); - - Ok(V10Document::Revocation(Box::new(RevocationDocument { - text: doc.to_owned(), - issuers: vec![issuer], - currency: currency.to_owned(), - identity_username, - identity_blockstamp, - identity_sig, - signatures, - }))) - } else { - Err(V10DocumentParsingError::InvalidInnerFormat("Revocation")) - }*/ } } @@ -354,14 +320,8 @@ IdtyTimestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B85 IdtySignature: 1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg== XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ=="; - let currency = "g1"; - - let doc = RevocationDocumentParser::parse(doc, currency).unwrap(); - if let V10Document::Revocation(doc) = doc { - println!("Doc : {:?}", doc); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) - } else { - panic!("Wrong document type"); - } + let doc = RevocationDocumentParser::parse(doc).unwrap(); + println!("Doc : {:?}", doc); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()) } } diff --git a/documents/src/v10/transaction.rs b/documents/src/v10/transaction.rs index 8969526018579cf0970d60c5adf6bd35da745e9a..c0729efc4dbb638155fd653d52ff0129bd9f254c 100644 --- a/documents/src/v10/transaction.rs +++ b/documents/src/v10/transaction.rs @@ -76,7 +76,7 @@ impl ToString for TransactionInput { } impl TransactionInput { - fn from_pest_pairs(mut pairs: Pairs<Rule>) -> TransactionInput { + fn from_pest_pair(mut pairs: Pairs<Rule>) -> TransactionInput { let tx_input_type_pair = pairs.next().unwrap(); match tx_input_type_pair.as_rule() { Rule::tx_input_du => { @@ -108,14 +108,14 @@ impl TransactionInput { } impl FromStr for TransactionInput { - type Err = V10DocumentParsingError; + type Err = TextDocumentParseError; fn from_str(source: &str) -> Result<Self, Self::Err> { match DocumentsParser::parse(Rule::tx_input, source) { - Ok(mut pairs) => Ok(TransactionInput::from_pest_pairs( + Ok(mut pairs) => Ok(TransactionInput::from_pest_pair( pairs.next().unwrap().into_inner(), )), - Err(_) => Err(V10DocumentParsingError::InvalidInnerFormat( + Err(_) => Err(TextDocumentParseError::InvalidInnerFormat( "Invalid unlocks !", )), } @@ -124,7 +124,7 @@ impl FromStr for TransactionInput { /*impl TransactionInput { /// Parse Transaction Input from string. - pub fn from_str(source: &str) -> Result<TransactionInput, V10DocumentParsingError> { + pub fn from_str(source: &str) -> Result<TransactionInput, TextDocumentParseError> { if let Some(caps) = D_INPUT_REGEX.captures(source) { let amount = &caps["amount"]; let base = &caps["base"]; @@ -156,7 +156,7 @@ impl FromStr for TransactionInput { )) } else { println!("Fail to parse this input = {:?}", source); - Err(V10DocumentParsingError::InvalidInnerFormat("Transaction2")) + Err(TextDocumentParseError::InvalidInnerFormat("Transaction2")) } } }*/ @@ -201,7 +201,7 @@ impl ToString for TransactionInputUnlocks { } impl TransactionInputUnlocks { - fn from_pest_pairs(pairs: Pairs<Rule>) -> TransactionInputUnlocks { + fn from_pest_pair(pairs: Pairs<Rule>) -> TransactionInputUnlocks { let mut input_index = 0; let mut unlock_conds = Vec::new(); for unlock_field in pairs { @@ -231,14 +231,14 @@ impl TransactionInputUnlocks { } impl FromStr for TransactionInputUnlocks { - type Err = V10DocumentParsingError; + type Err = TextDocumentParseError; fn from_str(source: &str) -> Result<Self, Self::Err> { match DocumentsParser::parse(Rule::tx_unlock, source) { - Ok(mut pairs) => Ok(TransactionInputUnlocks::from_pest_pairs( + Ok(mut pairs) => Ok(TransactionInputUnlocks::from_pest_pair( pairs.next().unwrap().into_inner(), )), - Err(_) => Err(V10DocumentParsingError::InvalidInnerFormat( + Err(_) => Err(TextDocumentParseError::InvalidInnerFormat( "Invalid unlocks !", )), } @@ -446,7 +446,7 @@ impl ToString for TransactionOutput { } impl TransactionOutput { - fn from_pest_pairs(mut utxo_pairs: Pairs<Rule>) -> TransactionOutput { + fn from_pest_pair(mut utxo_pairs: Pairs<Rule>) -> TransactionOutput { let amount = TxAmount(utxo_pairs.next().unwrap().as_str().parse().unwrap()); let base = TxBase(utxo_pairs.next().unwrap().as_str().parse().unwrap()); let conditions_pairs = utxo_pairs.next().unwrap(); @@ -463,14 +463,14 @@ impl TransactionOutput { } impl FromStr for TransactionOutput { - type Err = V10DocumentParsingError; + type Err = TextDocumentParseError; fn from_str(source: &str) -> Result<Self, Self::Err> { match DocumentsParser::parse(Rule::tx_output, source) { - Ok(mut utxo_pairs) => Ok(TransactionOutput::from_pest_pairs( + Ok(mut utxo_pairs) => Ok(TransactionOutput::from_pest_pair( utxo_pairs.next().unwrap().into_inner(), )), - Err(_) => Err(V10DocumentParsingError::InvalidInnerFormat( + Err(_) => Err(TextDocumentParseError::InvalidInnerFormat( "Invalid output !", )), } @@ -654,9 +654,9 @@ impl TextDocument for TransactionDocument { } } -impl IntoSpecializedDocument<BlockchainProtocol> for TransactionDocument { - fn into_specialized(self) -> BlockchainProtocol { - BlockchainProtocol::V10(Box::new(V10Document::Transaction(Box::new(self)))) +impl IntoSpecializedDocument<DUBPDocument> for TransactionDocument { + fn into_specialized(self) -> DUBPDocument { + DUBPDocument::V10(Box::new(V10Document::Transaction(Box::new(self)))) } } @@ -762,79 +762,83 @@ Issuers: pub struct TransactionDocumentParser; impl TextDocumentParser for TransactionDocumentParser { - fn parse(doc: &str, currency: &str) -> Result<V10Document, V10DocumentParsingError> { + type DocumentType = TransactionDocument; + + fn parse(doc: &str) -> Result<Self::DocumentType, TextDocumentParseError> { match DocumentsParser::parse(Rule::tx, doc) { - Ok(mut doc_ast) => { - let tx_ast = doc_ast.next().unwrap(); // get and unwrap the `tx` rule; never fails - let tx_vx_ast = tx_ast.into_inner().next().unwrap(); // get and unwrap the `tx_vX` rule; never fails - - match tx_vx_ast.as_rule() { - Rule::tx_v10 => { - let mut blockstamp = Blockstamp::default(); - let mut locktime = 0; - let mut issuers = Vec::new(); - let mut inputs = Vec::new(); - let mut unlocks = Vec::new(); - let mut outputs = Vec::new(); - let mut comment = ""; - let mut sigs = Vec::new(); - - for field in tx_vx_ast.into_inner() { - match field.as_rule() { - Rule::currency => { - if currency != field.as_str() { - return Err(V10DocumentParsingError::InvalidCurrency()); - } - } - Rule::blockstamp => { - let mut inner_rules = field.into_inner(); // ${ block_id ~ "-" ~ hash } - - let block_id: &str = inner_rules.next().unwrap().as_str(); - let block_hash: &str = inner_rules.next().unwrap().as_str(); - blockstamp = Blockstamp { - id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. - hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. - }; - } - Rule::tx_locktime => locktime = field.as_str().parse().unwrap(), // Grammar ensures that we have digits characters. - Rule::pubkey => issuers.push(PubKey::Ed25519( - ed25519::PublicKey::from_base58(field.as_str()).unwrap(), // Grammar ensures that we have a base58 string. - )), - Rule::tx_input => inputs - .push(TransactionInput::from_pest_pairs(field.into_inner())), - Rule::tx_unlock => unlocks.push( - TransactionInputUnlocks::from_pest_pairs(field.into_inner()), - ), - Rule::tx_output => outputs - .push(TransactionOutput::from_pest_pairs(field.into_inner())), - Rule::tx_comment => comment = field.as_str(), - Rule::ed25519_sig => { - sigs.push(Sig::Ed25519( - ed25519::Signature::from_base64(field.as_str()).unwrap(), // Grammar ensures that we have a base64 string. - )); - } - Rule::EOI => (), - _ => panic!("unexpected rule: {:?}", field.as_rule()), // Grammar ensures that we never reach this line - } - } - Ok(V10Document::Transaction(Box::new(TransactionDocument { - text: Some(doc.to_owned()), - currency: currency.to_owned(), - blockstamp, - locktime, - issuers, - inputs, - unlocks, - outputs, - comment: comment.to_owned(), - signatures: sigs, - hash: None, - }))) - } - _ => Err(V10DocumentParsingError::UnexpectedVersion()), + Ok(mut tx_pairs) => { + let tx_pair = tx_pairs.next().unwrap(); // get and unwrap the `tx` rule; never fails + let tx_vx_pair = tx_pair.into_inner().next().unwrap(); // get and unwrap the `tx_vX` rule; never fails + + match tx_vx_pair.as_rule() { + Rule::tx_v10 => Ok(TransactionDocumentParser::from_pest_pair(tx_vx_pair)), + _ => Err(TextDocumentParseError::UnexpectedVersion(format!( + "{:#?}", + tx_vx_pair.as_rule() + ))), } } - Err(pest_error) => panic!("{}", pest_error), //Err(V10DocumentParsingError::PestError()), + Err(pest_error) => Err(TextDocumentParseError::PestError(format!("{}", pest_error))), + } + } + fn from_pest_pair(pair: Pair<Rule>) -> Self::DocumentType { + let doc = pair.as_str(); + let mut currency = ""; + let mut blockstamp = Blockstamp::default(); + let mut locktime = 0; + let mut issuers = Vec::new(); + let mut inputs = Vec::new(); + let mut unlocks = Vec::new(); + let mut outputs = Vec::new(); + let mut comment = ""; + let mut sigs = Vec::new(); + + for field in pair.into_inner() { + match field.as_rule() { + Rule::currency => currency = field.as_str(), + Rule::blockstamp => { + let mut inner_rules = field.into_inner(); // ${ block_id ~ "-" ~ hash } + + let block_id: &str = inner_rules.next().unwrap().as_str(); + let block_hash: &str = inner_rules.next().unwrap().as_str(); + blockstamp = Blockstamp { + id: BlockId(block_id.parse().unwrap()), // Grammar ensures that we have a digits string. + hash: BlockHash(Hash::from_hex(block_hash).unwrap()), // Grammar ensures that we have an hexadecimal string. + }; + } + Rule::tx_locktime => locktime = field.as_str().parse().unwrap(), // Grammar ensures that we have digits characters. + Rule::pubkey => issuers.push(PubKey::Ed25519( + ed25519::PublicKey::from_base58(field.as_str()).unwrap(), // Grammar ensures that we have a base58 string. + )), + Rule::tx_input => inputs.push(TransactionInput::from_pest_pair(field.into_inner())), + Rule::tx_unlock => { + unlocks.push(TransactionInputUnlocks::from_pest_pair(field.into_inner())) + } + Rule::tx_output => { + outputs.push(TransactionOutput::from_pest_pair(field.into_inner())) + } + Rule::tx_comment => comment = field.as_str(), + Rule::ed25519_sig => { + sigs.push(Sig::Ed25519( + ed25519::Signature::from_base64(field.as_str()).unwrap(), // Grammar ensures that we have a base64 string. + )); + } + Rule::EOI => (), + _ => panic!("unexpected rule: {:?}", field.as_rule()), // Grammar ensures that we never reach this line + } + } + TransactionDocument { + text: Some(doc.to_owned()), + currency: currency.to_owned(), + blockstamp, + locktime, + issuers, + inputs, + unlocks, + outputs, + comment: comment.to_owned(), + signatures: sigs, + hash: None, } } } @@ -995,17 +999,14 @@ kL59C1izKjcRN429AlKdshwhWbasvyL7sthI757zm1DfZTdTIctDWlKbYeG/tS7QyAgI3gcfrTHPhu1E e3LpgB2RZ/E/BCxPJsn+TDDyxGYzrIsMyDt//KhJCjIQD6pNUxr5M5jrq2OwQZgwmz91YcmoQ2XRQAUDpe4BAw== w69bYgiQxDmCReB0Dugt9BstXlAKnwJkKCdWvCeZ9KnUCv0FJys6klzYk/O/b9t74tYhWZSX0bhETWHiwfpWBw=="; - let currency = "duniter_unit_test_currency"; - - let doc = TransactionDocumentParser::parse(doc, currency) + let doc = TransactionDocumentParser::parse(doc) .expect("fail to parse test transaction document !"); - if let V10Document::Transaction(doc) = doc { - //println!("Doc : {:?}", doc); - println!("{}", doc.generate_compact_text()); - assert_eq!(doc.verify_signatures(), VerificationResult::Valid()); - assert_eq!( - doc.generate_compact_text(), - "TX:10:3:6:6:3:1:0 + //println!("Doc : {:?}", doc); + println!("{}", doc.generate_compact_text()); + assert_eq!(doc.verify_signatures(), VerificationResult::Valid()); + assert_eq!( + doc.generate_compact_text(), + "TX:10:3:6:6:3:1:0 204-00003E2B8A35370BA5A7064598F628A62D4E9EC1936BE8651CE9A85F2E06981B DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV 4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR @@ -1029,9 +1030,6 @@ FD9wujR7KABw88RyKEGBYRLz8PA6jzVCbcBAsrBXBqSa kL59C1izKjcRN429AlKdshwhWbasvyL7sthI757zm1DfZTdTIctDWlKbYeG/tS7QyAgI3gcfrTHPhu1E1lKCBw== e3LpgB2RZ/E/BCxPJsn+TDDyxGYzrIsMyDt//KhJCjIQD6pNUxr5M5jrq2OwQZgwmz91YcmoQ2XRQAUDpe4BAw== w69bYgiQxDmCReB0Dugt9BstXlAKnwJkKCdWvCeZ9KnUCv0FJys6klzYk/O/b9t74tYhWZSX0bhETWHiwfpWBw==" - ); - } else { - panic!("Wrong document type"); - } + ); } } diff --git a/message/lib.rs b/message/lib.rs index b6d75d48790c2a630ee1f9ba69dc04fb0798be8b..b30c0fdc2ee24cf3efb116fb3d8a335592d9034f 100644 --- a/message/lib.rs +++ b/message/lib.rs @@ -42,7 +42,7 @@ use duniter_crypto::keys::Sig; use duniter_dal::dal_event::DALEvent; use duniter_dal::dal_requests::{DALRequest, DALResponse}; use duniter_documents::BlockId; -use duniter_documents::BlockchainProtocol; +use duniter_documents::DUBPDocument; use duniter_module::*; use duniter_network::{NetworkEvent, NetworkResponse, OldNetworkRequest}; @@ -89,7 +89,7 @@ pub enum DursMsgContent { /// Pow module response ProverResponse(BlockId, Sig, u64), /// Client API event - ReceiveDocsFromClient(Vec<BlockchainProtocol>), + ReceiveDocsFromClient(Vec<DUBPDocument>), /// Stop signal Stop(), }