def test_initiator_handle_contract_receive_secret_reveal(): """ Make sure the initiator handles ContractReceiveSecretReveal and checks the existence of the transfer's secrethash in secrethashes_to_lockedlocks and secrethashes_to_onchain_unlockedlocks. """ amount = UNIT_TRANSFER_AMOUNT * 2 block_number = 1 refund_pkey, refund_address = factories.make_privkey_address() pseudo_random_generator = random.Random() channel1 = factories.make_channel( our_balance=amount, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) pseudo_random_generator = random.Random() channel_map = { channel1.identifier: channel1, } available_routes = [ factories.route_from_channel(channel1), ] block_number = 10 current_state = make_initiator_manager_state( routes=available_routes, transfer_description=factories.UNIT_TRANSFER_DESCRIPTION, channel_map=channel_map, pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) transfer = current_state.initiator.transfer assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, ) initiator_manager.handle_onchain_secretreveal( payment_state=current_state, state_change=state_change, channelidentifiers_to_channels=channel_map, pseudo_random_generator=pseudo_random_generator, ) assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_onchain_unlockedlocks
def test_initiator_handle_contract_receive_secret_reveal_expired(): """ Initiator must *not* unlock off-chain if the secret is revealed on-chain *after* the lock expiration. """ setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=10) transfer = setup.current_state.initiator.transfer assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, block_number=transfer.lock.expiration + 1, ) iteration = initiator_manager.handle_onchain_secretreveal( payment_state=setup.current_state, state_change=state_change, channelidentifiers_to_channels=setup.channel_map, pseudo_random_generator=setup.prng, ) assert events.must_contain_entry(iteration.events, SendBalanceProof, {}) is None
def test_initiator_handle_contract_receive_secret_reveal(): """ Initiator must unlock off-chain if the secret is revealed on-chain and the channel is open. """ setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=10) transfer = setup.current_state.initiator.transfer assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, block_number=transfer.lock.expiration, ) message_identifier = message_identifier_from_prng(deepcopy(setup.prng)) iteration = initiator_manager.handle_onchain_secretreveal( payment_state=setup.current_state, state_change=state_change, channelidentifiers_to_channels=setup.channel_map, pseudo_random_generator=setup.prng, ) payment_identifier = setup.current_state.initiator.transfer_description.payment_identifier assert events.must_contain_entry( iteration.events, SendBalanceProof, { 'message_identifier': message_identifier, 'payment_identifier': payment_identifier, })
def test_initiator_handle_contract_receive_emptyhash_secret_reveal(): """ Initiator must not accept contract receive secret reveal with emptyhash """ setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=10) transfer = setup.current_state.initiator.transfer assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=EMPTY_HASH, block_number=transfer.lock.expiration, ) iteration = initiator_manager.handle_onchain_secretreveal( payment_state=setup.current_state, state_change=state_change, channelidentifiers_to_channels=setup.channel_map, pseudo_random_generator=setup.prng, ) assert len(iteration.events) == 0 # make sure the original lock wasn't moved assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks
def test_initiator_handle_contract_receive_secret_reveal(): """ Initiator must unlock off-chain if the secret is revealed on-chain and the channel is open. """ setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=10) transfer = setup.current_state.initiator.transfer assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, block_number=transfer.lock.expiration, ) message_identifier = message_identifier_from_prng(deepcopy(setup.prng)) iteration = initiator_manager.handle_onchain_secretreveal( payment_state=setup.current_state, state_change=state_change, channelidentifiers_to_channels=setup.channel_map, pseudo_random_generator=setup.prng, ) payment_identifier = setup.current_state.initiator.transfer_description.payment_identifier assert events.must_contain_entry(iteration.events, SendBalanceProof, { 'message_identifier': message_identifier, 'payment_identifier': payment_identifier, })
def test_initiator_handle_contract_receive_secret_reveal(): """ Initiator must unlock off-chain if the secret is revealed on-chain and the channel is open. """ amount = UNIT_TRANSFER_AMOUNT * 2 channel1 = factories.make_channel( our_balance=amount, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) pseudo_random_generator = random.Random() channel_map = { channel1.identifier: channel1, } available_routes = [ factories.route_from_channel(channel1), ] block_number = 10 current_state = make_initiator_manager_state( routes=available_routes, transfer_description=factories.UNIT_TRANSFER_DESCRIPTION, channel_map=channel_map, pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) transfer = current_state.initiator.transfer assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, block_number=transfer.lock.expiration, ) message_identifier = message_identifier_from_prng( deepcopy(pseudo_random_generator)) iteration = initiator_manager.handle_onchain_secretreveal( payment_state=current_state, state_change=state_change, channelidentifiers_to_channels=channel_map, pseudo_random_generator=pseudo_random_generator, ) assert events.must_contain_entry( iteration.events, SendBalanceProof, { 'message_identifier': message_identifier, 'payment_identifier': current_state.initiator.transfer_description.payment_identifier, })
def test_initiator_handle_contract_receive_after_channel_closed(): """ Initiator must accept on-chain secret reveal if the channel is closed. However, the off-chain unlock must not be done! This will happen because secrets are registered after a channel is closed, during the settlement window. """ block_number = 10 setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=block_number) transfer = setup.current_state.initiator.transfer assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks channel_closed = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=factories.make_address(), token_network_identifier=setup.channel.token_network_identifier, channel_identifier=setup.channel.identifier, block_number=block_number, ) channel_close_transition = channel.state_transition( channel_state=setup.channel, state_change=channel_closed, pseudo_random_generator=setup.prng, block_number=block_number, ) channel_state = channel_close_transition.new_state state_change = ContractReceiveSecretReveal( transaction_hash=factories.make_transaction_hash(), secret_registry_address=factories.make_address(), secrethash=transfer.lock.secrethash, secret=UNIT_SECRET, block_number=transfer.lock.expiration, ) channel_map = { channel_state.identifier: channel_state, } iteration = initiator_manager.handle_onchain_secretreveal( payment_state=setup.current_state, state_change=state_change, channelidentifiers_to_channels=channel_map, pseudo_random_generator=setup.prng, ) secrethash = setup.current_state.initiator.transfer_description.secrethash assert secrethash in channel_state.our_state.secrethashes_to_onchain_unlockedlocks msg = 'The channel is closed already, the balance proof must not be sent off-chain' assert not events.must_contain_entry(iteration.events, SendBalanceProof, {}), msg