def get_result(self, request: Request):
        version = request.operation.get(GET_TXN_AUTHOR_AGREEMENT_AML_VERSION)
        timestamp = request.operation.get(
            GET_TXN_AUTHOR_AGREEMENT_AML_TIMESTAMP)

        if version is not None:
            path = StaticTAAHelper.state_path_taa_aml_version(version)
            data, proof = self._get_value_from_state(path, with_proof=True)
            return self._return_txn_author_agreement_aml(request,
                                                         proof,
                                                         data=data)

        if timestamp is not None:
            head_hash = self.database_manager.ts_store.get_equal_or_prev(
                timestamp, CONFIG_LEDGER_ID)
            if head_hash is None:
                return self._return_txn_author_agreement_aml(request, None)
            head_hash = head_hash if head_hash else self.state.committedHeadHash
            data, proof = self._get_value_from_state(
                StaticTAAHelper.state_path_taa_aml_latest(),
                head_hash,
                with_proof=True)
            return self._return_txn_author_agreement_aml(request,
                                                         proof,
                                                         data=data)

        path = StaticTAAHelper.state_path_taa_aml_latest()
        data, proof = self._get_value_from_state(path, with_proof=True)
        return self._return_txn_author_agreement_aml(request, proof, data=data)
Ejemplo n.º 2
0
    def _validate_update_taa(self, request, digest):
        ledger_taa = self.get_from_state(StaticTAAHelper.state_path_taa_digest(digest))[0]

        # check TAA text
        taa_text = ledger_taa.get(TXN_AUTHOR_AGREEMENT_TEXT)
        if request.operation.get(TXN_AUTHOR_AGREEMENT_TEXT, taa_text) != taa_text:
            raise InvalidClientRequest(request.identifier, request.reqId,
                                       "Changing a text of existing transaction author agreement is forbidden")

        # check TAA ratification timestamp
        taa_ratified = ledger_taa.get(TXN_AUTHOR_AGREEMENT_RATIFICATION_TS)
        if request.operation.get(TXN_AUTHOR_AGREEMENT_RATIFICATION_TS, taa_ratified) != taa_ratified:
            raise InvalidClientRequest(request.identifier, request.reqId,
                                       "Changing ratification date of existing "
                                       "transaction author agreement is forbidden")

        # TODO: Following code assumes that the only reason for updating TAA is changing its retirement date.
        #   If this is no longer the case this needs to be changed. Also this cries for adding separate transaction
        #   for TAA retirement

        # check if TAA enforcement is disabled
        last_taa_digest = StaticTAAHelper.get_latest_taa(self.state)
        if last_taa_digest is None:
            raise InvalidClientRequest(request.identifier, request.reqId,
                                       "Retirement date cannot be changed when TAA enforcement is disabled.")

        # check if we are trying to modify latest TAA
        if last_taa_digest == digest:
            raise InvalidClientRequest(request.identifier, request.reqId,
                                       "The latest transaction author agreement cannot be retired.")
Ejemplo n.º 3
0
    def get_result(self, request: Request):
        version = request.operation.get(GET_TXN_AUTHOR_AGREEMENT_VERSION)
        digest = request.operation.get(GET_TXN_AUTHOR_AGREEMENT_DIGEST)
        timestamp = request.operation.get(GET_TXN_AUTHOR_AGREEMENT_TIMESTAMP)

        if version is not None:
            path = StaticTAAHelper.state_path_taa_version(version)
            digest, proof = self._get_value_from_state(path, with_proof=True)
            return self._return_txn_author_agreement(request,
                                                     proof,
                                                     digest=digest)

        if digest is not None:
            path = StaticTAAHelper.state_path_taa_digest(digest)
            data, proof = self._get_value_from_state(path, with_proof=True)
            return self._return_txn_author_agreement(request, proof, data=data)

        if timestamp is not None:
            head_hash = self.database_manager.ts_store.get_equal_or_prev(
                timestamp, CONFIG_LEDGER_ID)
            if head_hash is None:
                return self._return_txn_author_agreement(request, None)
            path = StaticTAAHelper.state_path_taa_latest()
            digest, proof = self._get_value_from_state(path,
                                                       head_hash,
                                                       with_proof=True)
            return self._return_txn_author_agreement(request,
                                                     proof,
                                                     head_hash=head_hash,
                                                     digest=digest)

        path = StaticTAAHelper.state_path_taa_latest()
        digest, proof = self._get_value_from_state(path, with_proof=True)
        return self._return_txn_author_agreement(request, proof, digest=digest)
