Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2356 from adenishchenko/frozen_ledgers
Browse files Browse the repository at this point in the history
UP-42: Add API calls for frozen ledgers
  • Loading branch information
Toktar authored Feb 8, 2021
2 parents 03f5482 + d1c6bf5 commit 8c669cf
Show file tree
Hide file tree
Showing 26 changed files with 926 additions and 11 deletions.
116 changes: 116 additions & 0 deletions cli/src/commands/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,89 @@ pub mod get_acceptance_mechanisms_command {
}
}

pub mod ledgers_freeze_command {
use super::*;

command!(CommandMetadata::build("ledgers-freeze", r#"Freeze ledgers"#)
.add_required_param("ledgers_ids", "List of ledgers IDs for freezing.")
.add_example("ledger ledgers-freeze ledgers_ids=1,2,3")
.finalize()
);

fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
trace!("execute >> ctx {:?} params {:?}", ctx, params);
let ledgers_ids = get_number_tuple_array_param("ledgers_ids", params);
let submitter_did = ensure_active_did(&ctx)?;
let (wallet_handle, wallet_name) = ensure_opened_wallet(&ctx)?;

let request = Ledger::build_ledgers_freeze_request(&submitter_did, ledgers_ids?)
.map_err(|err| handle_indy_error(err, None, None, None))?;

let (_, response) = send_write_request!(&ctx, params, &request, wallet_handle, &wallet_name, &submitter_did);

let result = handle_transaction_response(response)?;

println!("result {:?}", result);

trace!("execute <<");
Ok(())
}
}

pub mod get_frozen_ledgers_command {
use super::*;

command!(CommandMetadata::build("get-frozen-ledgers", r#"Get a list of frozen ledgers"#)
.add_example("ledger get-frozen-ledgers")
.finalize()
);

fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
trace!("execute >> ctx {:?} params {:?}", ctx, params);

let submitter_did = ensure_active_did(&ctx)?;

let request = Ledger::build_get_frozen_ledgers_request(&submitter_did)
.map_err(|err| handle_indy_error(err, None, None, None))?;

let (_, response) = send_read_request!(&ctx, params, &request, Some(&submitter_did));
let handle_response = handle_transaction_response(response)?;

// Flattering ap into vector
let handle_response = handle_response.as_object()
.expect("top level object is not a map");

let mut result = Vec::new();
for (response_ledger_key, response_ledger_value) in handle_response {
let mut ledger_info = response_ledger_value.as_object()
.expect("inner object is not a map").clone();

let ledger_id = serde_json::to_value(&response_ledger_key)
.map_err(|_| println_err!("Invalid format of Outputs: Ledger ID is incorrect."))?;
ledger_info.insert("ledger_id".to_owned(), ledger_id);

result.push(serde_json::to_value(&ledger_info)
.map_err(|_| println_err!("Invalid format of Outputs: result is incorrect."))?);
}

print_frozen_ledgers(result)?;
trace!("execute <<");
Ok(())
}

fn print_frozen_ledgers(frozen_ledgers: Vec<serde_json::Value>) -> Result<(), ()> {
println_succ!("Frozen ledgers has been received.");
print_list_table(&frozen_ledgers,
&[("ledger_id", "Ledger id"),
("ledger", "Ledger root hash"),
("state", "State root hash"),
("seq_no", "Last sequance number")],
"No frozen ledgers found.");

Ok(())
}
}

