Skip to content

Commit

Permalink
Merge pull request hyperledger-indy#1431 from KitHat/freshness
Browse files Browse the repository at this point in the history
IS-954 added freshness threshold
  • Loading branch information
jovfer authored Jan 29, 2019
2 parents 068f6e5 + 17c9f60 commit 8abfac3
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 82 deletions.
10 changes: 8 additions & 2 deletions libindy/src/commands/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use domain::ledger::node::NodeOperationData;
use errors::prelude::*;
use services::crypto::CryptoService;
use services::ledger::LedgerService;
use services::pool::PoolService;
use services::pool::{
PoolService,
parse_response_metadata
};
use services::wallet::{RecordOptions, WalletService};
use utils::crypto::base58;
use utils::crypto::signature_serializer::serialize_signature;
Expand Down Expand Up @@ -877,7 +880,10 @@ impl LedgerCommandExecutor {
response: &str) -> IndyResult<String> {
debug!("get_response_metadata >>> response: {:?}", response);

let res = self.ledger_service.get_response_metadata(response)?;
let metadata = parse_response_metadata(response)?;

let res = serde_json::to_string(&metadata)
.to_indy(IndyErrorKind::InvalidState, "Cannot serialize ResponseMetadata")?;

debug!("get_response_metadata <<< res: {:?}", res);

Expand Down
5 changes: 4 additions & 1 deletion libindy/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use services::blob_storage::BlobStorageService;
use services::crypto::CryptoService;
use services::ledger::LedgerService;
use services::payments::PaymentsService;
use services::pool::PoolService;
use services::pool::{PoolService, set_freshness_threshold};
use services::wallet::WalletService;

use self::threadpool::ThreadPool;
Expand Down Expand Up @@ -67,6 +67,9 @@ pub fn indy_set_runtime_config(config: IndyConfig) {
Some(false) => env::set_var("RUST_BACKTRACE", "0"),
_ => {}
}
if let Some(threshold) = config.freshness_threshold {
set_freshness_threshold(threshold);
}
}