Ejemplo n.º 4
0
 def update_state(self, txn, prev_result, request, is_committed=False):
     self._validate_txn_type(txn)
     seq_no = get_seq_no(txn)
     txn_time = get_txn_time(txn)
     _, taa_list = self.state.generate_state_proof_for_keys_with_prefix(
         StaticTAAHelper.state_path_taa_digest(""),
         serialize=False,
         get_value=True)
     for encode_key, encode_data in taa_list.items():
         taa = rlp_decode(encode_data)
         taa, last_seq_no, last_update_time = self._decode_state_value(
             taa[0])
         digest = StaticTAAHelper.get_digest_from_state_key(encode_key)
         if TXN_AUTHOR_AGREEMENT_RETIREMENT_TS not in taa or taa.get(
                 TXN_AUTHOR_AGREEMENT_RETIREMENT_TS, 0) > txn_time:
             self._set_taa_to_state(
                 digest,
                 seq_no,
                 txn_time,
                 taa[TXN_AUTHOR_AGREEMENT_TEXT],
                 taa[TXN_AUTHOR_AGREEMENT_VERSION],
                 taa.get(TXN_AUTHOR_AGREEMENT_RATIFICATION_TS,
                         last_update_time),
                 retirement_ts=txn_time)
     self.state.remove(StaticTAAHelper.state_path_taa_latest())
    def _add_taa_to_state(self, digest, seq_no, txn_time, text, version,
                          ratification_ts):
        self._set_taa_to_state(digest, seq_no, txn_time, text, version,
                               ratification_ts)

        self.state.set(StaticTAAHelper.state_path_taa_version(version), digest)
        self.state.set(StaticTAAHelper.state_path_taa_latest(), digest)
def test_update_state(txn_author_agreement_handler, taa_request):
    seq_no = 1
    txn_time = 1560241033
    txn_id = "id"
    txn = reqToTxn(taa_request)
    payload = get_payload_data(txn)
    text = payload[TXN_AUTHOR_AGREEMENT_TEXT]
    version = payload[TXN_AUTHOR_AGREEMENT_VERSION]
    digest = StaticTAAHelper.taa_digest(text, version)
    append_txn_metadata(txn, seq_no, txn_time, txn_id)

    state_value = {
        TXN_AUTHOR_AGREEMENT_TEXT: text,
        TXN_AUTHOR_AGREEMENT_VERSION: version
    }

    txn_author_agreement_handler.update_state(txn, None, taa_request)

    assert txn_author_agreement_handler.get_from_state(
        StaticTAAHelper.state_path_taa_digest(digest)) == (state_value, seq_no,
                                                           txn_time)
    assert txn_author_agreement_handler.state.get(
        StaticTAAHelper.state_path_taa_latest()) == digest
    assert txn_author_agreement_handler.state.get(
        StaticTAAHelper.state_path_taa_version(version)) == digest
 def update_state(self, txn, prev_result, request, is_committed=False):
     self._validate_txn_type(txn)
     payload = get_payload_data(txn)
     seq_no = get_seq_no(txn)
     txn_time = get_txn_time(txn)
     serialized_data = encode_state_value(payload, seq_no, txn_time, serializer=config_state_serializer)
     version = payload[AML_VERSION]
     self.state.set(StaticTAAHelper.state_path_taa_aml_latest(), serialized_data)
     self.state.set(StaticTAAHelper.state_path_taa_aml_version(version), serialized_data)