pub fn set_author_agreement(ctx: &CommandContext, request: &mut String) -> Result<(), ()> {
if let Some((text, version, acc_mech_type, time_of_acceptance)) = get_transaction_author_info(&ctx) {
if acc_mech_type.is_empty() {
Expand Down Expand Up @@ -2251,6 +2334,8 @@ fn get_txn_title(role: &serde_json::Value) -> serde_json::Value {
Some("5") => "TXN_AUTHR_AGRMT_AML",
Some("6") => "GET_TXN_AUTHR_AGRMT",
Some("7") => "GET_TXN_AUTHR_AGRMT_AML",
Some("9") => "LEDGERS_FREEZE",
Some("10") => "GET_FROZEN_LEDGERS",
Some("100") => "ATTRIB",
Some("101") => "SCHEMA",
Some("104") => "GET_ATTR",
Expand Down Expand Up @@ -5079,6 +5164,37 @@ pub mod tests {
}
}

mod frozen_ledgers {
use super::*;

#[test]
pub fn ledgers_freeze() {
let ctx = setup();

{
let cmd = ledgers_freeze_command::new();
let mut params = CommandParams::new();
params.insert("ledgers_ids", "0,1,10,237".to_string());
cmd.execute(&ctx, &params).unwrap_err();
}

tear_down();
}

#[test]
pub fn get_frozen_ledgers() {
let ctx = setup();

{
let cmd = get_frozen_ledgers_command::new();
let params = CommandParams::new();
cmd.execute(&ctx, &params).unwrap_err();
}

tear_down();
}
}

fn _path() -> (::std::path::PathBuf, String) {
let mut path = crate::utils::environment::EnvironmentUtils::indy_home_path();
path.push("transaction");
Expand Down
24 changes: 24 additions & 0 deletions cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,30 @@ pub fn get_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -
}
}

pub fn get_number_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<u64>, ()> {
match params.get(name) {
Some(v) if !v.is_empty() => {
let tuples: Vec<&str> = v.split(",").collect();
if tuples.is_empty() {
println_err!("Parameter \"{}\" has invalid format", name);
Err(())
} else {
let mut result: Vec<u64> = Vec::new();
for item in tuples {
println!("{:?}",item);
result.push(item.parse::<u64>().map_err(|err|
println_err!("Can't parse number parameter \"{}\": value: \"{}\", err \"{}\"", name, item, err))?);
}
Ok(result)
}
}
_ => {
println_err!("No required \"{}\" parameter present", name);
Err(())
}
}
}

pub fn get_opt_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<String>>, ()> {
match params.get(name) {
Some(v) =>
Expand Down
8 changes: 8 additions & 0 deletions cli/src/libindy/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,12 @@ impl Ledger {
endorser_did: &str) -> Result<String, IndyError> {
ledger::append_request_endorser(request_json, endorser_did).wait()
}

pub fn build_ledgers_freeze_request(submitter_did: &str, ledgers_ids: Vec<u64>) -> Result<String, IndyError> {
ledger::build_ledgers_freeze_request(submitter_did, ledgers_ids).wait()
}

pub fn build_get_frozen_ledgers_request(submitter_did: &str) -> Result<String, IndyError> {
ledger::build_get_frozen_ledgers_request(submitter_did).wait()
}
}
2 changes: 2 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ fn build_executor() -> CommandExecutor {
.add_command(ledger::get_acceptance_mechanisms_command::new())
.add_command(ledger::endorse_transaction_command::new())
.add_command(ledger::taa_disable_all_command::new())
.add_command(ledger::ledgers_freeze_command::new())
.add_command(ledger::get_frozen_ledgers_command::new())
.finalize_group()
.add_group(payment_address::group::new())
.add_command(payment_address::new_command::new())
Expand Down
51 changes: 51 additions & 0 deletions libindy/include/indy_ledger.h
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,57 @@ extern "C" {
const char* request_json)
);

/// Builds a LEDGERS_FREEZE request. Request to freeze list of ledgers.
///
/// #Params
/// command_handle: command handle to map callback to caller context.
/// submitter_did: (Optional) DID of the read request sender (if not provided then default Libindy DID will be used).
/// ledgers_ids: list of ledgers IDs for freezing ledgers (json format).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Request result as json.
///
/// #Errors
/// Common*
extern indy_error_t indy_build_ledgers_freeze_request(indy_handle_t command_handle,
const char * submitter_did,
const char * ledgers_ids,

void (*cb)(indy_handle_t command_handle_,
indy_error_t err,
const char* request_json)
);

/// Builds a GET_FROZEN_LEDGERS request. Request to get list of frozen ledgers.
/// frozen ledgers are defined by LEDGERS_FREEZE request.
///
/// #Params
/// command_handle: command handle to map callback to caller context.
/// submitter_did: (Optional) DID of the read request sender (if not provided then default Libindy DID will be used).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Request result as json.
/// {
/// <ledger_id>: {
/// "ledger": String - Ledger root hash,
/// "state": String - State root hash,
/// "seq_no": u64 - the latest transaction seqNo for particular Node,
/// },
/// ...
/// }
///
/// #Errors
/// Common*
extern indy_error_t indy_build_get_frozen_ledgers_request(indy_handle_t command_handle,
const char * submitter_did,

void (*cb)(indy_handle_t command_handle_,
indy_error_t err,
const char* request_json)
);

/// Builds a GET_TXN_AUTHR_AGRMT_AML request. Request to get a list of acceptance mechanisms from the ledger
/// valid for specified time or the latest one.
///
Expand Down
85 changes: 85 additions & 0 deletions libindy/src/api/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1792,6 +1792,91 @@ pub extern fn indy_get_response_metadata(command_handle: CommandHandle,
res
}

/// Builds a LEDGERS_FREEZE request. Request to freeze list of ledgers.
///
/// #Params
/// command_handle: command handle to map callback to caller context.
/// submitter_did: (Optional) DID of the read request sender (if not provided then default Libindy DID will be used).
/// ledgers_ids: list of ledgers IDs for freezing ledgers (json format).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Request result as json.
///
/// #Errors
/// Common*
#[no_mangle]
pub extern fn indy_build_ledgers_freeze_request(command_handle: CommandHandle,
submitter_did: *const c_char,
ledgers_ids: *const c_char,
cb: Option<extern fn(command_handle_: CommandHandle,
err: ErrorCode,
request_json: *const c_char)>) -> ErrorCode {
trace!("indy_build_ledgers_freeze_request: entities >>> submitter_did: {:?}, ledgers_ids: {:?}", submitter_did, ledgers_ids);

check_useful_validatable_string!(submitter_did, ErrorCode::CommonInvalidParam2, DidValue);
check_useful_json!(ledgers_ids, ErrorCode::CommonInvalidParam3, Vec<u64>);
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam4);

let result = CommandExecutor::instance()
.send(Command::Ledger(LedgerCommand::BuildLedgersFreezeRequest(
submitter_did,
ledgers_ids,
boxed_callback_string!("indy_build_ledgers_freeze_request", cb, command_handle)
)));

let res = prepare_result!(result);

trace!("indy_build_ledgers_freeze_request: <<< res: {:?}", res);

res
}

/// Builds a GET_FROZEN_LEDGERS request. Request to get list of frozen ledgers.
/// frozen ledgers are defined by LEDGERS_FREEZE request.
///
/// #Params
/// command_handle: command handle to map callback to caller context.
/// submitter_did: (Optional) DID of the read request sender (if not provided then default Libindy DID will be used).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Request result as json.
/// {
/// <ledger_id>: {
/// "ledger": String - Ledger root hash,
/// "state": String - State root hash,
/// "seq_no": u64 - the latest transaction seqNo for particular Node,
/// },
/// ...
/// }
///
/// #Errors
/// Common*
#[no_mangle]
pub extern fn indy_build_get_frozen_ledgers_request(command_handle: CommandHandle,
submitter_did: *const c_char,
cb: Option<extern fn(command_handle_: CommandHandle,
err: ErrorCode,
request_json: *const c_char)>) -> ErrorCode {
trace!("indy_build_get_frozen_ledgers_request: entities >>> submitter_did: {:?}", submitter_did);

check_useful_validatable_string!(submitter_did, ErrorCode::CommonInvalidParam2, DidValue);
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam3);

let result = CommandExecutor::instance()
.send(Command::Ledger(LedgerCommand::BuildGetFrozenLedgersRequest(
submitter_did,
boxed_callback_string!("indy_build_get_frozen_ledgers_request", cb, command_handle)
)));

let res = prepare_result!(result);

trace!("indy_build_get_frozen_ledgers_request: <<< res: {:?}", res);

res
}

/// Builds a AUTH_RULE request. Request to change authentication rules for a ledger transaction.
///
/// #Params
Expand Down
Loading

0 comments on commit 8c669cf

Please sign in to comment.