Skip to content

Commit

Permalink
Merge pull request #200 from andrewwhitehead/upd/bls-signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewwhitehead authored Aug 9, 2023
2 parents 06082b8 + c720238 commit c246ef8
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 925 deletions.
9 changes: 2 additions & 7 deletions libindy_vdr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ default = ["ffi", "log", "zmq_vendored"]
# This is added so we can lock the version that zmq uses
# 0.1.49 is broken for ios targets
cmake = { version = "=0.1.48", optional = true }
base64_rs = { package = "base64", version = "0.21" }
base64 = "0.21"
bs58 = "0.5"
etcommon-rlp = "0.2.4"
env_logger = { version = "0.10", optional = true }
Expand All @@ -39,7 +39,7 @@ futures-channel = "0.3"
futures-executor = "0.3"
futures-util = "0.3"
hex = "0.4"
hex-literal = "0.4"
indy-blssignatures = "0.1"
indy-data-types = { version = "0.6.1", default-features = false, features = [
"anoncreds",
"merkle_tree",
Expand All @@ -63,11 +63,6 @@ time = { version = "=0.3.20", features = ["parsing"] }
url = "2.2.2"
zmq = "0.9"

[dependencies.ursa]
version = "0.3.5"
default-features = false
features = ["bls_bn254"]

[dev-dependencies]
rstest = "0.18"
time = "0.3"
Expand Down
16 changes: 8 additions & 8 deletions libindy_vdr/src/config/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use hex_literal::hex;
use indy_blssignatures::Generator;
use once_cell::sync::Lazy;
use ursa::bls::Generator;

use crate::pool::ProtocolVersion;

Expand All @@ -14,12 +13,13 @@ pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::Node1_4;

pub static DEFAULT_GENERATOR: Lazy<Generator> = Lazy::new(|| {
Generator::from_bytes(
&hex!(
"16cb6e1f1b7803f30ab2c661196fe199af17d8ed193d98a3d0fa17638a3a1b831df541918f0e5acd
0576998bfdb839318349b8acbb4106fe93e6a3d35a3f008107e2c4a7c9a5049f2cc9f9d7ced5049f
4336f67843c5dc32ad940e397e252df7176a8f76fd15d536bc8d294ac7040f6cc8d560dad13de88c
3dfa7260ec363452"
)[..],
&hex::decode(
"16cb6e1f1b7803f30ab2c661196fe199af17d8ed193d98a3d0fa17638a3a1b831df541918f0e5acd\
0576998bfdb839318349b8acbb4106fe93e6a3d35a3f008107e2c4a7c9a5049f2cc9f9d7ced5049f\
4336f67843c5dc32ad940e397e252df7176a8f76fd15d536bc8d294ac7040f6cc8d560dad13de88c\
3dfa7260ec363452",
)
.unwrap(),
)
.unwrap()
});
2 changes: 1 addition & 1 deletion libindy_vdr/src/pool/builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::genesis::PoolTransactions;
use super::manager::{LocalPool, SharedPool};
use super::networker::{MakeLocal, MakeShared, ZMQNetworkerFactory};
use super::pool::{LocalPool, SharedPool};
use super::runner::PoolRunner;

use crate::common::error::prelude::*;
Expand Down
15 changes: 15 additions & 0 deletions libindy_vdr/src/pool/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,18 @@ pub(crate) fn build_pool_catchup_request(
};
Ok(Message::CatchupReq(cr))
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn min_consensus_works() {
assert_eq!(min_consensus(0), 0);
assert_eq!(min_consensus(3), 0);
assert_eq!(min_consensus(4), 1);
assert_eq!(min_consensus(5), 1);
assert_eq!(min_consensus(6), 1);
assert_eq!(min_consensus(7), 2);
}
}
2 changes: 1 addition & 1 deletion libindy_vdr/src/pool/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::handlers::{
build_pool_catchup_request, build_pool_status_request, handle_catchup_request,
handle_consensus_request, handle_full_request, handle_status_request, CatchupTarget,
};
use super::pool::Pool;
use super::manager::Pool;
use super::requests::{PreparedRequest, RequestMethod};
use super::types::{NodeReplies, RequestResult, TimingResult};

Expand Down
212 changes: 212 additions & 0 deletions libindy_vdr/src/pool/manager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
extern crate rand;
extern crate rmp_serde;

use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;

use futures_channel::mpsc::unbounded;
use futures_util::future::{lazy, FutureExt, LocalBoxFuture};
use rand::seq::SliceRandom;

use super::genesis::{build_node_transaction_map, build_verifiers, PoolTransactions};
use super::networker::{
LocalNetworker, Networker, NetworkerEvent, NetworkerFactory, SharedNetworker,
};
use super::requests::{PoolRequest, PoolRequestImpl};
use super::types::{PoolSetup, RequestHandle, Verifiers};

use crate::common::error::prelude::*;
use crate::common::merkle_tree::MerkleTree;
use crate::config::PoolConfig;
use crate::ledger::RequestBuilder;
use crate::utils::base58;

/// A generic verifier pool with support for creating pool transaction requests
pub trait Pool: Clone {
type Request: PoolRequest;

/// Get the pool configuration for this instance
fn get_config(&self) -> &PoolConfig;

/// Create a new pool request instance
fn create_request(
&self,
req_id: String,
req_json: String,
) -> LocalBoxFuture<'_, VdrResult<Self::Request>>;

/// Get the merkle tree representing the verifier pool transactions
fn get_merkle_tree(&self) -> &MerkleTree;

/// A sequence of verifier node aliases
fn get_node_aliases(&self) -> Vec<String>;

/// Get the size and root of the pool transactions merkle tree
fn get_merkle_tree_info(&self) -> (String, usize) {
let tree = self.get_merkle_tree();
(base58::encode(tree.root_hash()), tree.count())
}

/// Get a request builder corresponding to this verifier pool
fn get_request_builder(&self) -> RequestBuilder {
RequestBuilder::new(self.get_config().protocol_version)
}

/// Get the set of verifier pool transactions in JSON format
fn get_json_transactions(&self) -> VdrResult<Vec<String>> {
PoolTransactions::from(self.get_merkle_tree()).encode_json()
}

/// Get the summarized verifier details.
fn get_verifier_info(&self) -> VdrResult<Verifiers>;
}

/// The default `Pool` implementation
#[derive(Clone)]
pub struct PoolImpl<S: AsRef<PoolSetup> + Clone, T: Networker + Clone> {
setup: S,
networker: T,
}

/// A verifier pool instance restricted to a single thread
pub type LocalPool = PoolImpl<Rc<PoolSetup>, LocalNetworker>;

/// A verifier pool instance which can be shared between threads
pub type SharedPool = PoolImpl<Arc<PoolSetup>, SharedNetworker>;

impl<S, T> PoolImpl<S, T>
where
S: AsRef<PoolSetup> + Clone + From<Box<PoolSetup>>,
T: Networker + Clone,
{
pub(crate) fn new(setup: S, networker: T) -> Self {
Self { setup, networker }
}

/// Build a new verifier pool instance
pub fn build<F>(
config: PoolConfig,
merkle_tree: MerkleTree,
networker_factory: F,
node_weights: Option<HashMap<String, f32>>,
) -> VdrResult<Self>
where
F: NetworkerFactory<Output = T>,
{
let txn_map = build_node_transaction_map(&merkle_tree, config.protocol_version)?;
let verifiers = build_verifiers(txn_map)?;
let networker = networker_factory.make_networker(config.clone(), &verifiers)?;
let setup = PoolSetup::new(config, merkle_tree, node_weights, verifiers);
Ok(Self::new(S::from(Box::new(setup)), networker))
}
}

impl<S, T> Pool for PoolImpl<S, T>
where
S: AsRef<PoolSetup> + Clone,
T: Networker + Clone,
{
type Request = PoolRequestImpl<S, T>;

fn create_request(
&self,
req_id: String,
req_json: String,
) -> LocalBoxFuture<'_, VdrResult<Self::Request>> {
let setup = self.setup.clone();
let networker = self.networker.clone();
lazy(move |_| {
let (tx, rx) = unbounded();
let handle = RequestHandle::next();
let setup_ref = setup.as_ref();
let node_order = choose_nodes(&setup_ref.verifiers, setup_ref.node_weights.as_ref());
debug!(
"New {}: reqId({}), node order: {:?}",
handle, req_id, node_order
);
networker.send(NetworkerEvent::NewRequest(handle, req_id, req_json, tx))?;
Ok(PoolRequestImpl::new(
handle, rx, setup, networker, node_order,
))
})
.boxed_local()
}

fn get_config(&self) -> &PoolConfig {
&self.setup.as_ref().config
}

fn get_merkle_tree(&self) -> &MerkleTree {
&self.setup.as_ref().merkle_tree
}

fn get_node_aliases(&self) -> Vec<String> {
self.setup.as_ref().verifiers.keys().cloned().collect()
}

fn get_verifier_info(&self) -> VdrResult<Verifiers> {
Ok(self.setup.as_ref().verifiers.clone())
}
}

