Example #1
0
def secret_registry_batch_happy_path(
        web3: Web3, secret_registry_proxy: SecretRegistry) -> None:
    secrets = [make_secret() for i in range(4)]
    secrethashes = [sha256_secrethash(secret) for secret in secrets]

    secret_registered_filter = secret_registry_proxy.secret_registered_filter(
        GENESIS_BLOCK_NUMBER)
    secret_registry_proxy.register_secret_batch(secrets=secrets)

    logs = [
        secret_registry_proxy.proxy.decode_event(log) for log in
        secret_registered_filter.get_new_entries(web3.eth.blockNumber)
    ]

    for secrethash in secrethashes:
        secret_registered = must_have_event(logs, {
            "event": "SecretRevealed",
            "args": {
                "secrethash": secrethash
            }
        })
        assert secret_registered, "All secrets from the batch must be registered"

        block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
            secrethash=secrethash, block_identifier="latest")
        msg = "Block number reported by the proxy and the event must match"
        assert block == secret_registered["blockNumber"], msg
def secret_registry_batch_happy_path(
        proxy_manager: ProxyManager,
        secret_registry_proxy: SecretRegistry) -> None:
    secrets = [make_secret() for i in range(4)]
    secrethashes = [sha256_secrethash(secret) for secret in secrets]

    secret_registry_proxy.register_secret_batch(secrets=secrets)

    logs = get_secret_registry_events(
        proxy_manager=proxy_manager,
        secret_registry_address=secret_registry_proxy.address,
        contract_manager=secret_registry_proxy.contract_manager,
    )

    for secrethash in secrethashes:
        secret_registered = must_have_event(logs, {
            "event": "SecretRevealed",
            "args": {
                "secrethash": secrethash
            }
        })
        assert secret_registered, "All secrets from the batch must be registered"

        block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
            secrethash=secrethash, block_identifier="latest")
        msg = "Block number reported by the proxy and the event must match"
        assert block == secret_registered["block_number"], msg
Example #3
0
def secret_registry_batch_happy_path(
    proxy_manager: ProxyManager, secret_registry_proxy: SecretRegistry
) -> None:
    secrets = [make_secret() for i in range(4)]
    secrethashes = [sha256_secrethash(secret) for secret in secrets]

    transaction_hashes = secret_registry_proxy.register_secret_batch(secrets=secrets)
    for tx_hash in transaction_hashes:
        assert is_tx_hash_bytes(tx_hash)

    logs = get_contract_events(
        proxy_manager=proxy_manager,
        abi=proxy_manager.contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY),
        contract_address=Address(secret_registry_proxy.address),
    )

    for secrethash in secrethashes:
        secret_registered = must_have_event(
            logs, {"event": "SecretRevealed", "args": {"secrethash": secrethash}}
        )
        assert secret_registered, "All secrets from the batch must be registered"

        block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
            secrethash=secrethash, block_identifier=BLOCK_ID_LATEST
        )
        msg = "Block number reported by the proxy and the event must match"
        assert block == secret_registered["block_number"], msg
Example #4
0
def test_register_secret_happy_path(secret_registry_proxy: SecretRegistry,
                                    contract_manager):
    """Test happy path of SecretRegistry with a single secret.

    Test that `register_secret` changes the smart contract state by registering
    the secret, this can be verified by the block height and the existence of
    the SecretRegistered event.
    """
    secret = make_secret()
    secrethash = keccak(secret)
    secret_unregistered = make_secret()
    secrethash_unregistered = keccak(secret_unregistered)

    secret_registered_filter = secret_registry_proxy.secret_registered_filter()

    assert not secret_registry_proxy.is_secret_registered(
        secrethash=secrethash, block_identifier="latest"
    ), "Test setup is invalid, secret must be unknown"
    assert not secret_registry_proxy.is_secret_registered(
        secrethash=secrethash_unregistered, block_identifier="latest"
    ), "Test setup is invalid, secret must be unknown"

    chain = BlockChainService(jsonrpc_client=secret_registry_proxy.client,
                              contract_manager=contract_manager)
    chain.wait_until_block(STATE_PRUNING_AFTER_BLOCKS + 1)

    with pytest.raises(NoStateForBlockIdentifier):
        secret_registry_proxy.is_secret_registered(
            secrethash=secrethash_unregistered, block_identifier=0)

    secret_registry_proxy.register_secret(secret=secret)

    logs = [
        secret_registry_proxy.proxy.decode_event(encoded_log)
        for encoded_log in secret_registered_filter.get_all_entries()
    ]
    secret_registered = must_have_event(logs, {
        "event": "SecretRevealed",
        "args": {
            "secrethash": secrethash
        }
    })

    msg = "SecretRegistry.register_secret returned but the SecretRevealed event was not emitted."
    assert secret_registered, msg

    registered_block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
        secrethash=secrethash, block_identifier="latest")
    msg = (
        "Block height returned by the SecretRegistry.get_secret_registration_block_by_secrethash "
        "does not match the block from the SecretRevealed event.")
    assert secret_registered["blockNumber"] == registered_block, msg

    block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
        secrethash=secrethash_unregistered, block_identifier="latest")
    assert block is None, "The secret that was not registered must not change block height!"
