Ejemplo n.º 1
0
 def deduct_fees(self, request, cons_time, ledger_id, seq_no, txn):
     txn_type = request.operation[TXN_TYPE]
     fees_key = "{}#{}".format(txn_type, seq_no)
     if txn_type != XFER_PUBLIC and FeesAuthorizer.has_fees(request):
         inputs, outputs, signatures = getattr(request, f.FEES.nm)
         # This is correct since FEES is changed from config ledger whose
         # transactions have no fees
         fees = FeesAuthorizer.calculate_fees_from_req(
             self.utxo_cache, request)
         sigs = {i[ADDRESS]: s for i, s in zip(inputs, signatures)}
         txn = {
             OPERATION: {
                 TXN_TYPE: FEE_TXN,
                 INPUTS: inputs,
                 OUTPUTS: outputs,
                 REF: self.get_ref_for_txn_fees(ledger_id, seq_no),
                 FEES: fees,
             },
             f.SIGS.nm: sigs,
             f.REQ_ID.nm: get_req_id(txn),
             f.PROTOCOL_VERSION.nm: 2,
         }
         txn = reqToTxn(txn)
         self.token_ledger.append_txns_metadata([txn], txn_time=cons_time)
         _, txns = self.token_ledger.appendTxns(
             [TokenReqHandler.transform_txn_for_ledger(txn)])
         self.updateState(txns)
         self.fee_txns_in_current_batch += 1
         self.deducted_fees[fees_key] = fees
         return txn
Ejemplo n.º 2
0
def fees_authorizer(fees):
    authorizer = FeesAuthorizer(
        config_state=PruningState(KeyValueStorageInMemory()),
        utxo_cache=UTXOCache(KeyValueStorageInMemory()))
    authorizer.calculate_fees_from_req = lambda *args, **kwargs: fees.get(
        NYM_FEES_ALIAS)
    return authorizer
Ejemplo n.º 3
0
 def apply_request(self, request: Request, batch_ts, prev_result):
     txn_type = request.operation[TXN_TYPE]
     seq_no = get_seq_no(prev_result)
     cons_time = get_txn_time(prev_result)
     if FeesAuthorizer.has_fees(request):
         inputs, outputs, signatures = getattr(request, f.FEES.nm)
         # This is correct since FEES is changed from config ledger whose
         # transactions have no fees
         fees = FeesAuthorizer.calculate_fees_from_req(
             self.utxo_cache, request)
         sigs = {i[ADDRESS]: s for i, s in zip(inputs, signatures)}
         txn = {
             OPERATION: {
                 TXN_TYPE: FEE_TXN,
                 INPUTS: inputs,
                 OUTPUTS: outputs,
                 REF: self._get_ref_for_txn_fees(seq_no),
                 FEES: fees,
             },
             f.SIGS.nm: sigs,
             f.REQ_ID.nm: get_req_id(prev_result),
             f.PROTOCOL_VERSION.nm: 2,
         }
         txn = reqToTxn(txn)
         self.token_ledger.append_txns_metadata([txn], txn_time=cons_time)
         _, txns = self.token_ledger.appendTxns([txn])
         self.update_token_state(txn, request)
         self._fees_tracker.fees_in_current_batch += 1
         self._fees_tracker.add_deducted_fees(txn_type, seq_no, fees)
     return None, None, prev_result
Ejemplo n.º 4
0
def write_auth_req_validator(warv, helpers):
    fee_handler = helpers.node.get_fees_req_handler()
    fees_authorizer = FeesAuthorizer(config_state=warv.config_state,
                                     utxo_cache=fee_handler.utxo_cache)

    def _mocked_cpf(self, req, required_fees):
        return req.fees == required_fees, ''

    def _mocked_cffr(self, utxo_cache, request):
        return request.fees

    fees_authorizer.can_pay_fees = functools.partial(_mocked_cpf, fees_authorizer)
    fees_authorizer.calculate_fees_from_req = functools.partial(_mocked_cffr, fees_authorizer)
    warv.register_authorizer(fees_authorizer)
    return warv
Ejemplo n.º 5
0
def register_authentication(node):
    utxo_cache = node.db_manager.get_store(UTXO_CACHE_LABEL)
    token_authnr = node.clientAuthNr.get_authnr_by_type(TokenAuthNr)
    if not token_authnr:
        raise ImportError('sovtoken plugin should be loaded, '  # noqa
                          'authenticator not found')
    fees_authnr = FeesAuthNr(ACCEPTABLE_WRITE_TYPES_FEE, ACCEPTABLE_QUERY_TYPES_FEE, ACCEPTABLE_ACTION_TYPES_FEE,
                             node.db_manager.idr_cache, token_authnr)
    node.clientAuthNr.register_authenticator(fees_authnr)
    fees_authorizer = FeesAuthorizer(config_state=node.getState(CONFIG_LEDGER_ID),
                                     utxo_cache=utxo_cache)
    node.write_req_validator.register_authorizer(fees_authorizer)
    return fees_authnr
