diff --git a/raiden/network/proxies/token_network_registry.py b/raiden/network/proxies/token_network_registry.py index 3b2e76381c..ee37027ac0 100644 --- a/raiden/network/proxies/token_network_registry.py +++ b/raiden/network/proxies/token_network_registry.py @@ -30,6 +30,7 @@ Address, BlockSpecification, Dict, + SecretRegistryAddress, T_TargetAddress, TokenAddress, TokenAmount, @@ -118,6 +119,7 @@ def add_token( already_registered = self.get_token_network( token_address=token_address, block_identifier=block_identifier ) + secret_registry_address = self.get_secret_registry_address(to_block=block_identifier) except ValueError: # If `block_identifier` has been pruned the checks cannot be performed pass @@ -128,6 +130,11 @@ def add_token( raise BrokenPreconditionError( "The token is already registered in the TokenNetworkRegistry." ) + if secret_registry_address == NULL_ADDRESS_BYTES: + raise RaidenUnrecoverableError( + "Found a TokenNetworkRegistry with secret_registry_address being zero. " + "This is never supposed to happen." + ) return self._add_token( token_address=token_address, @@ -207,6 +214,12 @@ def _add_token( if self.get_token_network(token_address, block): raise RaidenRecoverableError(f"{error_prefix}. Token already registered") + if self.get_secret_registry_address(to_block=block) == NULL_ADDRESS_BYTES: + raise RaidenUnrecoverableError( + f"{error_prefix}. The SecretRegistryAddress in " + "TokenNetworkRegistry has changed to zero. Very weird." + ) + raise RaidenUnrecoverableError(error_prefix) token_network_address = self.get_token_network(token_address, "latest") @@ -269,3 +282,13 @@ def get_max_token_networks(self, to_block: BlockSpecification) -> int: token network registry. """ return self.proxy.contract.functions.max_token_networks().call(block_identifier=to_block) + + def get_secret_registry_address(self, to_block: BlockSpecification) -> SecretRegistryAddress: + """ Returns the SecretRegistry address stored in the TokenNetworkRegistry """ + return SecretRegistryAddress( + to_canonical_address( + self.proxy.contract.functions.secret_registry_address().call( + block_identifier=to_block + ) + ) + ) diff --git a/raiden/tests/integration/network/proxies/test_token_network_registry.py b/raiden/tests/integration/network/proxies/test_token_network_registry.py index cbea4ae6bf..b57f2e02d5 100644 --- a/raiden/tests/integration/network/proxies/test_token_network_registry.py +++ b/raiden/tests/integration/network/proxies/test_token_network_registry.py @@ -11,12 +11,18 @@ RaidenRecoverableError, ) from raiden.network.blockchain_service import BlockChainService, BlockChainServiceMetadata +from raiden.network.proxies.metadata import SmartContractMetadata from raiden.network.proxies.token import Token +from raiden.network.proxies.token_network_registry import TokenNetworkRegistry from raiden.network.rpc.client import JSONRPCClient from raiden.tests.utils.factories import make_token_address from raiden.tests.utils.smartcontracts import deploy_token from raiden.utils.typing import TokenAddress, TokenAmount, TokenNetworkRegistryAddress -from raiden_contracts.constants import TEST_SETTLE_TIMEOUT_MAX, TEST_SETTLE_TIMEOUT_MIN +from raiden_contracts.constants import ( + CONTRACT_TOKEN_NETWORK_REGISTRY, + TEST_SETTLE_TIMEOUT_MAX, + TEST_SETTLE_TIMEOUT_MIN, +) from raiden_contracts.contract_manager import ContractManager @@ -164,3 +170,32 @@ def test_token_network_registry_with_zero_token_address( token_network_deposit_limit=TokenAmount(UINT256_MAX), block_identifier=deploy_client.get_confirmed_blockhash(), ) + + +def test_token_network_registry_get_secret_registry_address( + deploy_client, token_network_registry_address, contract_manager, secret_registry_address +): + """ get_secret_registry_address() should return the address of SecretRegistry """ + blockchain_service = BlockChainService( + jsonrpc_client=deploy_client, + contract_manager=contract_manager, + metadata=BlockChainServiceMetadata( + token_network_registry_deployed_at=GENESIS_BLOCK_NUMBER, + filters_start_at=GENESIS_BLOCK_NUMBER, + ), + ) + token_network_registry_metadata = SmartContractMetadata( + deployed_at=GENESIS_BLOCK_NUMBER, + filters_start_at=GENESIS_BLOCK_NUMBER, + address=to_canonical_address(token_network_registry_address), + abi=contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK_REGISTRY), + ) + token_network_registry_proxy = TokenNetworkRegistry( + jsonrpc_client=deploy_client, + metadata=token_network_registry_metadata, + blockchain_service=blockchain_service, + ) + assert ( + token_network_registry_proxy.get_secret_registry_address(to_block="latest") + == secret_registry_address + )