Ejemplo n.º 8
0
 def _update_txn_author_agreement_acceptance_mechanisms(
         self, payload, seq_no, txn_time):
     serialized_data = encode_state_value(
         payload, seq_no, txn_time, serializer=config_state_serializer)
     version = payload[AML_VERSION]
     self.state.set(StaticTAAHelper.state_path_taa_aml_latest(),
                    serialized_data)
     self.state.set(StaticTAAHelper.state_path_taa_aml_version(version),
                    serialized_data)
 def dynamic_validation(self, request: Request):
     self._validate_request_type(request)
     self.authorize(request)
     operation, identifier, req_id = request.operation, request.identifier, request.reqId
     if self.state.get(StaticTAAHelper.state_path_taa_aml_latest()) is None:
         raise InvalidClientRequest(identifier, req_id,
                                    "TAA txn is forbidden until TAA AML is set. Send TAA AML first.")
     version = operation[TXN_AUTHOR_AGREEMENT_VERSION]
     if StaticTAAHelper.get_taa_digest(self.state, version, isCommitted=False) is not None:
         raise InvalidClientRequest(identifier, req_id,
                                    "Changing existing version of transaction author agreement is forbidden")
def test_update_state(txn_author_agreement_disable_handler,
                      taa_disable_request, txn_author_agreement_handler, tconf,
                      domain_state, taa_pp_time):
    # create TAAs
    taa_txns = []
    taa_digests = []
    taa_state_datas = []
    for _ in list(range(5)):
        txn, digest, state_data = create_taa_txn(
            taa_request(tconf, domain_state, taa_pp_time), taa_pp_time)
        taa_txns.append(txn)
        taa_digests.append(digest)
        taa_state_datas.append(state_data)
    assert taa_txns

    # create a disable txn
    disable_seq_no = 1
    disable_txn_time = get_utc_epoch()
    taa_disable_txn = reqToTxn(taa_disable_request)
    append_txn_metadata(taa_disable_txn, disable_seq_no, disable_txn_time)

    # set a TAAs
    for index, taa_txn in enumerate(taa_txns):
        txn_author_agreement_handler.update_state(taa_txn, None, None)

        check_taa_in_state(
            handler=txn_author_agreement_handler,
            digest=taa_digests[index],
            version=taa_state_datas[index][0][TXN_AUTHOR_AGREEMENT_VERSION],
            state_data=taa_state_datas[index])
        assert txn_author_agreement_disable_handler.state.get(
            StaticTAAHelper.state_path_taa_latest(),
            isCommitted=False) == taa_digests[index].encode()

    # disable TAAs
    txn_author_agreement_disable_handler.update_state(taa_disable_txn, None,
                                                      None)

    assert txn_author_agreement_disable_handler.state.get(
        StaticTAAHelper.state_path_taa_latest(), isCommitted=False) is None

    # set a TAAs
    for index, state_data in enumerate(taa_state_datas):
        state_value = state_data[0]
        state_value[TXN_AUTHOR_AGREEMENT_RETIREMENT_TS] = disable_txn_time
        check_taa_in_state(handler=txn_author_agreement_handler,
                           digest=taa_digests[index],
                           version=state_value[TXN_AUTHOR_AGREEMENT_VERSION],
                           state_data=(state_data[0], disable_seq_no,
                                       disable_txn_time))
Ejemplo n.º 11
0
    def _update_txn_author_agreement(self, seq_no, txn_time, text, version):
        digest = StaticTAAHelper.taa_digest(text, version)
        data = encode_state_value(
            {
                TXN_AUTHOR_AGREEMENT_TEXT: text,
                TXN_AUTHOR_AGREEMENT_VERSION: version
            },
            seq_no,
            txn_time,
            serializer=config_state_serializer)

        self.state.set(StaticTAAHelper.state_path_taa_digest(digest), data)
        self.state.set(StaticTAAHelper.state_path_taa_latest(), digest)
        self.state.set(StaticTAAHelper.state_path_taa_version(version), digest)
Ejemplo n.º 12
0
 def update_state(self, txn, prev_result, request, is_committed=False):
     self._validate_txn_type(txn)
     payload = get_payload_data(txn)
     text = payload.get(TXN_AUTHOR_AGREEMENT_TEXT)
     version = payload[TXN_AUTHOR_AGREEMENT_VERSION]
     retired = payload.get(TXN_AUTHOR_AGREEMENT_RETIREMENT_TS)
     ratified = payload.get(TXN_AUTHOR_AGREEMENT_RATIFICATION_TS)
     seq_no = get_seq_no(txn)
     txn_time = get_txn_time(txn)
     digest = StaticTAAHelper.get_taa_digest(self.state, version, isCommitted=False)
     if digest is None:
         digest = StaticTAAHelper.taa_digest(text, version)
         self._add_taa_to_state(digest, seq_no, txn_time, text, version, ratified)
     else:
         self._update_taa_to_state(digest, seq_no, txn_time, retired)
Ejemplo n.º 13
0
def expected_data(data: TaaData):
    return {
        TXN_AUTHOR_AGREEMENT_TEXT: data.text,
        TXN_AUTHOR_AGREEMENT_VERSION: data.version,
        TXN_AUTHOR_AGREEMENT_DIGEST: StaticTAAHelper.taa_digest(data.text, data.version),
        TXN_AUTHOR_AGREEMENT_RATIFICATION_TS: data.txn_time
    }, data.seq_no, data.txn_time
Ejemplo n.º 14
0
 def additional_dynamic_validation(self, request: Request,
                                   req_pp_time: Optional[int]):
     if not self.state.get(StaticTAAHelper.state_path_taa_latest(),
                           isCommitted=False):
         raise InvalidClientRequest(
             request.identifier, request.reqId,
             "Transaction author agreement is already disabled.")
Ejemplo n.º 15
0
    def update_state(self, txn, prev_result, request, is_committed=False):
        self._validate_txn_type(txn)
        payload = get_payload_data(txn)
        text = payload[TXN_AUTHOR_AGREEMENT_TEXT]
        version = payload[TXN_AUTHOR_AGREEMENT_VERSION]
        seq_no = get_seq_no(txn)
        txn_time = get_txn_time(txn)
        digest = StaticTAAHelper.taa_digest(text, version)
        data = encode_state_value({
            TXN_AUTHOR_AGREEMENT_TEXT: text,
            TXN_AUTHOR_AGREEMENT_VERSION: version
        }, seq_no, txn_time, serializer=config_state_serializer)

        self.state.set(StaticTAAHelper.state_path_taa_digest(digest), data)
        self.state.set(StaticTAAHelper.state_path_taa_latest(), digest)
        self.state.set(StaticTAAHelper.state_path_taa_version(version), digest)
Ejemplo n.º 16
0
def set_aml(txn_author_agreement_handler):
    txn_author_agreement_handler.state.set(
        StaticTAAHelper.state_path_taa_aml_latest(),
        encode_state_value("value",
                           "seqNo",
                           "txnTime",
                           serializer=config_state_serializer))
Ejemplo n.º 17
0
 def dynamic_validation(self, request: Request, req_pp_time: Optional[int]):
     self._validate_request_type(request)
     self.authorize(request)
     operation, identifier, req_id = request.operation, request.identifier, request.reqId
     aml_latest, _, _ = self.get_from_state(StaticTAAHelper.state_path_taa_aml_latest())
     if aml_latest is None:
         raise InvalidClientRequest(identifier, req_id,
                                    "TAA txn is forbidden until TAA AML is set. Send TAA AML first.")
     version = operation[TXN_AUTHOR_AGREEMENT_VERSION]
     digest = StaticTAAHelper.get_taa_digest(self.state, version, isCommitted=False)
     if digest is None:
         if req_pp_time is None:
             raise LogicError("Cannot validate TAA transaction outside of normal ordering")
         self._validate_add_taa(request, req_pp_time)
     else:
         self._validate_update_taa(request, digest)
Ejemplo n.º 18
0
def taa_input_data():
    input_data = []
    for n in range(10):
        text, version = gen_random_txn_author_agreement(32, 8)
        input_data.append(
            TaaData(text, version, n, n + 10,
                    StaticTAAHelper.taa_digest(text, version)))
    return input_data
 def dynamic_validation(self, request: Request):
     self._validate_request_type(request)
     self.authorize(request)
     operation, identifier, req_id = request.operation, request.identifier, request.reqId
     version = operation.get(AML_VERSION)
     if StaticTAAHelper.get_taa_aml_data(self.state, version, isCommitted=False) is not None:
         raise InvalidClientRequest(identifier, req_id,
                                    "Version of TAA AML must be unique and it cannot be modified")