Ejemplo n.º 6
0
def integrate_plugin_in_node(node):
    from sovtokenfees.client_authnr import FeesAuthNr
    from sovtokenfees.static_fee_req_handler import StaticFeesReqHandler
    from sovtokenfees.three_phase_commit_handling import \
        ThreePhaseCommitHandler
    from sovtoken import TOKEN_LEDGER_ID
    from sovtoken.client_authnr import TokenAuthNr

    def postCatchupCompleteClb(origin_clb):
        if origin_clb:
            origin_clb()
        fees_req_handler.postCatchupCompleteClbk()

    node.write_req_validator.auth_map.update(sovtokenfees_auth_map)

    token_authnr = node.clientAuthNr.get_authnr_by_type(TokenAuthNr)
    if not token_authnr:
        raise ImportError('sovtoken plugin should be loaded, '  # noqa
                          'authenticator not found')
    token_req_handler = node.get_req_handler(ledger_id=TOKEN_LEDGER_ID)
    if not token_req_handler:
        raise ImportError('sovtoken plugin should be loaded, request '  # noqa
                          'handler not found')

    # `handle_xfer_public_txn` in `TokenReqHandler` checks if the sum of inputs match
    # exactly the sum of outputs. Since the check to match inputs and outputs is done
    # during fees handling the check is avoided in `TokenReqHandler` by monkeypatching
    # `handle_xfer_public_txn` to do nothing.
    token_req_handler.handle_xfer_public_txn = lambda _: None

    token_ledger = token_req_handler.ledger
    token_state = token_req_handler.state
    utxo_cache = token_req_handler.utxo_cache
    fees_authnr = FeesAuthNr(node.getState(DOMAIN_LEDGER_ID), token_authnr)
    fees_req_handler = StaticFeesReqHandler(
        node.configLedger,
        node.getState(CONFIG_LEDGER_ID),
        token_ledger,
        token_state,
        utxo_cache,
        node.getState(DOMAIN_LEDGER_ID),
        node.bls_bft.bls_store,
        node,
        node.write_req_validator,
        ts_store=node.getStateTsDbStorage())
    origin_token_clb = node.ledgerManager.ledgerRegistry[
        TOKEN_LEDGER_ID].postCatchupCompleteClbk
    node.ledgerManager.ledgerRegistry[TOKEN_LEDGER_ID].postCatchupCompleteClbk = \
        functools.partial(postCatchupCompleteClb, origin_token_clb)

    origin_token_post_added_clb = node.ledgerManager.ledgerRegistry[
        TOKEN_LEDGER_ID].postTxnAddedToLedgerClbk

    def filter_fees(ledger_id: int, txn: Any):
        origin_token_post_added_clb(
            ledger_id, txn,
            get_type(txn) != FeesTransactions.FEES.value)

    node.ledgerManager.ledgerRegistry[
        TOKEN_LEDGER_ID].postTxnAddedToLedgerClbk = filter_fees
    node.clientAuthNr.register_authenticator(fees_authnr)
    node_config_req_handler = node.get_req_handler(ledger_id=CONFIG_LEDGER_ID)
    node.unregister_req_handler(node_config_req_handler, CONFIG_LEDGER_ID)
    node.register_req_handler(fees_req_handler, CONFIG_LEDGER_ID)
    fees_authorizer = FeesAuthorizer(
        config_state=node.getState(CONFIG_LEDGER_ID), utxo_cache=utxo_cache)
    node.write_req_validator.register_authorizer(fees_authorizer)
    node.register_hook(NodeHooks.PRE_SIG_VERIFICATION,
                       fees_authnr.verify_signature)
    node.register_hook(NodeHooks.POST_REQUEST_APPLICATION,
                       fees_req_handler.deduct_fees)
    node.register_hook(NodeHooks.POST_REQUEST_COMMIT,
                       fees_req_handler.commit_fee_txns)
    node.register_hook(NodeHooks.POST_BATCH_CREATED,
                       fees_req_handler.post_batch_created)
    node.register_hook(NodeHooks.POST_BATCH_REJECTED,
                       fees_req_handler.post_batch_rejected)
    node.register_hook(NodeHooks.POST_BATCH_COMMITTED,
                       fees_req_handler.post_batch_committed)
    node.register_hook(NodeHooks.POST_NODE_STOPPED,
                       token_req_handler.on_node_stopping)

    three_pc_handler = ThreePhaseCommitHandler(node.master_replica,
                                               token_ledger, token_state,
                                               fees_req_handler)
    node.master_replica.register_hook(ReplicaHooks.CREATE_PPR,
                                      three_pc_handler.add_to_pre_prepare)
    node.master_replica.register_hook(ReplicaHooks.CREATE_PR,
                                      three_pc_handler.add_to_prepare)
    node.master_replica.register_hook(ReplicaHooks.CREATE_ORD,
                                      three_pc_handler.add_to_ordered)
    node.master_replica.register_hook(ReplicaHooks.APPLY_PPR,
                                      three_pc_handler.check_recvd_pre_prepare)

    return node
Ejemplo n.º 7
0
def fees_authorizer(fee_handler):
    return FeesAuthorizer(config_state=fee_handler.state,
                          utxo_cache=fee_handler.utxo_cache)