Example #5
0
def check_ethereum_confirmed_block_is_not_pruned(
    jsonrpc_client: JSONRPCClient, secret_registry: SecretRegistry, confirmation_blocks: int
) -> None:
    """Checks the Ethereum client is not pruning data too aggressively, because
    in some circunstances it is necessary for a node to fetch additional data
    from the smart contract.
    """
    unconfirmed_block_number = jsonrpc_client.block_number()

    # This is a small error margin. It is possible during normal operation for:
    #
    # - AlarmTask sees a new block and calls RaidenService._callback_new_block
    # - The service gets the current latest block number and computes the
    #   confirmed block number.
    # - The service fetches every filter, this can take a while.
    # - While the above is happening, it is possible for a `few_blocks` to be
    #   mined.
    # - The decode function is called, and tries to access what it thinks is
    #   the latest_confirmed_block, but it is in reality `few_blocks` older.
    #
    # This value bellow is the expected drift, that allows the decode function
    # mentioned above to work properly.
    maximum_delay_to_process_a_block = 2

    minimum_available_history = confirmation_blocks + maximum_delay_to_process_a_block
    target_confirmed_block = unconfirmed_block_number - minimum_available_history

    try:
        # Using the secret registry is arbitrary, any proxy with an `eth_call`
        # would work here.
        secret_registry.get_secret_registration_block_by_secrethash(
            EMPTY_SECRETHASH, block_identifier=target_confirmed_block
        )
    except ValueError:
        # If this exception is raised the Ethereum node is too aggressive with
        # the block pruning.
        click.secho(
            f"The ethereum client does not have the necessary data available. "
            f"The client can not operate because the prunning strategy is too "
            f"agressive. Please make sure that at very minimum "
            f"{minimum_available_history} blocks of history are available.",
            fg="red",
        )
        sys.exit(1)
Example #6
0
    def secret_registry(self, address: Address) -> SecretRegistry:
        if not is_binary_address(address):
            raise ValueError("address must be a valid address")

        with self._secret_registry_creation_lock:
            if address not in self.address_to_secret_registry:
                self.address_to_secret_registry[address] = SecretRegistry(
                    jsonrpc_client=self.client,
                    secret_registry_address=address,
                    contract_manager=self.contract_manager,
                )

        return self.address_to_secret_registry[address]
Example #7
0
 def add_secret_registry_listener(
     self,
     secret_registry_proxy: SecretRegistry,
     contract_manager: ContractManager,
     from_block: typing.BlockSpecification = 'latest',
 ):
     secret_registry_filter = secret_registry_proxy.secret_registered_filter(
         from_block=from_block, )
     secret_registry_address = secret_registry_proxy.address
     self.add_event_listener(
         'SecretRegistry {}'.format(pex(secret_registry_address)),
         secret_registry_filter,
         contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY),
     )
Example #8
0
def secret_registry_proxy(deploy_client, secret_registry_address,
                          contract_manager):
    """This uses the available SecretRegistry JSONRPCClient proxy to
    instantiate a Raiden proxy.

    The JSONRPCClient proxy just exposes the functions from the smart contract
    as methods in a generate python object, the Raiden proxy uses it to
    provider alternative interfaces *and* most importantly to do additional
    error checking (reason for transaction failure, gas usage, etc.).
    """
    return SecretRegistry(
        jsonrpc_client=deploy_client,
        secret_registry_address=to_canonical_address(secret_registry_address),
        contract_manager=contract_manager,
    )
Example #9
0
 def add_secret_registry_listener(
     self,
     secret_registry_proxy: SecretRegistry,
     contract_manager: ContractManager,
     from_block: BlockNumber,
 ) -> None:
     secret_registry_filter = secret_registry_proxy.secret_registered_filter(
         from_block=from_block
     )
     secret_registry_address = secret_registry_proxy.address
     self.add_event_listener(
         "SecretRegistry {}".format(to_checksum_address(secret_registry_address)),
         secret_registry_filter,
         contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY),
     )
Example #10
0
def secret_registry_proxy_fixture(
    deploy_client: JSONRPCClient,
    secret_registry_address: SecretRegistryAddress,
    contract_manager: ContractManager,
) -> SecretRegistry:
    """This uses the available SecretRegistry JSONRPCClient proxy to
    instantiate a Raiden proxy.

    The JSONRPCClient proxy just exposes the functions from the smart contract
    as methods in a generate python object, the Raiden proxy uses it to
    provider alternative interfaces *and* most importantly to do additional
    error checking (reason for transaction failure, gas usage, etc.).
    """
    return SecretRegistry(
        jsonrpc_client=deploy_client,
        secret_registry_address=secret_registry_address,
        contract_manager=contract_manager,
        block_identifier=BLOCK_ID_LATEST,
    )
Example #11
0
def test_register_secret_happy_path(web3: Web3,
                                    secret_registry_proxy: SecretRegistry,
                                    contract_manager: ContractManager) -> None:
    """Test happy path of SecretRegistry with a single secret.

    Test that `register_secret` changes the smart contract state by registering
    the secret, this can be verified by the block height and the existence of
    the SecretRegistered event.
    """
    secret = make_secret()
    secrethash = sha256_secrethash(secret)
    secret_unregistered = make_secret()
    secrethash_unregistered = sha256_secrethash(secret_unregistered)

    secret_registered_filter = secret_registry_proxy.secret_registered_filter(
        GENESIS_BLOCK_NUMBER)

    assert not secret_registry_proxy.is_secret_registered(
        secrethash=secrethash, block_identifier="latest"
    ), "Test setup is invalid, secret must be unknown"
    assert not secret_registry_proxy.is_secret_registered(
        secrethash=secrethash_unregistered, block_identifier="latest"
    ), "Test setup is invalid, secret must be unknown"

    proxy_manager = ProxyManager(
        rpc_client=secret_registry_proxy.client,
        contract_manager=contract_manager,
        metadata=ProxyManagerMetadata(
            token_network_registry_deployed_at=GENESIS_BLOCK_NUMBER,
            filters_start_at=GENESIS_BLOCK_NUMBER,
        ),
    )
    proxy_manager.wait_until_block(BlockNumber(STATE_PRUNING_AFTER_BLOCKS + 1))

    with pytest.raises(NoStateForBlockIdentifier):
        secret_registry_proxy.is_secret_registered(
            secrethash=secrethash_unregistered, block_identifier=0)

    secret_registry_proxy.register_secret(secret=secret)

    logs = [
        secret_registry_proxy.proxy.decode_event(encoded_log) for encoded_log
        in secret_registered_filter.get_new_entries(web3.eth.blockNumber)
    ]
    secret_registered = must_have_event(logs, {
        "event": "SecretRevealed",
        "args": {
            "secrethash": secrethash
        }
    })

    msg = "SecretRegistry.register_secret returned but the SecretRevealed event was not emitted."
    assert secret_registered, msg

    registered_block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
        secrethash=secrethash, block_identifier="latest")
    msg = (
        "Block height returned by the SecretRegistry.get_secret_registration_block_by_secrethash "
        "does not match the block from the SecretRevealed event.")
    assert secret_registered["blockNumber"] == registered_block, msg

    block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
        secrethash=secrethash_unregistered, block_identifier="latest")
    assert block is None, "The secret that was not registered must not change block height!"
Example #12
0
def test_register_secret_happy_path(
    secret_registry_proxy: SecretRegistry, contract_manager: ContractManager
) -> None:
    """Test happy path of SecretRegistry with a single secret.

    Test that `register_secret` changes the smart contract state by registering
    the secret, this can be verified by the block height and the existence of
    the SecretRegistered event.
    """
    secret = make_secret()
    secrethash = sha256_secrethash(secret)
    secret_unregistered = make_secret()
    secrethash_unregistered = sha256_secrethash(secret_unregistered)

    assert not secret_registry_proxy.is_secret_registered(
        secrethash=secrethash, block_identifier=BLOCK_ID_LATEST
    ), "Test setup is invalid, secret must be unknown"
    assert not secret_registry_proxy.is_secret_registered(
        secrethash=secrethash_unregistered, block_identifier=BLOCK_ID_LATEST
    ), "Test setup is invalid, secret must be unknown"

    secret_registry_proxy.client.wait_until_block(BlockNumber(STATE_PRUNING_AFTER_BLOCKS + 1))

    with pytest.raises(NoStateForBlockIdentifier):
        secret_registry_proxy.is_secret_registered(
            secrethash=secrethash_unregistered, block_identifier=BlockNumber(0)
        )

    secret_registry_proxy.register_secret(secret=secret)

    proxy_manager = ProxyManager(
        rpc_client=secret_registry_proxy.client,
        contract_manager=contract_manager,
        metadata=ProxyManagerMetadata(
            token_network_registry_deployed_at=GENESIS_BLOCK_NUMBER,
            filters_start_at=GENESIS_BLOCK_NUMBER,
        ),
    )
    logs = get_contract_events(
        proxy_manager=proxy_manager,
        abi=proxy_manager.contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY),
        contract_address=Address(secret_registry_proxy.address),
    )
    secret_registered = must_have_event(
        logs, {"event": "SecretRevealed", "args": {"secrethash": secrethash}}
    )

    msg = "SecretRegistry.register_secret returned but the SecretRevealed event was not emitted."
    assert secret_registered, msg

    registered_block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
        secrethash=secrethash, block_identifier=BLOCK_ID_LATEST
    )
    msg = (
        "Block height returned by the SecretRegistry.get_secret_registration_block_by_secrethash "
        "does not match the block from the SecretRevealed event."
    )
    assert secret_registered["block_number"] == registered_block, msg

    block = secret_registry_proxy.get_secret_registration_block_by_secrethash(
        secrethash=secrethash_unregistered, block_identifier=BLOCK_ID_LATEST
    )
    assert block is None, "The secret that was not registered must not change block height!"