Ejemplo n.º 20
0
 def additional_dynamic_validation(self, request: Request,
                                   req_pp_time: Optional[int]):
     operation, identifier, req_id = request.operation, request.identifier, request.reqId
     version = operation.get(AML_VERSION)
     if StaticTAAHelper.get_taa_aml_data(self.state,
                                         version,
                                         isCommitted=False) is not None:
         raise InvalidClientRequest(
             identifier, req_id,
             "Version of TAA AML must be unique and it cannot be modified")
Ejemplo n.º 21
0
    def _update_taa_to_state(self, digest, seq_no, txn_time, retirement_ts=None):
        ledger_data = self.get_from_state(StaticTAAHelper.state_path_taa_digest(digest))
        if ledger_data is None:
            return
        ledger_taa, last_seq_no, last_update_time = ledger_data
        ratification_ts = ledger_taa.get(TXN_AUTHOR_AGREEMENT_RATIFICATION_TS, last_update_time)
        text = ledger_taa.get(TXN_AUTHOR_AGREEMENT_TEXT)
        version = ledger_taa.get(TXN_AUTHOR_AGREEMENT_VERSION)

        self._set_taa_to_state(digest, seq_no, txn_time, text, version, ratification_ts, retirement_ts)
def test_update_state(txn_author_agreement_aml_handler, domain_state,
                      aml_request):
    seq_no = 1
    txn_time = 1560241033
    txn_id = "id"
    txn = reqToTxn(aml_request)
    payload = get_payload_data(txn)
    version = payload[AML_VERSION]
    append_txn_metadata(txn, seq_no, txn_time, txn_id)

    txn_author_agreement_aml_handler.update_state(txn, None, aml_request)

    assert txn_author_agreement_aml_handler.get_from_state(
        StaticTAAHelper.state_path_taa_aml_latest()) == (payload, seq_no,
                                                         txn_time)
    assert txn_author_agreement_aml_handler.get_from_state(
        StaticTAAHelper.state_path_taa_aml_version(version)) == (payload,
                                                                 seq_no,
                                                                 txn_time)
def test_dynamic_validation_with_not_unique_aml(
        txn_author_agreement_aml_handler, aml_request):
    version = aml_request.operation[AML_VERSION]
    txn_author_agreement_aml_handler.state.set(
        StaticTAAHelper.state_path_taa_aml_version(version), "{}")
    with pytest.raises(
            InvalidClientRequest,
            match="Version of TAA AML must be unique and it cannot be modified"
    ):
        txn_author_agreement_aml_handler.dynamic_validation(aml_request)
Ejemplo n.º 24
0
def expected_state_data(data: TaaData) -> Dict:
    return {
        'lsn': data.seq_no,
        'lut': data.txn_time,
        'val': {
            TXN_AUTHOR_AGREEMENT_TEXT: data.text,
            TXN_AUTHOR_AGREEMENT_VERSION: data.version,
            TXN_AUTHOR_AGREEMENT_DIGEST: StaticTAAHelper.taa_digest(data.text, data.version),
            TXN_AUTHOR_AGREEMENT_RATIFICATION_TS: data.txn_time
        }
    }
Ejemplo n.º 25
0
def test_dynamic_validation_with_not_unique_version(
        txn_author_agreement_handler, taa_request, set_aml):
    version = taa_request.operation[TXN_AUTHOR_AGREEMENT_VERSION]
    txn_author_agreement_handler.state.set(
        StaticTAAHelper.state_path_taa_version(version), "{}".encode())
    with pytest.raises(
            InvalidClientRequest,
            match=
            "Changing existing version of transaction author agreement is forbidden"
    ):
        txn_author_agreement_handler.dynamic_validation(taa_request)
