def test_is_publisher_allowed():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)
    processor = MetadataCreatedProcessor(event_sample, None, web3, None, None,
                                         None, None, None)
    processor.allowed_publishers = None
    assert processor.is_publisher_allowed(processor.sender_address) is True
Example #2
0
def test_events_monitor_object(monkeypatch):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monkeypatch.setenv("ALLOWED_PUBLISHERS", "can not be converted to a set")
    monitor = EventsMonitor(setup_web3(config_file), config_file)
    assert monitor._allowed_publishers == set()

    monkeypatch.setenv("OCN_EVENTS_MONITOR_QUITE_TIME",
                       "can not be converted to int")
    monitor = EventsMonitor(setup_web3(config_file), config_file)
    assert monitor._monitor_sleep_time == 10

    monkeypatch.setenv("EVENTS_CLEAN_START", "1")
    with patch("aquarius.events.events_monitor.EventsMonitor.reset_chain"
               ) as mock:
        monitor = EventsMonitor(setup_web3(config_file), config_file)
        mock.assert_called_once()
def test_order_started_processor():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)

    test_account1 = Account.from_key(
        os.environ.get("EVENTS_TESTS_PRIVATE_KEY", None))
    dt_address = deploy_datatoken(web3, test_account1, "TT1", "TT1Symbol")

    es_instance = Mock()
    es_instance.read.return_value = {
        "sample_asset": "mock",
        "stats": {
            "orders": 0
        }
    }
    es_instance.update.return_value = None

    price_json = {
        "value": 12.4,
        "tokenAddress": "test",
        "tokenSymbol": "test2"
    }

    processor = OrderStartedProcessor(dt_address, es_instance, 0, 0)
    with patch(
            "aquarius.events.processors.get_number_orders_price") as no_mock:
        no_mock.return_value = 3, price_json
        updated_asset = processor.process()

    assert es_instance.update.called_once()
    assert updated_asset["stats"]["orders"] == 3
    assert updated_asset["stats"]["price"] == price_json
Example #4
0
def test_deploy_datatoken_fails():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)
    test_account1 = Account.from_key(os.environ.get("EVENTS_TESTS_PRIVATE_KEY", None))
    with patch.object(type(web3.eth), "getTransactionReceipt") as mock:
        mock.side_effect = Exception()
        with pytest.raises(Exception, match="tx not found"):
            deploy_datatoken(web3, test_account1, "TT1", "TT1Symbol")
Example #5
0
def test_start_stop_events_monitor():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monitor = EventsMonitor(setup_web3(config_file), config_file)

    monitor._monitor_is_on = True
    assert monitor.start_events_monitor() is None

    monitor = EventsMonitor(setup_web3(config_file), config_file)
    monitor._contract_address = None
    assert monitor.start_events_monitor() is None

    monitor = EventsMonitor(setup_web3(config_file), config_file)
    monitor._contract = None
    assert monitor.start_events_monitor() is None

    monitor = EventsMonitor(setup_web3(config_file), config_file)
    with patch("aquarius.events.events_monitor.Thread.start") as mock:
        monitor.start_events_monitor()
        mock.assert_called_once()

    monitor.stop_monitor()
def test_drop_non_factory():
    dt_factory = Mock()
    dt_factory.caller = Mock()
    dt_factory.caller.erc721List.return_value = "not the address"

    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)

    processor = MetadataCreatedProcessor(event_sample, None, None, None, web3,
                                         None, None, None)

    with patch("aquarius.events.processors.get_dt_factory") as mock2:
        mock2.return_value = dt_factory
        assert not processor.process()
Example #7
0
def test_run_monitor_purgatory(monkeypatch):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monkeypatch.setenv(
        "ASSET_PURGATORY_URL",
        "https://raw.githubusercontent.com/oceanprotocol/list-purgatory/main/list-assets.json",
    )
    monitor = EventsMonitor(setup_web3(config_file), config_file)
    monitor._monitor_is_on = True
    with patch("aquarius.events.purgatory.Purgatory.update_lists") as mock:
        monitor.do_run_monitor()
        mock.assert_called_once()

    with patch("aquarius.events.purgatory.Purgatory.update_lists") as mock:
        mock.side_effect = Exception("Boom!")
        monitor.do_run_monitor()
def test_order_started_processor_no_asset():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)

    test_account1 = Account.from_key(
        os.environ.get("EVENTS_TESTS_PRIVATE_KEY", None))
    dt_address = deploy_datatoken(web3, test_account1, "TT1", "TT1Symbol")

    es_instance = Mock()
    es_instance.read.return_value = None

    processor = OrderStartedProcessor(dt_address, es_instance, 0, 0)
    updated_asset = processor.process()

    assert not es_instance.update.called
    assert updated_asset is None
def test_do_decode_update():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)
    processor = MetadataUpdatedProcessor(event_updated_sample, None, web3,
                                         None, None, None, None, None)

    processor.block = 0
    old_asset = {
        "event": {
            "block": 100,
            "tx": "placeholder"
        },
        "publicKey": [{
            "owner": "some_address"
        }],
    }
    assert processor.check_update(None, old_asset, "") is False
Example #10
0
def test_run_monitor(monkeypatch):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monitor = EventsMonitor(setup_web3(config_file), config_file)
    monitor.sleep_time = 1

    monitor._monitor_is_on = False
    assert monitor.do_run_monitor() is None

    monitor._monitor_is_on = True
    with patch(
            "aquarius.events.events_monitor.EventsMonitor.process_current_blocks"
    ) as mock:
        mock.side_effect = Exception("Boom!")
        assert monitor.do_run_monitor() is None

    with patch(
            "aquarius.events.events_monitor.EventsMonitor.process_current_blocks"
    ) as mock:
        monitor.do_run_monitor()
        mock.assert_called_once()
Example #11
0
def test_process_block_range(client, base_ddo_url, events_object):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monitor = EventsMonitor(setup_web3(config_file), config_file)
    assert monitor.process_block_range(
        13, 10) is None  # not processing if from > to

    _ddo = new_ddo(test_account1, get_web3(), "dt.0")
    send_create_update_tx("create", _ddo, bytes([2]), test_account1)

    with patch(
            "aquarius.events.events_monitor.MetadataCreatedProcessor.process"
    ) as mock:
        mock.side_effect = Exception("Boom!")
        assert events_object.process_current_blocks() is None

    send_create_update_tx("update", _ddo, bytes([2]), test_account1)
    with patch(
            "aquarius.events.events_monitor.MetadataUpdatedProcessor.process"
    ) as mock:
        mock.side_effect = Exception("Boom!")
        assert events_object.process_current_blocks() is None
Example #12
0
def test_process_fallback(monkeypatch, client, base_ddo_url, events_object):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)
    block = web3.eth.block_number
    _ddo = new_ddo(test_account1, web3, f"dt.{block}")
    did = _ddo.id
    send_create_update_tx("create", _ddo, bytes([2]), test_account1)
    events_object.process_current_blocks()
    published_ddo = get_ddo(client, base_ddo_url, did)
    assert published_ddo["id"] == did

    events_object._es_instance.delete(did)

    _ddo["metadata"]["name"] = "Updated ddo by event"
    send_create_update_tx("update", _ddo, bytes(2), test_account1)

    # falls back on the MetadataCreatedProcessor
    # since no es instance means read will throw an Exception
    with patch("aquarius.events.processors.MetadataCreatedProcessor.process"
               ) as mock:
        events_object.process_current_blocks()
        mock.assert_called()
def test_check_metadata_proofs(monkeypatch):
    # empty env var => everything is validated
    monkeypatch.delenv("ALLOWED_VALIDATORS", None)
    assert check_metadata_proofs(None, "whatever_it_works")

    # wrong env var => nothing is validated
    monkeypatch.setenv("ALLOWED_VALIDATORS", "not a json")
    assert not check_metadata_proofs(None, "whatever_it_works")

    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)

    random_addresses = []
    random_dicts = []

    for i in range(5):
        random_address = web3.eth.account.create().address
        random_addresses.append(random_address)
        random_dicts.append(
            AttributeDict({"args": AttributeDict({"validator": random_address})})
        )

    monkeypatch.setenv(
        "ALLOWED_VALIDATORS", json.dumps([random_addresses[0], random_addresses[1]])
    )
    assert check_metadata_proofs(web3, [random_dicts[0]])
    assert check_metadata_proofs(web3, [random_dicts[1]])
    assert not check_metadata_proofs(web3, [random_dicts[2]])
    assert not check_metadata_proofs(web3, [random_dicts[2], random_dicts[3]])
    assert check_metadata_proofs(web3, [random_dicts[0], random_dicts[3]])
    assert check_metadata_proofs(web3, [random_dicts[0], random_dicts[0]])

    # no metadata proofs set
    assert not check_metadata_proofs(web3, [])
    assert not check_metadata_proofs(web3, [])

    # no validators set
    monkeypatch.setenv("ALLOWED_VALIDATORS", json.dumps([]))
    assert check_metadata_proofs(web3, [random_dicts[4]])
Example #14
0
def run_events_monitor():
    setup_logging()
    logger.info("EventsMonitor: preparing")
    required_env_vars = ["EVENTS_RPC", "AQUARIUS_CONFIG_FILE"]
    for envvar in required_env_vars:
        if not os.getenv(envvar):
            raise AssertionError(
                f"env var {envvar} is missing, make sure to set the following "
                f"environment variables before starting the events monitor: {required_env_vars}"
            )

    config_file = os.getenv("AQUARIUS_CONFIG_FILE", "config.ini")
    monitor = EventsMonitor(setup_web3(config_file, logger), config_file)
    monitor.start_events_monitor()

    logger.info("EventsMonitor: started")
    if os.getenv("EVENTS_HTTP", None):
        logger.info("Events HTTP probing started on port 5001..")
        httpd = socketserver.TCPServer(("", 5001), Handler)
        httpd.serve_forever()
    else:
        while True:
            time.sleep(5)
Example #15
0
def trigger_caching():
    """Triggers manual caching of a specific transaction (MetadataCreated or MetadataUpdated event)
    ---
    tags:
      - name
    consumes:
      - application/json
    parameters:
      - name: transactionId
        required: true
        description: transaction id containing MetadataCreated or MetadataUpdated event
      - name: logIndex
        required: false
        description: zero-based index in log if transaction contains more events
    responses:
      200:
        description: successful operation.
      400:
        description: bad request. Log index not found or event not found.
      500:
        description: server error/exception
    """
    try:
        data = request.args if request.args else request.json
        tx_id = data.get("transactionId")
        log_index = int(data.get("logIndex", 0))

        config_file = app.config["AQUARIUS_CONFIG_FILE"]
        web3 = setup_web3(config_file)
        tx_receipt = web3.eth.wait_for_transaction_receipt(tx_id)

        if len(tx_receipt.logs) <= log_index or log_index < 0:
            return jsonify(error=f"Log index {log_index} not found"), 400

        dt_address = tx_receipt.logs[log_index].address
        dt_contract = web3.eth.contract(
            abi=ERC721Template.abi, address=web3.toChecksumAddress(dt_address))
        created_event = dt_contract.events.MetadataCreated().processReceipt(
            tx_receipt, errors=DISCARD)
        updated_event = dt_contract.events.MetadataUpdated().processReceipt(
            tx_receipt, errors=DISCARD)

        if not created_event and not updated_event:
            return jsonify(
                error="No metadata created/updated event found in tx."), 400

        es_instance = ElasticsearchInstance(config_file)
        allowed_publishers = get_allowed_publishers()
        purgatory = (Purgatory(es_instance) if
                     (os.getenv("ASSET_PURGATORY_URL")
                      or os.getenv("ACCOUNT_PURGATORY_URL")) else None)
        chain_id = web3.eth.chain_id
        processor_args = [
            es_instance, web3, allowed_publishers, purgatory, chain_id
        ]

        processor = (MetadataCreatedProcessor
                     if created_event else MetadataUpdatedProcessor)
        event_to_process = created_event[
            0] if created_event else updated_event[0]
        event_processor = processor(
            *([event_to_process, dt_contract, tx_receipt["from"]] +
              processor_args))
        event_processor.process()
        did = make_did(dt_address, chain_id)

        response = app.response_class(
            response=sanitize_record(es_instance.get(did)),
            status=200,
            mimetype="application/json",
        )
        return response
    except Exception as e:
        logger.error(f"trigger_caching failed: {str(e)}.")
        return (
            jsonify(
                error=f"Encountered error when triggering caching: {str(e)}."),
            500,
        )
