Skip to content
Snippets Groups Projects
Commit f0a99b64 authored by Éloïs's avatar Éloïs
Browse files

[enh] add generate compact format for all documents

parent 91b9d8cd
No related branches found
No related tags found
No related merge requests found
......@@ -191,6 +191,16 @@ CertTimestamp: {blockstamp}
blockstamp = self.blockstamp,
)
}
fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String {
format!(
"{issuer}:{target}:{block_number}:{signature}",
issuer = self.issuer,
target = self.target,
block_number = self.blockstamp.id.0,
signature = signatures[0],
)
}
}
/// Certification document parser
......@@ -297,6 +307,12 @@ mod tests {
builder.build_and_sign(vec![prikey]).verify_signatures(),
VerificationResult::Valid()
);
assert_eq!(
builder.generate_compact_text(vec![sig]),
"4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR:\
DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:36:\
qfR6zqT1oJbqIsppOi64gC9yTtxb6g6XA9RYpulkq9ehMvqg2VYVigCbR0yVpqKFsnYiQTrnjgFuFRSJCJDfCw=="
);
}
#[test]
......
......@@ -43,7 +43,7 @@ pub struct IdentityDocument {
/// Currency.
currency: String,
/// Unique ID
unique_id: String,
username: String,
/// Blockstamp
blockstamp: Blockstamp,
/// Document issuer (there should be only one).
......@@ -54,8 +54,8 @@ pub struct IdentityDocument {
impl IdentityDocument {
/// Unique ID
pub fn unique_id(&self) -> &str {
&self.unique_id
pub fn username(&self) -> &str {
&self.username
}
}
......@@ -102,7 +102,7 @@ pub struct IdentityDocumentBuilder<'a> {
/// Document currency.
pub currency: &'a str,
/// Identity unique id.
pub unique_id: &'a str,
pub username: &'a str,
/// Reference blockstamp.
pub blockstamp: &'a Blockstamp,
/// Document/identity issuer.
......@@ -118,7 +118,7 @@ impl<'a> IdentityDocumentBuilder<'a> {
IdentityDocument {
text,
currency: self.currency.to_string(),
unique_id: self.unique_id.to_string(),
username: self.username.to_string(),
blockstamp: *self.blockstamp,
issuers: vec![*self.issuer],
signatures,
......@@ -147,15 +147,25 @@ impl<'a> TextDocumentBuilder for IdentityDocumentBuilder<'a> {
Type: Identity
Currency: {currency}
Issuer: {issuer}
UniqueID: {unique_id}
UniqueID: {username}
Timestamp: {blockstamp}
",
currency = self.currency,
issuer = self.issuer,
unique_id = self.unique_id,
username = self.username,
blockstamp = self.blockstamp
)
}
fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String {
format!(
"{issuer}:{signature}:{blockstamp}:{username}",
issuer = self.issuer,
signature = signatures[0],
blockstamp = self.blockstamp,
username = self.username,
)
}
}
/// Identity document parser
......@@ -182,7 +192,7 @@ impl StandardTextDocumentParser for IdentityDocumentParser {
Ok(V10Document::Identity(IdentityDocument {
text: doc.to_owned(),
currency: currency.to_owned(),
unique_id: uid.to_owned(),
username: uid.to_owned(),
blockstamp,
issuers: vec![issuer],
signatures,
......@@ -223,7 +233,7 @@ mod tests {
let builder = IdentityDocumentBuilder {
currency: "duniter_unit_test_currency",
unique_id: "tic",
username: "tic",
blockstamp: &block,
issuer: &pubkey,
};
......
......@@ -190,6 +190,17 @@ CertTS: {ity_blockstamp}
ity_blockstamp = self.identity_blockstamp,
)
}
fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String {
format!(
"{issuer}:{signature}:{blockstamp}:{idty_blockstamp}:{username}",
issuer = self.issuer,
signature = signatures[0],
blockstamp = self.blockstamp,
idty_blockstamp = self.identity_blockstamp,
username = self.identity_username,
)
}
}
/// Membership document parser
......@@ -284,6 +295,14 @@ mod tests {
builder.build_and_sign(vec![prikey]).verify_signatures(),
VerificationResult::Valid()
);
assert_eq!(
builder.generate_compact_text(vec![sig]),
"DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:\
s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==:\
0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:\
0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:\
tic"
);
}
#[test]
......
......@@ -105,6 +105,13 @@ pub trait TextDocumentBuilder: DocumentBuilder {
/// - Contains line breaks on all line.
fn generate_text(&self) -> String;
/// Generate document compact text.
/// the compact format is the one used in the blocks.
///
/// - Don't contains leading signatures
/// - Contains line breaks on all line.
fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String;
/// Generate final document with signatures, and also return them in an array.
///
/// Returns :
......@@ -164,15 +171,6 @@ trait StandardTextDocumentParser {
) -> Result<V10Document, V10DocumentParsingError>;
}
trait CompactTextDocumentParser<D: TextDocument> {
fn parse_compact(
doc: &str,
body: &str,
currency: &str,
signatures: Vec<ed25519::Signature>,
) -> Result<D, V10DocumentParsingError>;
}
/// A V10 document parser.
#[derive(Debug, Clone, Copy)]
pub struct V10DocumentParser;
......@@ -298,11 +296,11 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN
fn parse_identity_document() {
let text = "Version: 10
Type: Identity
Currency: duniter_unit_test_currency
Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
UniqueID: tic
Currency: g1
Issuer: D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx
UniqueID: elois
Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==";
Ydnclvw76/JHcKSmU9kl9Ie0ne5/X8NYOqPqbGnufIK3eEPRYYdEYaQh+zffuFhbtIRjv6m/DkVLH5cLy/IyAg==";
let doc = V10DocumentParser::parse(text).unwrap();
if let V10Document::Identity(doc) = doc {
......@@ -317,13 +315,13 @@ Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
fn parse_membership_document() {
let text = "Version: 10
Type: Membership
Currency: duniter_unit_test_currency
Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
Currency: g1
Issuer: D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx
Block: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Membership: IN
UserID: tic
UserID: elois
CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==";
FFeyrvYio9uYwY5aMcDGswZPNjGLrl8THn9l3EPKSNySD3SDSHjCljSfFEwb87sroyzJQoVzPwER0sW/cbZMDg==";
let doc = V10DocumentParser::parse(text).unwrap();
if let V10Document::Membership(doc) = doc {
......
......@@ -165,6 +165,13 @@ IdtySignature: {idty_sig}
idty_sig = self.identity_sig,
)
}
fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String {
format!(
"{issuer}:{signature}",
issuer = self.issuer,
signature = signatures[0],
)
}
}
/// Revocation document parser
......
......@@ -535,6 +535,52 @@ Issuers:
comment = self.comment,
)
}
fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String {
let mut issuers_str = String::from("");
for issuer in self.issuers {
issuers_str.push_str(&issuer.to_string());
}
let mut inputs_str = String::from("");
for input in self.inputs {
inputs_str.push_str(&input.to_string());
}
let mut unlocks_str = String::from("");
for unlock in self.unlocks {
unlocks_str.push_str(&unlock.to_string());
}
let mut outputs_str = String::from("");
for output in self.outputs {
outputs_str.push_str(&output.to_string());
}
let mut signatures_str = String::from("");
for sig in signatures {
signatures_str.push_str(&sig.to_string());
}
format!(
"TX:10:{issuers_count}:{inputs_count}:{unlocks_count}:{outputs_count}:{has_comment}:{locktime}
{blockstamp}
{issuers}
{inputs}
{unlocks}
{outputs}
{comment}
{signatures}",
issuers_count = self.issuers.len(),
inputs_count = self.inputs.len(),
unlocks_count = self.unlocks.len(),
outputs_count = self.outputs.len(),
has_comment = if self.comment.is_empty() { 0 } else { 1 },
locktime = self.locktime,
blockstamp = self.blockstamp,
issuers = issuers_str,
inputs = inputs_str,
unlocks = unlocks_str,
outputs = outputs_str,
comment = self.comment,
signatures = signatures_str,
)
}
}
/// Transaction document parser
......@@ -553,20 +599,18 @@ impl StandardTextDocumentParser for TransactionDocumentParser {
.build()
.expect("fail to build TRANSACTION_REGEX !");
if let Some(caps) = tx_regex.captures(body) {
let blockstamp = &caps["blockstamp"];
let locktime = &caps["locktime"];
let issuers_string = &caps["issuers"];
let blockstamp =
Blockstamp::from_string(&caps["blockstamp"]).expect("fail to parse blockstamp");
let locktime = caps["locktime"].parse().expect("fail to parse locktime");
let issuers_str = &caps["issuers"];
let inputs = &caps["inputs"];
let unlocks = &caps["unlocks"];
let outputs = &caps["outputs"];
let comment = &caps["comment"];
let comment = String::from(&caps["comment"]);
// Regex match so should not fail.
// TODO : Test it anyway
let blockstamp = Blockstamp::from_string(blockstamp).expect("fail to parse blockstamp");
let locktime = locktime.parse().expect("fail to parse locktime");
let mut issuers = Vec::new();
for caps in ISSUER_REGEX.captures_iter(issuers_string) {
for caps in ISSUER_REGEX.captures_iter(issuers_str) {
println!("{:?}", &caps["issuer"]);
issuers.push(
ed25519::PublicKey::from_base58(&caps["issuer"]).expect("fail to parse issuer"),
);
......@@ -592,8 +636,6 @@ impl StandardTextDocumentParser for TransactionDocumentParser {
outputs.push(TransactionOuput::parse_from_str(output)?);
}
}
let comment = String::from(comment);
// let re = Regex::new(r"[ \t]+").unwrap();
Ok(V10Document::Transaction(Box::new(TransactionDocument {
text: doc.to_owned(),
......@@ -673,6 +715,18 @@ mod tests {
builder.build_and_sign(vec![prikey]).verify_signatures(),
VerificationResult::Valid()
);
assert_eq!(
builder.generate_compact_text(vec![sig]),
"TX:10:1:1:1:1:1:0
0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
10:0:D:DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:0
0:SIG(0)
10:0:SIG(FD9wujR7KABw88RyKEGBYRLz8PA6jzVCbcBAsrBXBqSa)
test
pRQeKlzCsvPNmYAAkEP5jPPQO1RwrtFMRfCajEfkkrG0UQE0DhoTkxG3Zs2JFmvAFLw67pn1V5NQ08zsSfJkBg=="
);
}
#[test]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment