Ejemplo n.º 1
0
def set_receieved_verification_for_block_from_chain_sync(block_id: str, level: int, chain_id: str) -> None:
    """Signify a successful receipt from a higher level node receipt for a certain block (sync)
    Args:
        block_id: block_id of lvl 1 block for received receipt
        level: level of the node from the higher level receipt
        chain_id: id of the higher level dragonchain receipt
    """
    # Check that this block is accepting verifications for the specified level
    accepting_verification_level = get_current_block_level_sync(block_id)
    if accepting_verification_level != level:
        raise exceptions.NotAcceptingVerifications(
            f"Block {block_id} is only accepting verifications for level {accepting_verification_level} (Not {level}) at the moment"
        )

    set_key = verifications_key(block_id, level)
    p = redis.pipeline_sync()
    p.sadd(set_key, chain_id)
    p.scard(set_key)
    verifications = p.execute()[1]  # Execute the commands and get the result of the scard operation (number of members in the set)
    required = dragonnet_config.DRAGONNET_CONFIG[f"l{level}"]["nodesRequired"]

    # Check if this block needs to be promoted to the next level
    if verifications >= required:
        if level >= 5:
            # If level 5, block needs no more verifications; remove it from the broadcast system
            remove_block_from_broadcast_system_sync(block_id)
        else:
            # Set the block to the next level and schedule it for broadcasting
            redis.delete_sync(storage_error_key(block_id))
            set_current_block_level_sync(block_id, level + 1)
            schedule_block_for_broadcast_sync(block_id)
Ejemplo n.º 2
0
def process_receipt_v1(block_dto: Dict[str, Any]) -> None:
    if not block_dto:
        raise exceptions.ValidationException("block_dto missing")
    _log.info(
        f"[RECEIPT] Got receipt from L{block_dto['header']['level']}: {block_dto}"
    )
    block_model = cast("model.BlockModel",
                       None)  # This will always get defined, or it will raise
    level_received_from: int = block_dto["header"]["level"]
    if level_received_from == 2:
        block_model = l2_block_model.new_from_at_rest(block_dto)
    elif level_received_from == 3:
        block_model = l3_block_model.new_from_at_rest(block_dto)
    elif level_received_from == 4:
        block_model = l4_block_model.new_from_at_rest(block_dto)
    elif level_received_from == 5:
        block_model = l5_block_model.new_from_at_rest(block_dto)
    else:
        raise exceptions.InvalidNodeLevel("Unsupported level receipt")

    _log.info(f"Block model {block_model.__dict__}")
    l1_block_id_set = block_model.get_associated_l1_block_id()

    _log.info(
        f"Processing receipt for blocks {l1_block_id_set} from L{level_received_from}"
    )
    for l1_block_id in l1_block_id_set:
        # Check that the chain which sent this receipt is in our claims, and that this L1 block is accepting receipts for this level
        validations = matchmaking.get_claim_check(
            l1_block_id)["validations"][f"l{level_received_from}"]
        if (
                block_model.dc_id in validations
        ) and broadcast_functions.is_block_accepting_verifications_from_level(
                l1_block_id, level_received_from):
            _log.info(
                f"Verified that block {l1_block_id} was sent. Inserting receipt"
            )
            storage_location = broadcast_functions.verification_storage_location(
                l1_block_id, level_received_from, block_model.dc_id)
            storage.put_object_as_json(storage_location,
                                       block_model.export_as_at_rest())
            # Set new receipt for matchmaking claim check
            try:
                block_id = block_model.block_id
                proof = block_model.proof
                dc_id = block_model.dc_id
                matchmaking.add_receipt(l1_block_id, level_received_from,
                                        dc_id, block_id, proof)
            except Exception:
                _log.exception("matchmaking add_receipt failed!")
            # Update the broadcast system about this receipt
            broadcast_functions.set_receieved_verification_for_block_from_chain_sync(
                l1_block_id, level_received_from, block_model.dc_id)
        else:
            _log.warning(
                f"Chain {block_model.dc_id} (level {level_received_from}) returned a receipt that wasn't expected (possibly expired?) for block {l1_block_id}. Rejecting receipt"  # noqa: B950
            )
            raise exceptions.NotAcceptingVerifications(
                f"Not accepting verifications for block {l1_block_id} from {block_model.dc_id}"
            )
Ejemplo n.º 3
0
 def test_webserver_error_handler_not_accepting_verifications(self, mock_http_response, mock_report_exception):
     exception = exceptions.NotAcceptingVerifications()
     helpers.webserver_error_handler(exception)
     mock_report_exception.assert_not_called()
     mock_http_response.assert_called_once_with(412, ANY)