def add_revoc_def_by_demand(create_node_and_not_start, looper, sdk_wallet_steward): node = create_node_and_not_start data = { "id": randomString(50), "type": REVOC_REG_DEF, "tag": randomString(5), "credDefId": randomString(50), "value":{ "issuanceType": ISSUANCE_ON_DEMAND, "maxCredNum": 1000000, "tailsHash": randomString(50), "tailsLocation": 'http://tails.location.com', "publicKeys": {}, } } req = sdk_sign_request_from_dict(looper, sdk_wallet_steward, data) req_handler = node.getDomainReqHandler() req_handler.validate(Request(**req)) txn = reqToTxn(Request(**req)) txn[f.SEQ_NO.nm] = node.domainLedger.seqNo + 1 txn[TXN_TIME] = int(time.time()) req_handler._addRevocDef(txn) return req
def test_no_state_proofs_if_protocol_version_less(write_manager, read_manager, db_manager): nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' role = "2" verkey = "~7TYfekw4GUagBnBVCqPjiC" identifier = "6ouriXMZkLeHsuXrN1X1fd" seq_no = 0 txn_time = int(time.time()) # Adding nym data = { TARGET_NYM: nym, ROLE: role, VERKEY: verkey, } txn = append_txn_metadata(reqToTxn( Request(operation=data, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=identifier)), seq_no=seq_no, txn_time=txn_time) txn = set_type(txn, NYM) txn = append_payload_metadata(txn, frm=nym) write_manager.update_state(txn) db_manager.get_state(DOMAIN_LEDGER_ID).commit() multi_sig = save_multi_sig(db_manager) # Getting nym request = Request(operation={ TARGET_NYM: nym, TXN_TYPE: GET_NYM, }, signatures={}) result = read_manager.get_result(request) assert STATE_PROOF not in result
def test_no_state_proofs_if_protocol_version_less(request_handler): nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' role = "2" verkey = "~7TYfekw4GUagBnBVCqPjiC" seq_no = 0 txn_time = int(time.time()) # Adding nym data = { f.IDENTIFIER.nm: nym, ROLE: role, VERKEY: verkey, f.SEQ_NO.nm: seq_no, TXN_TIME: txn_time, } txn = append_txn_metadata(reqToTxn(Request(operation=data)), seq_no=seq_no, txn_time=txn_time) txn = append_payload_metadata(txn, frm=nym) request_handler.updateNym(nym, txn) request_handler.state.commit() multi_sig = save_multi_sig(request_handler) # Getting nym request = Request(operation={TARGET_NYM: nym}, signatures={}) result = request_handler.handleGetNymReq(request) assert STATE_PROOF not in result
def test_validation_with_unexpected_accum( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default node.write_manager.apply_request(Request(**req_entry), int(time.time())) with pytest.raises(InvalidClientRequest, match="must be equal to the last accumulator value"): node.write_manager.dynamic_validation(Request(**req_entry))
def test_validation_with_unexpected_accum( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default req_handler = node.get_req_handler(DOMAIN_LEDGER_ID) req_handler.apply(Request(**req_entry), int(time.time())) with pytest.raises(InvalidClientRequest, match="must be equal to the last accumulator value"): req_handler.validate(Request(**req_entry))
def test_state_proofs_for_get_claim_def(write_manager, read_manager, db_manager): # Adding claim def nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' seq_no = 0 txn_time = int(time.time()) identifier = "6ouriXMZkLeHsuXrN1X1fd" schema_seqno = 0 signature_type = 'CL' key_components = '{"key_components": []}' tag = 'tag1' txn = { TXN_TYPE: CLAIM_DEF, TARGET_NYM: nym, CLAIM_DEF_SCHEMA_REF: schema_seqno, CLAIM_DEF_PUBLIC_KEYS: key_components, CLAIM_DEF_TAG: tag } txn = append_txn_metadata(reqToTxn( Request(operation=txn, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=identifier)), seq_no=seq_no, txn_time=txn_time) txn = append_payload_metadata(txn, frm=nym) write_manager.update_state(txn) db_manager.get_state(DOMAIN_LEDGER_ID).commit() multi_sig = save_multi_sig(db_manager) # Getting claim def request = Request(operation={ IDENTIFIER: nym, CLAIM_DEF_FROM: nym, CLAIM_DEF_SCHEMA_REF: schema_seqno, CLAIM_DEF_SIGNATURE_TYPE: signature_type, CLAIM_DEF_TAG: tag, TXN_TYPE: GET_CLAIM_DEF, }, signatures={}, protocolVersion=CURRENT_PROTOCOL_VERSION) result = read_manager.get_result(request) proof = extract_proof(result, multi_sig) assert result[DATA] == key_components # Verifying signed state proof path = domain.make_state_path_for_claim_def(nym, schema_seqno, signature_type, tag) assert is_proof_verified(db_manager, proof, path, key_components, seq_no, txn_time)
def build_req_multi_signed_by_endorser(author_role, endorser_role=ENDORSER, append_endorser=False): author_idr = get_idr_by_role(author_role) if author_role != IDENTITY_OWNER else "author_no_role" endorser_idr = get_idr_by_role(endorser_role) req = Request(identifier=author_idr, reqId=1, operation=randomOperation(), signatures={endorser_idr: "sig1", author_idr: "sig2"}, protocolVersion=CURRENT_PROTOCOL_VERSION) if append_endorser: req.endorser = endorser_idr return req
def test_validation_with_same_revoked_by_default( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default req_entry['operation'][VALUE][REVOKED] = [1, 2] req_handler = node.getDomainReqHandler() req_handler.apply(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ACCUM] with pytest.raises(InvalidClientRequest, match="are already revoked in current state"): req_handler.validate(Request(**req_entry))
def test_validation_with_equal_accums_but_not_empty_indices( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default node.write_manager.apply_request(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][REVOKED] = [100, 200] with pytest.raises(InvalidClientRequest, match="Got equal accum and prev_accum"): node.write_manager.dynamic_validation(Request(**req_entry))
def test_validation_with_right_accums_but_empty_indices( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default node.write_manager.apply_request(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][ACCUM] = randomString(10) del req_entry['operation'][VALUE][ISSUED] del req_entry['operation'][VALUE][REVOKED] with pytest.raises(InvalidClientRequest, match="lists are empty"): node.write_manager.dynamic_validation(Request(**req_entry))
def test_validation_with_revoked_no_issued_before_by_demand( build_txn_for_revoc_def_entry_by_demand, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_demand req_entry['operation'][VALUE][ISSUED] = [1, 2] req_handler = node.getDomainReqHandler() req_handler.apply(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][REVOKED] = [3, 4] req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ACCUM] with pytest.raises(InvalidClientRequest, match="are not present in the current issued list"): req_handler.validate(Request(**req_entry))
def test_validation_with_same_revoked_by_default( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default req_entry['operation'][VALUE][REVOKED] = [1, 2] node.write_manager.apply_request(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][ACCUM] = randomString(10) with pytest.raises(InvalidClientRequest, match="are already revoked in current state"): node.write_manager.dynamic_validation(Request(**req_entry))
def test_validation_with_equal_accums_but_not_empty_indices( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default req_handler = node.get_req_handler(DOMAIN_LEDGER_ID) req_handler.apply(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][REVOKED] = [100, 200] with pytest.raises(InvalidClientRequest, match="Got equal accum and prev_accum"): req_handler.validate(Request(**req_entry), int(time.time()))
def test_invalid_cred_def_id_format(build_revoc_def_by_default, create_node_and_not_start): node = create_node_and_not_start req_handler = node.getDomainReqHandler() req = build_revoc_def_by_default req['operation'][CRED_DEF_ID] = ":".join(3 * [randomString(10)]) with pytest.raises(InvalidClientRequest, match="Format of {} field is not acceptable".format(CRED_DEF_ID)): req_handler.validate(Request(**req)) req['operation'][CRED_DEF_ID] = ":".join(6 * [randomString(10)]) with pytest.raises(InvalidClientRequest, match="Format of {} field is not acceptable".format(CRED_DEF_ID)): req_handler.validate(Request(**req))
def test_validation_with_revoked_no_issued_before_by_demand( build_txn_for_revoc_def_entry_by_demand, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_demand req_entry['operation'][VALUE][ISSUED] = [1, 2] node.write_manager.apply_request(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][REVOKED] = [3, 4] req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][ACCUM] = randomString(10) with pytest.raises(InvalidClientRequest, match="are not present in the current issued list"): node.write_manager.dynamic_validation(Request(**req_entry))
def test_validation_with_right_accums_but_empty_indices( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default req_handler = node.get_req_handler(DOMAIN_LEDGER_ID) req_handler.apply(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][ACCUM] = randomString(10) del req_entry['operation'][VALUE][ISSUED] del req_entry['operation'][VALUE][REVOKED] with pytest.raises(InvalidClientRequest, match="lists are empty"): req_handler.validate(Request(**req_entry), int(time.time()))
def test_validation_with_same_issued_by_demand( build_txn_for_revoc_def_entry_by_demand, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_demand req_entry['operation'][VALUE][ISSUED] = [1, 2] req_handler = node.get_req_handler(DOMAIN_LEDGER_ID) req_handler.apply(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][ACCUM] = randomString(10) req_entry['operation'][VALUE][ISSUED] = [1, 2] with pytest.raises(InvalidClientRequest, match="are already issued in current state"): req_handler.validate(Request(**req_entry))
def test_state_proofs_for_get_claim_def(request_handler): # Adding claim def nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' seq_no = 0 txn_time = int(time.time()) identifier = "6ouriXMZkLeHsuXrN1X1fd" schema_seqno = 0 signature_type = 'CL' key_components = '{"key_components": []}' txn = { TXN_TYPE: CLAIM_DEF, TARGET_NYM: nym, REF: schema_seqno, DATA: key_components } txn = append_txn_metadata(reqToTxn( Request(operation=txn, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=identifier)), seq_no=seq_no, txn_time=txn_time) txn = append_payload_metadata(txn, frm=nym) request_handler._addClaimDef(txn) request_handler.state.commit() multi_sig = save_multi_sig(request_handler) # Getting claim def request = Request(operation={ IDENTIFIER: nym, ORIGIN: nym, REF: schema_seqno, SIGNATURE_TYPE: signature_type }, signatures={}, protocolVersion=CURRENT_PROTOCOL_VERSION) result = request_handler.handleGetClaimDefReq(request) proof = extract_proof(result, multi_sig) assert result[DATA] == key_components # Verifying signed state proof path = domain.make_state_path_for_claim_def(nym, schema_seqno, signature_type) assert is_proof_verified(request_handler, proof, path, key_components, seq_no, txn_time)
def test_validation_with_issued_no_revoked_before_by_default( build_txn_for_revoc_def_entry_by_default, create_node_and_not_start): node = create_node_and_not_start req_entry = build_txn_for_revoc_def_entry_by_default req_entry['operation'][VALUE][REVOKED] = [1, 2] req_handler = node.get_req_handler(DOMAIN_LEDGER_ID) req_handler.apply(Request(**req_entry), int(time.time())) req_entry['operation'][VALUE][ISSUED] = [3, 4] req_entry['operation'][VALUE][REVOKED] = [] req_entry['operation'][VALUE][PREV_ACCUM] = req_entry['operation'][VALUE][ ACCUM] req_entry['operation'][VALUE][ACCUM] = randomString(10) with pytest.raises(InvalidClientRequest, match="are not present in the current revoked list"): req_handler.validate(Request(**req_entry))
def test_state_proofs_for_get_schema(write_manager, read_manager, db_manager): # Adding schema nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' seq_no = 0 txn_time = int(time.time()) identifier = "6ouriXMZkLeHsuXrN1X1fd" schema_name = "schema_a" schema_version = "1.0" # data = '{"name": "schema_a", "version": "1.0"}' schema_key = {SCHEMA_NAME: schema_name, SCHEMA_VERSION: schema_version} data = {**schema_key, SCHEMA_ATTR_NAMES: ["Some_Attr", "Attr1"]} txn = { TXN_TYPE: SCHEMA, DATA: data, } txn = append_txn_metadata(reqToTxn( Request(operation=txn, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=identifier)), seq_no=seq_no, txn_time=txn_time) txn = append_payload_metadata(txn, frm=nym) write_manager.update_state(txn) db_manager.get_state(DOMAIN_LEDGER_ID).commit() multi_sig = save_multi_sig(db_manager) # Getting schema request = Request(operation={ TARGET_NYM: nym, DATA: schema_key, TXN_TYPE: GET_SCHEMA }, signatures={}, protocolVersion=CURRENT_PROTOCOL_VERSION) result = read_manager.get_result(request) proof = extract_proof(result, multi_sig) assert result[DATA] == data data.pop(NAME) data.pop(VERSION) # Verifying signed state proof path = domain.make_state_path_for_schema(nym, schema_name, schema_version) assert is_proof_verified(db_manager, proof, path, data, seq_no, txn_time)
def test_state_proofs_for_get_nym(request_handler): nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' role = "2" verkey = "~7TYfekw4GUagBnBVCqPjiC" seq_no = 0 txn_time = int(time.time()) # Adding nym data = { f.IDENTIFIER.nm: nym, ROLE: role, VERKEY: verkey, f.SEQ_NO.nm: seq_no, TXN_TIME: txn_time, } request_handler.updateNym(nym, data) request_handler.state.commit() multi_sig = save_multi_sig(request_handler) # Getting nym request = Request(operation={TARGET_NYM: nym}, protocolVersion=CURRENT_PROTOCOL_VERSION) result = request_handler.handleGetNymReq(request, "Sender") proof = extract_proof(result, multi_sig) # Verifying signed state proof path = request_handler.nym_to_state_key(nym) encoded_value = request_handler.stateSerializer.serialize(data) proof_nodes = base64.b64decode(proof[PROOF_NODES]) root_hash = base58.b58decode(proof[ROOT_HASH]) verified = request_handler.state.verify_state_proof(root_hash, path, encoded_value, proof_nodes, serialized=True) assert verified
def test_send_nym_with_fees(helpers, looper, nodeSetWithIntegratedTokenPlugin, sdk_wallet_trustee, sdk_wallet_steward, sdk_pool_handle, fees_set, address_main, mint_tokens): req = helpers.request.nym_new(sdk_wallet=sdk_wallet_trustee) amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 utxos = [{ "source": utxo_from_addr_and_seq_no(address_main, init_seq_no), AMOUNT: amount }] req = Request(**json.loads(req)) req = add_fees_request_with_address(helpers, fees_set, req, address_main, utxos=utxos) token_len = len(nodeSetWithIntegratedTokenPlugin[0].ledgers[-1]) helpers.sdk.send_and_check_request_objects([req], wallet=sdk_wallet_trustee) assert token_len == len( nodeSetWithIntegratedTokenPlugin[0].ledgers[-1]) - 1 assert get_last_token_txn( nodeSetWithIntegratedTokenPlugin)[1]['txn']['data']['fees'] == NYM_FEE request = looper.loop.run_until_complete( build_get_nym_request(sdk_wallet_trustee[1], req.operation['dest'])) read_rep = sdk_get_and_check_replies(looper, [ sdk_sign_and_submit_req(sdk_pool_handle, sdk_wallet_trustee, request) ]) reply = json.loads(read_rep[0][1]['result'][DATA]) assert req.operation['dest'] == reply['dest'] assert req.operation['verkey'] == reply['verkey']
def test_state_proofs_for_get_attr(request_handler): # Adding attribute nym = 'Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv' attr_key = 'last_name' raw_attribute = '{"last_name":"Anderson"}' seq_no = 0 txn_time = int(time.time()) txn = { TXN_TYPE: ATTRIB, TARGET_NYM: nym, RAW: raw_attribute, f.SEQ_NO.nm: seq_no, TXN_TIME: txn_time, } request_handler._addAttr(txn) request_handler.state.commit() multi_sig = save_multi_sig(request_handler) # Getting attribute get_request = Request(operation={ TARGET_NYM: nym, RAW: 'last_name' }, protocolVersion=CURRENT_PROTOCOL_VERSION) result = request_handler.handleGetAttrsReq(get_request, 'Sender') proof = extract_proof(result, multi_sig) attr_value = result[DATA] assert attr_value == raw_attribute # Verifying signed state proof path = domain.make_state_path_for_attr(nym, attr_key) assert is_proof_verified(request_handler, proof, path, domain.hash_of(attr_value), seq_no, txn_time)
def test_validation_cred_def_not_present(build_revoc_def_by_default, create_node_and_not_start): node = create_node_and_not_start req = build_revoc_def_by_default req_handler = node.getDomainReqHandler() with pytest.raises(InvalidClientRequest, match="There is no any CRED_DEF"): req_handler.validate(Request(**req))
def build_req_and_action(action: Action): sig = None sigs = None identifier = IDENTIFIERS[action.author][0] endorser_did = None # if there is only 1 sig from the Author - use `signature` instead of `signatures` if len(action.sigs) == 1 and next(iter(action.sigs.values())) == 1 and next( iter(action.sigs.keys())) == action.author: sig = 'signature' else: sigs = {IDENTIFIERS[role][i]: 'signature' for role, sig_count in action.sigs.items() for i in range(sig_count)} if action.endorser is not None: endorser_did = IDENTIFIERS[action.endorser][0] operation = randomOperation() if action.amount is not None: operation[PLUGIN_FIELD] = action.amount req = Request(identifier=identifier, operation=operation, signature=sig, signatures=sigs, endorser=endorser_did) action = AuthActionAdd(txn_type=req.operation[TYPE], field='some_field', value='new_value', is_owner=action.is_owner) return req, [action]
def build_req_signed_by_author_only(author_role): idr = get_idr_by_role_author(author_role) return Request(identifier=idr, reqId=1, operation=randomOperation(), signature="sig2", protocolVersion=CURRENT_PROTOCOL_VERSION)
def build_req_multi_signed_by_non_author_only(author_role, non_author_role): return Request( identifier=get_idr_by_role_author(author_role), reqId=1, operation=randomOperation(), signatures={get_idr_by_role_endorser(non_author_role): "sig"}, protocolVersion=CURRENT_PROTOCOL_VERSION)
def add_revoc_def_by_demand(create_node_and_not_start, looper, sdk_wallet_steward): node = create_node_and_not_start data = { ID: randomString(50), TXN_TYPE: REVOC_REG_DEF, REVOC_TYPE: "CL_ACCUM", TAG: randomString(5), CRED_DEF_ID: ":".join(4 * [randomString(10)]), VALUE: { ISSUANCE_TYPE: ISSUANCE_ON_DEMAND, MAX_CRED_NUM: 1000000, TAILS_HASH: randomString(50), TAILS_LOCATION: 'http://tails.location.com', PUBLIC_KEYS: {}, } } req = sdk_sign_request_from_dict(looper, sdk_wallet_steward, data) req_handler = node.getDomainReqHandler() txn = append_txn_metadata(reqToTxn(Request(**req)), txn_time=int(time.time()), seq_no=node.domainLedger.seqNo + 1) req_handler._addRevocDef(txn) return req
def test_getVerkey_success(node): token_authnr = TokenAuthNr(ACCEPTABLE_WRITE_TYPES, ACCEPTABLE_QUERY_TYPES, ACCEPTABLE_ACTION_TYPES, node[0].db_manager.idr_cache) ver_key = token_authnr.getVerkey(VALID_IDENTIFIER, Request()) assert len(ver_key) == 23 assert ver_key[0] == '~'
def test_getVerkey_invalid_identifier(node): token_authnr = TokenAuthNr(ACCEPTABLE_WRITE_TYPES, ACCEPTABLE_QUERY_TYPES, ACCEPTABLE_ACTION_TYPES, node[0].db_manager.idr_cache) identifier_invalid = 'INVALID_IDENTIFIER' with pytest.raises(UnknownIdentifier): token_authnr.getVerkey(identifier_invalid, Request())
def processRequest(self, request: Request, frm: str): if self.is_query(request.operation[TXN_TYPE]): self.process_query(request, frm) self.total_read_request_number += 1 else: # forced request should be processed before consensus if (request.operation[TXN_TYPE] in [ POOL_UPGRADE, POOL_CONFIG]) and request.isForced(): self.configReqHandler.validate(request) self.configReqHandler.applyForced(request) # here we should have write transactions that should be processed # only on writable pool if self.poolCfg.isWritable() or (request.operation[TXN_TYPE] in [ POOL_UPGRADE, POOL_CONFIG]): super().processRequest(request, frm) else: raise InvalidClientRequest( request.identifier, request.reqId, 'Pool is in readonly mode, try again in 60 seconds')
def applyForced(self, req: Request): if req.isForced(): txn = reqToTxn(req) self.upgrader.handleUpgradeTxn(txn) self.poolCfg.handleConfigTxn(txn)