From 43f8edf4144ffcfa83c9f8336e5db366bac70d70 Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 08:26:16 +0000 Subject: [PATCH 01/10] Secrets file mandatory --- src/cli.rs | 2 +- src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index b0cd670a..b098406a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -144,7 +144,7 @@ pub enum BuildKindCommand { max_thread_count: MaxThreadCount, #[arg(short, long, value_name = "FILE_PATH", long_help = SECRETS_HELP)] - secrets_file: Option, + secrets_file: InputArg, #[command(flatten)] entity_source: EntitySource, diff --git a/src/main.rs b/src/main.rs index e64a358c..4310b378 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,7 +65,7 @@ fn main() { entity_source.entities_file.and_then(|arg| arg.into_path()), ) .num_random_entities_opt(entity_source.random_entities) - .secrets_file_path_opt(secrets_file.and_then(|arg| arg.into_path())) + .secrets_file_path_opt(secrets_file.into_path()) .build() .log_on_err_unwrap() .parse() From 2426d9a8e993355d9f82a3f6e46c9b1703c5aa04 Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 08:44:18 +0000 Subject: [PATCH 02/10] Fix smol error in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b0b7552e..1c79407f 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,8 @@ Generate proofs (proofs will live in the `./inclusion_proofs/` directory): Build a tree using cli args as apposed to a config file: ```bash -# this will generate random secrets & 1000 random entities -./target/release/dapol -vvv build-tree new --accumulator ndm-smt --height 16 --random-entities 1000 +# this will generate 1000 random entities +./target/release/dapol -vvv build-tree new --accumulator ndm-smt --height 16 --random-entities 1000 --secrets-file ./examples/dapol_secrets_example.toml ``` #### Proof generation From e65895a0315a1530029f0ab37908a1840c8e647c Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 09:16:45 +0000 Subject: [PATCH 03/10] Change default log verbosity to info --- src/cli.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index b098406a..2cbdeab7 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -3,7 +3,7 @@ //! See [MAIN_LONG_ABOUT] for more information. use clap::{command, Args, Parser, Subcommand}; -use clap_verbosity_flag::{Verbosity, WarnLevel}; +use clap_verbosity_flag::{Verbosity, InfoLevel}; use patharg::{InputArg, OutputArg}; use primitive_types::H256; @@ -30,7 +30,7 @@ pub struct Cli { pub command: Command, #[command(flatten)] - pub verbose: Verbosity, + pub verbose: Verbosity, } #[derive(Debug, Subcommand)] From 439fa736bec8b0ba6038f100f6d242eb4784f68d Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 13:16:23 +0000 Subject: [PATCH 04/10] Make EntityIdNotFound error clearer --- src/accumulators/ndm_smt.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/accumulators/ndm_smt.rs b/src/accumulators/ndm_smt.rs index 695f302c..c62dfc6d 100644 --- a/src/accumulators/ndm_smt.rs +++ b/src/accumulators/ndm_smt.rs @@ -309,7 +309,7 @@ impl NdmSmt { .entity_mapping .get(entity_id) .and_then(|leaf_x_coord| self.binary_tree.get_leaf_node(*leaf_x_coord)) - .ok_or(NdmSmtError::EntityIdNotFound)?; + .ok_or(NdmSmtError::EntityIdNotFound(entity_id.clone()))?; let path_siblings = PathSiblings::build_using_multi_threaded_algorithm( &self.binary_tree, @@ -394,8 +394,8 @@ pub enum NdmSmtError { InclusionProofPathSiblingsGenerationError(#[from] crate::binary_tree::PathSiblingsBuildError), #[error("Inclusion proof generation failed")] InclusionProofGenerationError(#[from] crate::inclusion_proof::InclusionProofError), - #[error("Entity ID not found in the entity mapping")] - EntityIdNotFound, + #[error("Entity ID {0:?} not found in the entity mapping")] + EntityIdNotFound(EntityId), #[error("Entity ID {0:?} was duplicated")] DuplicateEntityIds(EntityId), } From 4ca5511afae84e0904fe18cd4489026c94fecaa7 Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 13:18:20 +0000 Subject: [PATCH 05/10] Allow entity-id parser to accept string list --- src/entity.rs | 4 +- src/entity/entities_parser.rs | 4 -- src/entity/entity_ids_parser.rs | 85 ++++++++++++++++++++++++++------- src/main.rs | 24 +++++++--- 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/src/entity.rs b/src/entity.rs index d16dfe0d..53a5678d 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -40,13 +40,13 @@ pub const ENTITY_ID_MAX_BYTES: usize = 32; pub struct EntityId(String); impl FromStr for EntityId { - type Err = EntitiesParserError; + type Err = EntityIdsParserError; /// Constructor that takes in a string slice. /// If the length of the str is greater than the max then Err is returned. fn from_str(s: &str) -> Result { if s.len() > ENTITY_ID_MAX_BYTES { - Err(EntitiesParserError::EntityIdTooLongError { id: s.into() }) + Err(Self::Err::EntityIdTooLongError { id: s.into() }) } else { Ok(EntityId(s.into())) } diff --git a/src/entity/entities_parser.rs b/src/entity/entities_parser.rs index 27a91a74..f71c6012 100644 --- a/src/entity/entities_parser.rs +++ b/src/entity/entities_parser.rs @@ -170,10 +170,6 @@ pub enum EntitiesParserError { UnsupportedFileType { ext: String }, #[error("Error opening or reading CSV file")] CsvError(#[from] csv::Error), - #[error( - "The given entity ID ({id:?}) is longer than the max allowed {ENTITY_ID_MAX_BYTES} bytes" - )] - EntityIdTooLongError { id: String }, } // ------------------------------------------------------------------------------------------------- diff --git a/src/entity/entity_ids_parser.rs b/src/entity/entity_ids_parser.rs index 670da2c8..6a335b5c 100644 --- a/src/entity/entity_ids_parser.rs +++ b/src/entity/entity_ids_parser.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use std::{ffi::OsString, path::PathBuf}; -use log::debug; +use log::{debug, info}; use crate::entity::{EntityId, ENTITY_ID_MAX_BYTES}; @@ -23,6 +23,7 @@ use crate::entity::{EntityId, ENTITY_ID_MAX_BYTES}; /// ``` pub struct EntityIdsParser { path: Option, + entity_ids_list: Option, } /// Supported file types for the parser. @@ -31,21 +32,59 @@ enum FileType { } impl EntityIdsParser { - /// Open and parse the file, returning a vector of entity IDs. - /// The file is expected to hold 1 or more entity records. + /// Parse the input. /// - /// An error is returned if: - /// a) the file cannot be opened - /// b) the file type is not supported - /// c) deserialization of any of the records in the file fails + /// If the `path` field is set then: + /// - Open and parse the file, returning a vector of entity IDs. + /// - The file is expected to hold 1 or more entity records. + /// - An error is returned if: + /// a) the file cannot be opened + /// b) the file type is not supported + /// c) deserialization of any of the records in the file fails + /// + /// If `path` is not set and `entity_ids_list` is then: + /// - Parse the value as a string list using `serde_json` + /// - An error is returned if: + /// a) deserialization using `serde_json` fails pub fn parse(self) -> Result, EntityIdsParserError> { + if let Some(path) = self.path { + EntityIdsParser::parse_csv(path) + } else if let Some(entity_ids_list) = self.entity_ids_list { + info!("list {:?}", entity_ids_list); + // let mut json_styled = "{".to_string(); + // json_styled.push_str(&entity_ids_list); + // json_styled.push_str("}"); + EntityIdsParser::parse_list(entity_ids_list) + } else { + Err(EntityIdsParserError::NeitherPathNorListSet) + } + } + + fn parse_list(mut entity_ids_list: String) -> Result, EntityIdsParserError> { + if entity_ids_list.chars().nth_back(0).map_or(false, |c| c == '\n') { + entity_ids_list.pop(); + } + + // let raw_vec: Vec = serde_json::from_str(entity_ids_json)?; + let parts = entity_ids_list.split(','); + //let entity_ids = parts.collect::>(); + + let mut entity_ids = Vec::::new();// = Vec::with_capacity(raw_vec.len()); + for part in parts { + entity_ids.push(EntityId::from_str(&part)?) + } + + info!("entity ids {:?}", entity_ids); + + Ok(entity_ids) + } + + fn parse_csv(path: PathBuf) -> Result, EntityIdsParserError> { debug!( "Attempting to parse {:?} as a file containing a list of entity IDs", - &self.path + &path ); - let path = self.path.ok_or(EntityIdsParserError::PathNotSet)?; - let ext = path.extension().and_then(|s| s.to_str()).ok_or( EntityIdsParserError::UnknownFileType(path.clone().into_os_string()), )?; @@ -71,14 +110,28 @@ impl EntityIdsParser { impl From for EntityIdsParser { fn from(path: PathBuf) -> Self { - Self { path: Some(path) } + Self { + path: Some(path), + entity_ids_list: None, + } + } +} + +impl FromStr for EntityIdsParser { + type Err = EntityIdsParserError; + + fn from_str(value: &str) -> Result { + Ok(Self { + path: None, + entity_ids_list: Some(value.to_string()), + }) } } impl FromStr for FileType { type Err = EntityIdsParserError; - fn from_str(ext: &str) -> Result { + fn from_str(ext: &str) -> Result { match ext { "csv" => Ok(FileType::Csv), _ => Err(EntityIdsParserError::UnsupportedFileType { ext: ext.into() }), @@ -92,16 +145,16 @@ impl FromStr for FileType { /// Errors encountered when handling [EntityIdsParser]. #[derive(thiserror::Error, Debug)] pub enum EntityIdsParserError { - #[error("Expected path to be set but found none")] - PathNotSet, - #[error("Expected num_entities to be set but found none")] - NumEntitiesNotSet, + #[error("Either path or entity_id_list must be set")] + NeitherPathNorListSet, #[error("Unable to find file extension for path {0:?}")] UnknownFileType(OsString), #[error("The file type with extension {ext:?} is not supported")] UnsupportedFileType { ext: String }, #[error("Error opening or reading CSV file")] CsvError(#[from] csv::Error), + #[error("Problem serializing/deserializing with serde_json")] + JsonSerdeError(#[from] serde_json::Error), #[error( "The given entity ID ({id:?}) is longer than the max allowed {ENTITY_ID_MAX_BYTES} bytes" )] diff --git a/src/main.rs b/src/main.rs index 4310b378..dca33b83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -138,17 +138,27 @@ fn main() { ) .log_on_err_unwrap(); - // TODO for entity IDs: accept either path or stdin - let entity_ids = EntityIdsParser::from( - entity_ids - .into_path() - .expect("Expected file path, not stdin"), - ) + let entity_ids = if entity_ids.is_path() { + EntityIdsParser::from( + entity_ids + .into_path() + .expect("Expected file path, not stdin"), + ) + } else { + EntityIdsParser::from_str( + &entity_ids + .read_to_string() + .expect("Problem reading from stdin"), + ) + .log_on_err_unwrap() + } .parse() .log_on_err_unwrap(); let dir = PathBuf::from("./inclusion_proofs/"); - std::fs::create_dir(dir.as_path()).log_on_err_unwrap(); + if !dir.exists() { + std::fs::create_dir(dir.as_path()).log_on_err_unwrap(); + } let aggregation_factor = AggregationFactor::Percent(range_proof_aggregation); From 8b5ac6877fbdc919890cdd818e329ec8fd8c8ee6 Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 13:22:07 +0000 Subject: [PATCH 06/10] Easier install method in readme --- README.md | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1c79407f..6617126d 100644 --- a/README.md +++ b/README.md @@ -40,29 +40,21 @@ See the [examples](https://github.com/silversixpence-crypto/dapol/examples) dire ### CLI -There is no downloadable executable ([yet](https://github.com/silversixpence-crypto/dapol/issues/110)) so the CLI has to be built from source. You will need to have the rust compiler installed: +Install with cargo: ```bash -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs >> ./rustup-init.sh -./rustup-init.sh -y --no-modify-path -rm -f ./rustup-init.sh -``` - -For now you must clone the repo to use the CLI. Once you have cloned the repo build everything: -```bash -# run inside the repo -cargo build --release +cargo install dapol ``` You can invoke the CLI like so: ```bash -./target/release/dapol help +dapol help ``` The CLI offers 3 main operations: tree building, proof generation & proof verification. All options can be explored with: ```bash -./target/release/dapol build-tree help -./target/release/dapol gen-proofs help -./target/release/dapol verify-proof help +dapol build-tree help +dapol gen-proofs help +dapol verify-proof help ``` #### Tree building @@ -74,28 +66,28 @@ Building a tree can be done: Build a tree using config file (full log verbosity): ```bash -./target/release/dapol -vvv build-tree config-file ./examples/dapol_config_example.toml +dapol -vvv build-tree config-file ./examples/dapol_config_example.toml ``` Add serialization: ```bash -./target/release/dapol -vvv build-tree config-file ./examples/dapol_config_example.toml --serialize . +dapol -vvv build-tree config-file ./examples/dapol_config_example.toml --serialize . ``` Deserialize a tree from a file: ```bash -./target/release/dapol -vvv build-tree deserialize +dapol -vvv build-tree deserialize ``` Generate proofs (proofs will live in the `./inclusion_proofs/` directory): ```bash -./target/release/dapol -vvv build-tree config-file ./examples/dapol_config_example.toml --gen-proofs ./examples/entities_example.csv +dapol -vvv build-tree config-file ./examples/dapol_config_example.toml --gen-proofs ./examples/entities_example.csv ``` Build a tree using cli args as apposed to a config file: ```bash # this will generate 1000 random entities -./target/release/dapol -vvv build-tree new --accumulator ndm-smt --height 16 --random-entities 1000 --secrets-file ./examples/dapol_secrets_example.toml +dapol -vvv build-tree new --accumulator ndm-smt --height 16 --random-entities 1000 --secrets-file ./examples/dapol_secrets_example.toml ``` #### Proof generation @@ -103,7 +95,7 @@ Build a tree using cli args as apposed to a config file: As seen above, the proof generation can be done via the tree build command, but it can also be done via its own command, which offers some more options around how the proofs are generated. ```bash -./target/release/dapol -vvv gen-proofs --entity-ids ./examples/entities_example.csv --tree-file +dapol -vvv gen-proofs --entity-ids ./examples/entities_example.csv --tree-file ``` The proof generation command only offers 1 way to inject the tree (deserialization), as apposed to the tree build which offers different options. @@ -111,7 +103,7 @@ The proof generation command only offers 1 way to inject the tree (deserializati #### Proof verification ```bash -./target/release/dapol -vvv verify-proof --file-path --root-hash +dapol -vvv verify-proof --file-path --root-hash ``` The root hash is logged out at info level when the tree is built or deserialized. From b940bdfa06815bbb36abb233467584d607bdf5e5 Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 19:38:20 +0000 Subject: [PATCH 07/10] Add json serde for inclusion proofs Note that deserialization of Bulletproofs from json is broken --- .gitignore | 3 +- src/cli.rs | 9 ++++- src/inclusion_proof.rs | 83 +++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 2 +- src/main.rs | 7 ++-- 5 files changed, 92 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index a9e1c12d..3920ed61 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ Cargo.lock # Generated files **/*.dapoltree -**/*.dapolproof \ No newline at end of file +**/*.dapolproof +inclusion_proofs/ \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 2cbdeab7..1a9b48dc 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -3,7 +3,7 @@ //! See [MAIN_LONG_ABOUT] for more information. use clap::{command, Args, Parser, Subcommand}; -use clap_verbosity_flag::{Verbosity, InfoLevel}; +use clap_verbosity_flag::{InfoLevel, Verbosity}; use patharg::{InputArg, OutputArg}; use primitive_types::H256; @@ -12,8 +12,9 @@ use std::str::FromStr; use crate::{ accumulators::AccumulatorType, binary_tree::Height, + inclusion_proof, percentage::{Percentage, ONE_HUNDRED_PERCENT}, - MaxLiability, MaxThreadCount, Salt, + InclusionProofFileType, MaxLiability, MaxThreadCount, Salt, }; // ------------------------------------------------------------------------------------------------- @@ -87,6 +88,10 @@ pub enum Command { /// are aggregated using the Bulletproofs protocol. #[arg(short, long, value_parser = Percentage::from_str, default_value = ONE_HUNDRED_PERCENT, value_name = "PERCENTAGE")] range_proof_aggregation: Percentage, + + /// File type for proofs (supported types: binary, json). + #[arg(short, long, value_parser = InclusionProofFileType::from_str, default_value = InclusionProofFileType::default())] + file_type: inclusion_proof::InclusionProofFileType, }, /// Verify an inclusion proof. diff --git a/src/inclusion_proof.rs b/src/inclusion_proof.rs index d5ecdff2..1e642cf9 100644 --- a/src/inclusion_proof.rs +++ b/src/inclusion_proof.rs @@ -225,15 +225,22 @@ impl InclusionProof { &self, entity_id: &EntityId, dir: PathBuf, + file_type: InclusionProofFileType, ) -> Result { let mut file_name = entity_id.to_string(); file_name.push('.'); - file_name.push_str(SERIALIZED_PROOF_EXTENSION); + file_name.push_str(match file_type { + InclusionProofFileType::Binary => SERIALIZED_PROOF_EXTENSION, + InclusionProofFileType::Json => "json", + }); let path = dir.join(file_name); info!("Serializing inclusion proof to path {:?}", path); - read_write_utils::serialize_to_bin_file(&self, path.clone())?; + match file_type { + InclusionProofFileType::Binary => read_write_utils::serialize_to_bin_file(&self, path.clone())?, + InclusionProofFileType::Json => read_write_utils::serialize_to_json_file(&self, path.clone())?, + } Ok(path) } @@ -246,15 +253,77 @@ impl InclusionProof { /// 1. The file cannot be opened. /// 2. The [bincode] deserializer fails. pub fn deserialize(file_path: PathBuf) -> Result { - info!("Deserializing inclusion proof to path {:?}", file_path); - let proof: InclusionProof = read_write_utils::deserialize_from_bin_file(file_path)?; - Ok(proof) + let ext = file_path.extension().and_then(|s| s.to_str()).ok_or( + InclusionProofError::UnknownFileType(file_path.clone().into_os_string()), + )?; + + info!("Deserializing inclusion proof from file {:?}", file_path); + + match ext { + SERIALIZED_PROOF_EXTENSION => Ok(read_write_utils::deserialize_from_bin_file(file_path)?), + "json" => Ok(read_write_utils::deserialize_from_json_file(file_path)?), + _ => Err(InclusionProofError::UnsupportedFileType { ext: ext.into() }), + } + } +} + +// ------------------------------------------------------------------------------------------------- +// Supported (de)serialization file types. + +/// Supported file types for serialization. +#[derive(Debug, Clone)] +pub enum InclusionProofFileType { + /// Binary file format. + /// + /// Most efficient but not human readable, unless you have the gift. + Binary, + + /// JSON file format. + /// + /// Not the most efficient but is human readable. + Json, +} + +use std::str::FromStr; + +impl FromStr for InclusionProofFileType { + type Err = InclusionProofError; + + fn from_str(ext: &str) -> Result { + match ext.to_lowercase().as_str() { + "binary" => Ok(InclusionProofFileType::Binary), + "json" => Ok(InclusionProofFileType::Json), + _ => Err(InclusionProofError::UnsupportedFileType { ext: ext.into() }), + } + } +} + +use clap::builder::{OsStr, Str}; + +// From for OsStr (for the CLI). +impl From for OsStr { + fn from(file_type: InclusionProofFileType) -> OsStr { + OsStr::from(Str::from(file_type.to_string())) + } +} + +impl std::fmt::Display for InclusionProofFileType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl Default for InclusionProofFileType { + fn default() -> Self { + InclusionProofFileType::Binary } } // ------------------------------------------------------------------------------------------------- // Errors +use std::ffi::OsString; + /// Errors encountered when handling [InclusionProof]. #[derive(thiserror::Error, Debug)] pub enum InclusionProofError { @@ -266,6 +335,10 @@ pub enum InclusionProofError { RangeProofError(#[from] RangeProofError), #[error("Error serializing/deserializing file")] SerdeError(#[from] crate::read_write_utils::ReadWriteError), + #[error("The file type with extension {ext:?} is not supported")] + UnsupportedFileType { ext: String }, + #[error("Unable to find file extension for path {0:?}")] + UnknownFileType(OsString), } #[derive(thiserror::Error, Debug)] diff --git a/src/lib.rs b/src/lib.rs index 537d3a03..bcf76206 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,7 +117,7 @@ mod secret; pub use secret::{Secret, SecretParserError}; mod inclusion_proof; -pub use inclusion_proof::{AggregationFactor, InclusionProof, InclusionProofError}; +pub use inclusion_proof::{AggregationFactor, InclusionProof, InclusionProofError, InclusionProofFileType}; mod entity; pub use entity::{Entity, EntityId, EntityIdsParser, EntityIdsParserError}; diff --git a/src/main.rs b/src/main.rs index dca33b83..d8efa368 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use dapol::{ cli::{BuildKindCommand, Cli, Command}, initialize_machine_parallelism, utils::{activate_logging, Consume, IfNoneThen, LogOnErr, LogOnErrUnwrap}, - AggregationFactor, DapolConfig, DapolConfigBuilder, DapolTree, EntityIdsParser, InclusionProof, + AggregationFactor, DapolConfig, DapolConfigBuilder, DapolTree, EntityIdsParser, InclusionProof, InclusionProofFileType, }; use patharg::InputArg; @@ -107,7 +107,7 @@ fn main() { .generate_inclusion_proof(&entity_id) .log_on_err_unwrap(); - proof.serialize(&entity_id, dir.clone()).log_on_err_unwrap(); + proof.serialize(&entity_id, dir.clone(), InclusionProofFileType::Json).log_on_err_unwrap(); } } @@ -130,6 +130,7 @@ fn main() { entity_ids, tree_file, range_proof_aggregation, + file_type, } => { let dapol_tree = DapolTree::deserialize( tree_file @@ -167,7 +168,7 @@ fn main() { .generate_inclusion_proof_with(&entity_id, aggregation_factor.clone()) .log_on_err_unwrap(); - proof.serialize(&entity_id, dir.clone()).log_on_err_unwrap(); + proof.serialize(&entity_id, dir.clone(), file_type.clone()).log_on_err_unwrap(); } } Command::VerifyInclusionProof { From acdf5a18c82d9ed465722c54163bd2d42067a675 Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 21:17:51 +0000 Subject: [PATCH 08/10] Changelog & version bump --- CHANGELOG.md | 4 ++++ Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffbf4dbe..7891e4d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## v0.3.1 (2024-01-20) + +- Minor updates to the CLI [PR 154](https://github.com/silversixpence-crypto/dapol/pull/154) + ## v0.3.0 (2024-01-20) - Adjust API to read better using DapolTree instead of Accumulator [36dd58f](https://github.com/silversixpence-crypto/dapol/commit/36dd58fcd9cd2100ac7a1c4a7010faab3397770f). Also included in this change: diff --git a/Cargo.toml b/Cargo.toml index 1cb65b2b..258ff1cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dapol" -version = "0.3.0" +version = "0.3.1" authors = ["Stenton Mayne "] edition = "2021" description = "DAPOL+ Proof of Liabilities protocol" From eea57b82c967fe42c569b6eed50ae1543ab1aecf Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 21:18:00 +0000 Subject: [PATCH 09/10] Minor fixes to prev changes --- README.md | 4 ++++ src/entity/entity_ids_parser.rs | 14 +++++--------- src/inclusion_proof.rs | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6617126d..82fdd62b 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,10 @@ As seen above, the proof generation can be done via the tree build command, but dapol -vvv gen-proofs --entity-ids ./examples/entities_example.csv --tree-file ``` +```bash +echo "david.martin@example.com" | dapol -vvv gen-proofs --tree-file examples/my_serialized_tree_for_testing.dapoltree --entitiy-ids - +``` + The proof generation command only offers 1 way to inject the tree (deserialization), as apposed to the tree build which offers different options. #### Proof verification diff --git a/src/entity/entity_ids_parser.rs b/src/entity/entity_ids_parser.rs index 6a335b5c..499be033 100644 --- a/src/entity/entity_ids_parser.rs +++ b/src/entity/entity_ids_parser.rs @@ -46,14 +46,12 @@ impl EntityIdsParser { /// - Parse the value as a string list using `serde_json` /// - An error is returned if: /// a) deserialization using `serde_json` fails + /// + /// If neither are set then an error is returned. pub fn parse(self) -> Result, EntityIdsParserError> { if let Some(path) = self.path { EntityIdsParser::parse_csv(path) } else if let Some(entity_ids_list) = self.entity_ids_list { - info!("list {:?}", entity_ids_list); - // let mut json_styled = "{".to_string(); - // json_styled.push_str(&entity_ids_list); - // json_styled.push_str("}"); EntityIdsParser::parse_list(entity_ids_list) } else { Err(EntityIdsParserError::NeitherPathNorListSet) @@ -61,21 +59,19 @@ impl EntityIdsParser { } fn parse_list(mut entity_ids_list: String) -> Result, EntityIdsParserError> { + // Remove trailing newline if it exists. if entity_ids_list.chars().nth_back(0).map_or(false, |c| c == '\n') { entity_ids_list.pop(); } - // let raw_vec: Vec = serde_json::from_str(entity_ids_json)?; + // Assume the input is a comma-separated list. let parts = entity_ids_list.split(','); - //let entity_ids = parts.collect::>(); - let mut entity_ids = Vec::::new();// = Vec::with_capacity(raw_vec.len()); + let mut entity_ids = Vec::::new(); for part in parts { entity_ids.push(EntityId::from_str(&part)?) } - info!("entity ids {:?}", entity_ids); - Ok(entity_ids) } diff --git a/src/inclusion_proof.rs b/src/inclusion_proof.rs index 1e642cf9..660a8de9 100644 --- a/src/inclusion_proof.rs +++ b/src/inclusion_proof.rs @@ -251,7 +251,8 @@ impl InclusionProof { /// /// An error is logged and returned if /// 1. The file cannot be opened. - /// 2. The [bincode] deserializer fails. + /// 2. The deserializer fails. + /// 3. The file extension is not supported. pub fn deserialize(file_path: PathBuf) -> Result { let ext = file_path.extension().and_then(|s| s.to_str()).ok_or( InclusionProofError::UnknownFileType(file_path.clone().into_os_string()), From fc09ba8a277962826eedc2c5529fca2772a91f1e Mon Sep 17 00:00:00 2001 From: Stent Date: Wed, 31 Jan 2024 21:21:46 +0000 Subject: [PATCH 10/10] Fix smol bug in benches --- benches/criterion_benches.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benches/criterion_benches.rs b/benches/criterion_benches.rs index b2f57b47..0cc7efae 100644 --- a/benches/criterion_benches.rs +++ b/benches/criterion_benches.rs @@ -15,7 +15,7 @@ use criterion::{criterion_group, criterion_main}; use criterion::{BenchmarkId, Criterion, SamplingMode}; use statistical::*; -use dapol::{DapolConfigBuilder, DapolTree, InclusionProof, Secret}; +use dapol::{DapolConfigBuilder, DapolTree, InclusionProof, Secret, InclusionProofFileType}; mod inputs; use inputs::{max_thread_counts_greater_than, num_entities_in_range, tree_heights_in_range}; @@ -292,7 +292,7 @@ pub fn bench_generate_proof(c: &mut Criterion) { std::fs::create_dir_all(dir.clone()).unwrap(); let path = proof .expect("Proof should be set") - .serialize(entity_id, dir) + .serialize(entity_id, dir, InclusionProofFileType::Binary) .unwrap(); let file_size = std::fs::metadata(path) .expect("Unable to get serialized tree metadata for {path}")