Example #16
0
def test_missing_attributes():
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    web3 = setup_web3(config_file)

    test_account1 = Account.from_key(
        os.environ.get("EVENTS_TESTS_PRIVATE_KEY", None))
    dt_address = deploy_datatoken(web3, test_account1, "TT1", "TT1Symbol")
    dt_contract = web3.eth.contract(abi=ERC721Template.abi,
                                    address=web3.toChecksumAddress(dt_address))

    dt_factory = Mock()
    dt_factory.caller = Mock()
    dt_factory.caller.erc721List.return_value = (
        "0x0000000000000000000000000000000000000000")

    processor = MetadataCreatedProcessor(event_sample, None, None, None, web3,
                                         None, None, None)

    assert processor._get_contract_attribute(dt_contract, "non_existent") == ""
    assert processor._get_contract_attribute(dt_contract,
                                             "symbol") == "TT1Symbol"

    processor.dt_contract = Mock(spec=ERC721Template)
    processor.caller = Mock()
    processor.caller.ownerOf.side_effect = Exception()
    assert processor.get_nft_owner() == ""

    processor.event = Mock()
    processor.event.args.decryptorUrl = ""
    processor.event.args.metaDataHash = ""
    processor.event.args.address = ""
    processor.event.address = "0x0000000000000000000000000000000000000000"

    with patch("aquarius.events.processors.decrypt_ddo") as mock:
        mock.return_value = None
        with patch("aquarius.events.processors.get_dt_factory") as mock2:
            mock2.return_value = dt_factory
            with pytest.raises(Exception, match="Decrypt ddo failed"):
                processor.process()

    processor = MetadataUpdatedProcessor(event_sample, None, None, None, web3,
                                         None, None, None)

    assert processor._get_contract_attribute(dt_contract, "non_existent") == ""
    assert processor._get_contract_attribute(dt_contract,
                                             "symbol") == "TT1Symbol"

    processor.dt_contract = Mock(spec=ERC721Template)
    processor.caller = Mock()
    processor.caller.ownerOf.side_effect = Exception()
    assert processor.get_nft_owner() == ""

    processor.event = Mock()
    processor.event.args.decryptorUrl = ""
    processor.event.args.metaDataHash = ""
    processor.event.address = "0x0000000000000000000000000000000000000000"

    with patch("aquarius.events.processors.decrypt_ddo") as mock:
        mock.return_value = None
        with patch("aquarius.events.processors.get_dt_factory") as mock2:
            mock2.return_value = dt_factory
            with pytest.raises(Exception, match="Decrypt ddo failed"):
                processor.process()
Example #17
0
        id=index_name,
        body=record,
        doc_type="_doc",
        refresh="wait_for",
    )["_id"]

    print("OK")


def get_status():
    if Elasticsearch(config.db_url).ping():
        return "Elasticsearch connected", 200
    else:
        return "Not connected to any database", 400


# Start events monitoring if required
if get_bool_env_value("EVENTS_ALLOW", 0):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monitor = EventsMonitor(setup_web3(config_file), config_file)
    monitor.start_events_monitor()

if __name__ == "__main__":
    if isinstance(config.aquarius_url.split(":")[-1], int):
        app.run(
            host=config.aquarius_url.split(":")[1],
            port=config.aquarius_url.split(":")[-1],
        )
    else:
        app.run()
Example #18
0
def test_setup_web3(monkeypatch):
    config_file = app.config["AQUARIUS_CONFIG_FILE"]
    monkeypatch.setenv("NETWORK_NAME", "rinkeby")
    assert setup_web3(config_file, logger)