def test_fill_ts_store_for_config_after_catchup(txnPoolNodeSet, looper,
                                                sdk_pool_handle,
                                                sdk_wallet_trustee, tconf,
                                                tdir, allPluginsPath,
                                                set_txn_author_agreement_aml):
    sdk_send_txn_author_agreement(looper,
                                  sdk_pool_handle,
                                  sdk_wallet_trustee,
                                  *create_random_taa(),
                                  ratified=get_utc_epoch() - 600)
    node_to_disconnect = txnPoolNodeSet[-1]

    disconnect_node_and_ensure_disconnected(looper, txnPoolNodeSet,
                                            node_to_disconnect)
    looper.removeProdable(name=node_to_disconnect.name)
    sdk_reply = sdk_send_txn_author_agreement(looper,
                                              sdk_pool_handle,
                                              sdk_wallet_trustee,
                                              *create_random_taa(),
                                              ratified=get_utc_epoch() - 600)

    node_to_disconnect = start_stopped_node(node_to_disconnect, looper, tconf,
                                            tdir, allPluginsPath)
    txnPoolNodeSet[-1] = node_to_disconnect
    looper.run(checkNodesConnected(txnPoolNodeSet))

    waitNodeDataEquality(looper,
                         node_to_disconnect,
                         *txnPoolNodeSet,
                         exclude_from_check=['check_last_ordered_3pc_backup'])
    req_handler = node_to_disconnect.read_manager.request_handlers[
        GET_TXN_AUTHOR_AGREEMENT]
    last_digest = StaticTAAHelper.get_taa_digest(req_handler.state)
    key = StaticTAAHelper.state_path_taa_digest(last_digest)
    root_hash = req_handler.database_manager.ts_store.get_equal_or_prev(
        get_txn_time(sdk_reply[1]['result']))
    assert root_hash
    from_state = req_handler.state.get_for_root_hash(root_hash=root_hash,
                                                     key=key)
    assert config_state_serializer.deserialize(from_state)['val']['text'] == \
           get_payload_data(sdk_reply[1]['result'])['text']
def test_update_state(txn_author_agreement_handler, taa_request, taa_pp_time):
    txn, digest, state_data = create_taa_txn(taa_request, taa_pp_time)

    txn_author_agreement_handler.update_state(txn, None, taa_request)

    check_taa_in_state(handler=txn_author_agreement_handler,
                       digest=digest,
                       version=state_data[0][TXN_AUTHOR_AGREEMENT_VERSION],
                       state_data=state_data)
    assert txn_author_agreement_handler.state.get(
        StaticTAAHelper.state_path_taa_latest(),
        isCommitted=False) == digest.encode()
 def authorize(self, request):
     version = request.operation.get(TXN_AUTHOR_AGREEMENT_VERSION)
     if StaticTAAHelper.get_taa_digest(self.state, version, isCommitted=False) is None:
         self.write_req_validator.validate(request,
                                           [AuthActionAdd(txn_type=self.txn_type,
                                                          field='*',
                                                          value='*')])
     else:
         self.write_req_validator.validate(request,
                                           [AuthActionEdit(txn_type=self.txn_type,
                                                           field='*',
                                                           old_value='*',
                                                           new_value='*')])
Ejemplo n.º 29
0
def set_txn_author_agreement(
        looper, sdk_pool_handle, sdk_wallet, text: str, version: str, ratified: int, retired: Optional[int]
) -> TaaData:
    reply = sdk_send_txn_author_agreement(looper, sdk_pool_handle, sdk_wallet, version, text,
                                          ratified=ratified, retired=retired)[1]

    assert reply[OP_FIELD_NAME] == REPLY
    result = reply[f.RESULT.nm]

    return TaaData(
        text, version,
        seq_no=result[TXN_METADATA][TXN_METADATA_SEQ_NO],
        txn_time=result[TXN_METADATA][TXN_METADATA_TIME],
        # TODO: Add ratified?
        digest=StaticTAAHelper.taa_digest(text, version)
    )
def test_dynamic_validation_update_with_retired_taa_off(
        txn_author_agreement_handler, domain_state, taa_request, taa_pp_time,
        set_aml, retired_time):

    txn, digest, state_data = create_taa_txn(taa_request, taa_pp_time)
    txn_author_agreement_handler.update_state(txn, None, taa_request)
    txn_author_agreement_handler.state.remove(
        StaticTAAHelper.state_path_taa_latest())
    if retired_time != "without":
        taa_request.operation[
            TXN_AUTHOR_AGREEMENT_RETIREMENT_TS] = retired_time
    with pytest.raises(
            InvalidClientRequest,
            match=
            "Retirement date cannot be changed when TAA enforcement is disabled."
    ):
        txn_author_agreement_handler.dynamic_validation(
            taa_request, taa_pp_time)