pub struct CommandExecutor {
Expand Down
3 changes: 2 additions & 1 deletion libindy/src/domain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub mod wallet;
#[derive(Debug, Serialize, Deserialize)]
pub struct IndyConfig {
pub crypto_thread_pool_size : Option<usize>,
pub collect_backtrace: Option<bool>
pub collect_backtrace: Option<bool>,
pub freshness_threshold: Option<u64>
}
49 changes: 1 addition & 48 deletions libindy/src/services/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use domain::ledger::node::{NodeOperation, NodeOperationData};
use domain::ledger::nym::GetNymOperation;
use domain::ledger::pool::{PoolConfigOperation, PoolRestartOperation, PoolUpgradeOperation};
use domain::ledger::request::Request;
use domain::ledger::response::{Message, Reply, ReplyType, ResponseMetadata};
use domain::ledger::response::{Message, Reply, ReplyType};
use domain::ledger::rev_reg::{GetRevocRegDeltaReplyResult, GetRevocRegReplyResult, GetRevRegDeltaOperation, GetRevRegOperation, RevRegEntryOperation};
use domain::ledger::rev_reg_def::{GetRevocRegDefReplyResult, GetRevRegDefOperation, RevRegDefOperation};
use domain::ledger::schema::{GetSchemaOperation, GetSchemaOperationData, GetSchemaReplyResult, SchemaOperation, SchemaOperationData};
Expand Down Expand Up @@ -548,47 +548,6 @@ impl LedgerService {
Ok(res)
}

pub fn get_response_metadata(&self, response: &str) -> IndyResult<String> {
info!("get_response_metadata >>> response: {:?}", response);

let message: Message<serde_json::Value> = serde_json::from_str(response)
.to_indy(IndyErrorKind::InvalidTransaction, "Cannot deserialize transaction Response")?;

let response_object: Reply<serde_json::Value> = LedgerService::handle_response_message_type(message)?;
let response_result = response_object.result();

let response_metadata = match response_result["ver"].as_str() {
None => LedgerService::parse_transaction_metadata_v0(&response_result),
Some("1") => LedgerService::parse_transaction_metadata_v1(&response_result),
ver @ _ => return Err(err_msg(IndyErrorKind::InvalidTransaction, format!("Unsupported transaction response version: {:?}", ver)))
};

let res = serde_json::to_string(&response_metadata)
.to_indy(IndyErrorKind::InvalidState, "Cannot serialize ResponseMetadata")?;

info!("get_response_metadata <<< res: {:?}", res);

Ok(res)
}

fn parse_transaction_metadata_v0(message: &serde_json::Value) -> ResponseMetadata {
ResponseMetadata {
seq_no: message["seqNo"].as_u64(),
txn_time: message["txnTime"].as_u64(),
last_txn_time: message["state_proof"]["multi_signature"]["value"]["timestamp"].as_u64(),
last_seq_no: None,
}
}

fn parse_transaction_metadata_v1(message: &serde_json::Value) -> ResponseMetadata {
ResponseMetadata {
seq_no: message["txnMetadata"]["seqNo"].as_u64(),
txn_time: message["txnMetadata"]["txnTime"].as_u64(),
last_txn_time: message["multiSignature"]["signedState"]["stateMetadata"]["timestamp"].as_u64(),
last_seq_no: None,
}
}

pub fn parse_response<T>(response: &str) -> IndyResult<Reply<T>> where T: DeserializeOwned + ReplyType + ::std::fmt::Debug {
trace!("parse_response >>> response {:?}", response);

Expand All @@ -602,12 +561,6 @@ impl LedgerService {
let message: Message<T> = serde_json::from_value(message)
.to_indy(IndyErrorKind::LedgerItemNotFound, "Structure doesn't correspond to type. Most probably not found")?; // FIXME: Review how we handle not found

LedgerService::handle_response_message_type(message)
}

fn handle_response_message_type<T>(message: Message<T>) -> IndyResult<Reply<T>> where T: DeserializeOwned + ::std::fmt::Debug {
trace!("handle_response_message_type >>> message {:?}", message);

match message {
Message::Reject(response) | Message::ReqNACK(response) =>
Err(err_msg(IndyErrorKind::InvalidTransaction, format!("Transaction has been failed: {:?}", response.reason))),
Expand Down
78 changes: 73 additions & 5 deletions libindy/src/services/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,32 @@ extern crate sha2;
extern crate time;
extern crate zmq;

use self::byteorder::{ByteOrder, LittleEndian};
use self::zmq::Socket;

use std::{fs, io};
use std::cell::RefCell;
use std::collections::HashMap;
use std::io::Write;
use std::sync::Mutex;

use serde_json;
use serde::de::DeserializeOwned;

use api::ledger::{CustomFree, CustomTransactionParser};
use domain::pool::{PoolConfig, PoolOpenConfig};
use errors::prelude::*;
use domain::{
pool::{PoolConfig, PoolOpenConfig},
ledger::response::{
Message,
Reply,
ResponseMetadata
}
};
use errors::*;
use services::pool::pool::{Pool, ZMQPool};
use utils::environment;
use utils::sequence;

use self::byteorder::{ByteOrder, LittleEndian};
use self::zmq::Socket;

mod catchup;
mod commander;
mod events;
Expand Down Expand Up @@ -256,6 +264,66 @@ impl PoolService {
}
}

lazy_static! {
static ref THRESHOLD: Mutex<u64> = Mutex::new(600);
}

pub fn set_freshness_threshold(threshold: u64) {
let mut th = THRESHOLD.lock().unwrap();
*th = ::std::cmp::max(threshold, 300);
}


pub fn parse_response_metadata(response: &str) -> IndyResult<ResponseMetadata> {
let message: Message<serde_json::Value> = serde_json::from_str(response)
.to_indy(IndyErrorKind::InvalidTransaction, "Cannot deserialize transaction Response")?;

let response_object: Reply<serde_json::Value> = _handle_response_message_type(message)?;
let response_result = response_object.result();

let response_metadata = match response_result["ver"].as_str() {
None => _parse_transaction_metadata_v0(&response_result),
Some("1") => _parse_transaction_metadata_v1(&response_result),
ver @ _ => return Err(err_msg(IndyErrorKind::InvalidTransaction, format!("Unsupported transaction response version: {:?}", ver)))
};

Ok(response_metadata)
}

pub fn get_last_signed_time(response: &str) -> Option<u64> {
let c = parse_response_metadata(response);
c.ok().and_then(|resp| resp.last_txn_time)
}

fn _handle_response_message_type<T>(message: Message<T>) -> IndyResult<Reply<T>> where T: DeserializeOwned + ::std::fmt::Debug {
trace!("handle_response_message_type >>> message {:?}", message);

match message {
Message::Reject(response) | Message::ReqNACK(response) =>
Err(err_msg(IndyErrorKind::InvalidTransaction, format!("Transaction has been failed: {:?}", response.reason))),
Message::Reply(reply) =>
Ok(reply)
}
}

fn _parse_transaction_metadata_v0(message: &serde_json::Value) -> ResponseMetadata {
ResponseMetadata {
seq_no: message["seqNo"].as_u64(),
txn_time: message["txnTime"].as_u64(),
last_txn_time: message["state_proof"]["multi_signature"]["value"]["timestamp"].as_u64(),
last_seq_no: None,
}
}

fn _parse_transaction_metadata_v1(message: &serde_json::Value) -> ResponseMetadata {
ResponseMetadata {
seq_no: message["txnMetadata"]["seqNo"].as_u64(),
txn_time: message["txnMetadata"]["txnTime"].as_u64(),
last_txn_time: message["multiSignature"]["signedState"]["stateMetadata"]["timestamp"].as_u64(),
last_seq_no: None,
}
}

#[cfg(test)]
mod tests {
use std::thread;
Expand Down
Loading

0 comments on commit 8abfac3

Please sign in to comment.