pub(crate) fn choose_nodes(
verifiers: &Verifiers,
weights: Option<&HashMap<String, f32>>,
) -> Vec<String> {
let mut weighted = verifiers
.keys()
.filter_map(|name| {
let weight = weights
.as_ref()
.and_then(|w| w.get(name))
.copied()
.unwrap_or(1.0);
if weight <= 0.0 {
None
} else {
Some((weight, name.as_str()))
}
})
.collect::<Vec<(f32, &str)>>();
let mut rng = rand::thread_rng();
let mut result = vec![];
for _ in 0..weighted.len() {
let found = weighted
.choose_weighted_mut(&mut rng, |item| item.0)
.unwrap();
found.0 = 0.0;
result.push(found.1.to_string());
}
result
}

#[cfg(test)]
mod tests {
use std::collections::HashMap;

use crate::pool::{VerifierInfo, Verifiers};

use super::*;

#[test]
fn test_choose_nodes() {
let test_verif = VerifierInfo {
client_addr: "127.0.0.1".into(),
node_addr: "127.0.0.1".into(),
public_key: "pk".into(),
enc_key: "ek".into(),
bls_key: None,
};
let mut verifiers = Verifiers::new();
verifiers.insert("a".into(), test_verif.clone());
verifiers.insert("b".into(), test_verif.clone());
verifiers.insert("c".into(), test_verif);

let mut weights = HashMap::new();
weights.insert("a".into(), 0.0);
weights.insert("b".into(), 0.000001);
let found = choose_nodes(&verifiers, Some(&weights));
assert_eq!(found, ["c", "b"]);
}
}
6 changes: 3 additions & 3 deletions libindy_vdr/src/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ mod genesis;
pub(crate) mod handlers;
/// Methods for performing requests against the verifier pool
pub mod helpers;
/// General verifier pool management
mod manager;
/// Pool networker traits and implementations
pub mod networker;
/// General verifier pool management
mod pool;
/// Data types and traits for handling pending verifier pool requests
mod requests;
/// A pool executor that processes events in its own thread
Expand All @@ -16,7 +16,7 @@ mod types;

pub use self::builder::PoolBuilder;
pub use self::genesis::PoolTransactions;
pub use self::pool::{LocalPool, Pool, PoolImpl, SharedPool};
pub use self::manager::{LocalPool, Pool, PoolImpl, SharedPool};
pub use self::requests::{
new_request_id, PoolRequest, PoolRequestImpl, PreparedRequest, RequestMethod,
};
Expand Down
Loading

0 comments on commit c246ef8

Please sign in to comment.