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

UP-42: Add API calls for frozen ledgers #2356

Merged
merged 12 commits into from
Feb 8, 2021
50 changes: 24 additions & 26 deletions cli/src/commands/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2045,20 +2045,19 @@ pub mod get_acceptance_mechanisms_command {
pub mod ledgers_freeze_command {
use super::*;

command!(CommandMetadata::build("ledgers-freeze", r#"Freeze all ledgers"#)
.add_required_param("ledgers_ids", "List ledgers for freeze.")
.add_example("ledger ledgers-freeze ledgers_ids=[1,2,3]")
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 ledgers_ids = get_str_param("ledgers_ids", params).map_err(error_err!())?;

let request = Ledger::build_ledgers_freeze_request(&submitter_did, ledgers_ids)
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);
Expand All @@ -2074,7 +2073,6 @@ pub mod ledgers_freeze_command {

pub mod get_frozen_ledgers_command {
use super::*;
use serde_json::Value;

command!(CommandMetadata::build("get-frozen-ledgers", r#"Get a list of frozen ledgers"#)
.add_example("ledger get-frozen-ledgers")
Expand All @@ -2090,38 +2088,38 @@ pub mod get_frozen_ledgers_command {
.map_err(|err| handle_indy_error(err, None, None, None))?;

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

// Flattering ap into vector
let result = result.as_object()
.expect("top level object is not a map")
.iter()
.map(|kv| {
let key = kv.0;
let value = kv.1;
let handle_response = handle_response.as_object()
.expect("top level object is not a map");

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

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

serde_json::to_value(&flat_value).unwrap()
}).collect::<Vec<Value>>();
result.push(serde_json::to_value(&flat_value)
.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!("Following Receipts has been received.");
println_succ!("Frozen ledgers has been received.");
print_list_table(&frozen_ledgers,
&[("ledger_id", "Ledger id"),
("ledger", "Payment Address of recipient"),
("state", "Amount"),
("seq_no", "Extra")],
"");
("ledger", "Ledger root hash"),
("state", "State root hash"),
("seq_no", "Last sequance number")],
"No frozen ledgers found.");

Ok(())
}
Expand Down Expand Up @@ -5176,7 +5174,7 @@ pub mod tests {
{
let cmd = ledgers_freeze_command::new();
let mut params = CommandParams::new();
params.insert("ledgers_ids", json!(vec![0, 1, 10, 23]).to_string());
params.insert("ledgers_ids", "0,1,10,237".to_string());
cmd.execute(&ctx, &params).unwrap_err();
}

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
2 changes: 1 addition & 1 deletion cli/src/libindy/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl Ledger {
ledger::append_request_endorser(request_json, endorser_did).wait()
}

pub fn build_ledgers_freeze_request(submitter_did: &str, ledgers_ids: &str) -> Result<String, IndyError> {
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()
}

Expand Down
6 changes: 3 additions & 3 deletions libindy/src/api/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1797,7 +1797,7 @@ pub extern fn indy_get_response_metadata(command_handle: CommandHandle,
/// #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 ids for freeze ledgers (json format).
/// ledgers_ids: list of ledgers IDs for freezing ledgers (json format).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
Expand All @@ -1806,7 +1806,7 @@ pub extern fn indy_get_response_metadata(command_handle: CommandHandle,
/// #Errors
/// Common*
#[no_mangle]
pub extern fn indy_build_ledgers_freeze_request (command_handle: CommandHandle,
pub extern fn indy_build_ledgers_freeze_request(command_handle: CommandHandle,
submitter_did: *const c_char,
ledgers_ids: *const c_char,
Toktar marked this conversation as resolved.
Show resolved Hide resolved
cb: Option<extern fn(command_handle_: CommandHandle,
Expand Down Expand Up @@ -1854,7 +1854,7 @@ pub extern fn indy_build_ledgers_freeze_request (command_handle: CommandHandle,
/// #Errors
/// Common*
#[no_mangle]
pub extern fn indy_build_get_frozen_ledgers_request (command_handle: CommandHandle,
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,
Expand Down
4 changes: 2 additions & 2 deletions libindy/src/domain/ledger/ledgers_freeze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ pub struct LedgersFreezeOperation {
impl LedgersFreezeOperation {
pub fn new(ledgers_ids: Vec<u64>) -> LedgersFreezeOperation {
LedgersFreezeOperation {
ledgers_ids,
_type: LEDGERS_FREEZE.to_string()
_type: LEDGERS_FREEZE.to_string(),
ledgers_ids
}
}
}
Expand Down
41 changes: 41 additions & 0 deletions libindy/src/services/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,47 @@ mod tests {
ledger_service.validate_action(&request).unwrap();
}

#[test]
fn build_ledgers_freeze_request_work_with_valid_data() {
let ledger_service = LedgerService::new();
let ledgers_ids = vec![0,1,50,873];
let res = ledger_service.build_ledgers_freeze_request(&identifier(), ledgers_ids);

match res {
Ok(_) => {},
Err(ec) => {
assert!(false, "build_ledgers_freeze_request_work_with_valid_data returned error_code {:?}", ec);
}
}
}

#[test]
fn build_get_frozen_ledgers_request_work_with_valid_data() {
let ledger_service = LedgerService::new();
let res = ledger_service.build_get_frozen_ledgers_request(&identifier());

match res {
Ok(_) => {},
Err(ec) => {
assert!(false, "build_get_frozen_ledgers_request_work_with_valid_data returned error_code {:?}", ec);
}
}
}

#[test]
fn build_ledgers_freeze_request_work_with_empty_data() {
let ledger_service = LedgerService::new();
let ledgers_ids = vec![];
let res = ledger_service.build_ledgers_freeze_request(&identifier(), ledgers_ids);

match res {
Ok(_) => {},
Err(ec) => {
assert!(false, "build_ledgers_freeze_request_work_with_empty_data returned error_code {:?}", ec);
}
}
}

mod auth_rule {
use super::*;

Expand Down
6 changes: 3 additions & 3 deletions libindy/tests/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ mod high_cases {

#[test]
fn indy_build_ledgers_freeze_request() {
let ledgers_ids = json!(vec![0u64, 1u64, 10u64, 23u64]);
let res = ledger::build_ledgers_freeze_request(DID_TRUSTEE, &ledgers_ids.to_string());
let ledgers_ids = vec![0u64, 1u64, 10u64, 23u64];
let res = ledger::build_ledgers_freeze_request(DID_TRUSTEE, ledgers_ids);

match res {
Ok(_) => {},
Expand All @@ -222,7 +222,7 @@ mod high_cases {
let res = ledger::get_frozen_ledgers_request(DID_TRUSTEE);

match res {
Ok(res) => {println!("{:?}",res)},
Ok(_) => {},
Err(ec) => {
assert!(false, "indy_get_frozen_ledgers_request returned error_code {:?}", ec);
}
Expand Down
2 changes: 1 addition & 1 deletion libindy/tests/utils/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ pub fn post_qualified_entities() -> (&'static str, &'static str) {
(SCHEMA_ID_V2, CRED_DEF_ID_V2)
}
}
pub fn build_ledgers_freeze_request(submitter_did: &str, ledgers_ids: &str) -> Result<String, IndyError> {
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()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.hyperledger.indy.sdk.pool.Pool;
import org.hyperledger.indy.sdk.wallet.Wallet;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
Expand Down Expand Up @@ -1789,13 +1790,13 @@ public static CompletableFuture<String> appendRequestEndorser(
*
* @param command_handle - command handle to map callback to caller context.
* @param submitter_did - (Optional) DID of the read request sender (if not provided then default Libindy DID will be used).
* @param ledgers_ids - list ids for freeze ledgers (json format).
* @param ledgers_ids - List of ledgers IDs for freezing.
* @param cb - Callback that takes command result as parameter.
*
* @return A future resolving to a request result as json.
* @throws IndyException Thrown if an error occurs when calling the underlying SDK.
*/
public static CompletableFuture<String> buildLedgersFreezeRequest(String submitterDid, String ledgersIds) throws IndyException {
public static CompletableFuture<String> buildLedgersFreezeRequest(String submitterDid, List<Integer> ledgersIds) throws IndyException {
ParamGuard.notNullOrWhiteSpace(submitterDid, "submitterDid");

CompletableFuture<String> future = new CompletableFuture<String>();
Expand All @@ -1804,7 +1805,7 @@ public static CompletableFuture<String> buildLedgersFreezeRequest(String submitt
int result = LibIndy.api.indy_build_ledgers_freeze_request(
commandHandle,
submitterDid,
ledgersIds,
ledgersIds.toString(),
buildRequestCb);

checkResult(future, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.junit.Test;
import org.junit.rules.Timeout;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

Expand All @@ -17,8 +17,6 @@ public class GetFrozenLedgersTest extends LedgerIntegrationTest {

@Test
public void TestBuildGetFrozenLedgersRequest() throws Exception {
DidResults.CreateAndStoreMyDidResult trusteeDidResult = Did.createAndStoreMyDid(wallet, TRUSTEE_IDENTITY_JSON).get();

DidResults.CreateAndStoreMyDidResult myDidResult = Did.createAndStoreMyDid(wallet, "{}").get();
String did = myDidResult.getDid();

Expand All @@ -35,27 +33,39 @@ public void TestBuildGetFrozenLedgersRequest() throws Exception {

@Test
public void TestLedgersFreezeRequest() throws Exception {
DidResults.CreateAndStoreMyDidResult trusteeDidResult = Did.createAndStoreMyDid(wallet, TRUSTEE_IDENTITY_JSON).get();

DidResults.CreateAndStoreMyDidResult myDidResult = Did.createAndStoreMyDid(wallet, "{}").get();
String did = myDidResult.getDid();

String ledgersIds = "[0,1,28,345]";
List<Integer> ledgersIds = Arrays.asList(0, 1, 28 ,345);
String request = Ledger.buildLedgersFreezeRequest(did, ledgersIds).get();

List<Integer> expe = new ArrayList<Integer>();
expe.add(0);
expe.add(1);
expe.add(28);
expe.add(345);

List<Integer> expectedLedgersIds = Arrays.asList(0, 1, 28 ,345);
JSONObject expectedResult = new JSONObject()
.put("operation", new JSONObject()
.put("type", "9")
.put("ledgers_ids", expe)
.put("ledgers_ids", expectedLedgersIds)
);

assert (new JSONObject(request).toMap().entrySet()
.containsAll(expectedResult.toMap().entrySet()));
}

@Test
public void TestLedgersFreezeRequestWithEmptyData() throws Exception {
DidResults.CreateAndStoreMyDidResult myDidResult = Did.createAndStoreMyDid(wallet, "{}").get();
String did = myDidResult.getDid();

List<Integer> ledgersIds = Arrays.asList();
String request = Ledger.buildLedgersFreezeRequest(did, ledgersIds).get();

List<Integer> expectedLedgersIds = Arrays.asList();
JSONObject expectedResult = new JSONObject()
.put("operation", new JSONObject()
.put("type", "9")
.put("ledgers_ids", expectedLedgersIds)
);

assert (new JSONObject(request).toMap().entrySet()
.containsAll(expectedResult.toMap().entrySet()));
}
}
9 changes: 5 additions & 4 deletions wrappers/python/indy/ledger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .libindy import do_call, create_cb

from typing import Optional
from typing import Optional, List
from ctypes import *

import logging
Expand Down Expand Up @@ -1840,13 +1840,13 @@ async def append_request_endorser(request_json: str,
return res


async def build_ledgers_freeze_request(submitter_did: str, ledgers_ids: str) -> str:
async def build_ledgers_freeze_request(submitter_did: str, ledgers_ids: List[int]) -> str:
"""
Request to freeze list of ledgers.

:param command_handle: command handle to map callback to caller context.
:param submitter_did: (Optional) DID of the read request sender (if not provided then default Libindy DID will be used).
:param ledgers_ids: list ids for freeze ledgers (json format).
:param ledgers_ids: List of ledgers IDs for freezing.
:param cb: Callback that takes command result as parameter.

:return: Request result as json.
Expand All @@ -1861,7 +1861,8 @@ async def build_ledgers_freeze_request(submitter_did: str, ledgers_ids: str) ->
build_ledgers_freeze_request.cb = create_cb(CFUNCTYPE(None, c_int32, c_int32, c_char_p))

c_submitter_did = c_char_p(submitter_did.encode('utf-8'))
c_ledgers_ids = c_char_p(ledgers_ids.encode('utf-8'))
json_ledgers_ids = '[' + ','.join(str(e) for e in ledgers_ids) + ']'
c_ledgers_ids = c_char_p(json_ledgers_ids.encode('utf-8'))

request_json = await do_call('indy_build_ledgers_freeze_request',
c_submitter_did,
Expand Down
Loading