def settle_channel(self, partner): channel = self.address_to_channel[partner] channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), token_network_identifier=channel.token_network_identifier, channel_identifier=channel.identifier, block_number=self.block_number + 1, ) node.state_transition(self.chain_state, channel_settled_state_change)
def new_channel_with_transaction(self): partner_address = self.new_channel() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), self.token_network_id, self.address_to_channel[partner_address], self.block_number, ) node.state_transition(self.chain_state, channel_new_state_change) return partner_address
def new_channel_with_transaction(self): partner_address = self.new_channel() channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=self.address_to_channel[partner_address], block_number=self.block_number, block_hash=factories.make_block_hash(), ) node.state_transition(self.chain_state, channel_new_state_change) self.chain_state.nodeaddresses_to_networkstates[ partner_address] = NetworkState.REACHABLE return partner_address
def exceeded_capacity_init_initiator(self, partner, payment_id, excess_amount, secret): amount = self._available_amount(partner) + excess_amount transfer = self._new_transfer_description(partner, payment_id, amount, secret) action = self._action_init_initiator(transfer) result = node.state_transition(self.chain_state, action) assert event_types_match(result.events, EventPaymentSentFailed) self.event('ActionInitInitiator failed: Amount exceeded')
def _invalid_authentic_secret_request(self, previous, action): result = node.state_transition(self.chain_state, action) if action.secrethash in self.processed_secret_requests or self._is_removed(previous): assert not result.events else: assert event_types_match(result.events, EventPaymentSentFailed) self.processed_secret_requests.add(action.secrethash)
def valid_receive_secret_reveal(self, previous_action): secret = self.secrethash_to_secret[ previous_action.from_transfer.lock.secrethash] sender = previous_action.from_transfer.target recipient = previous_action.from_transfer.initiator action = ReceiveSecretReveal(secret=secret, sender=sender) result = node.state_transition(self.chain_state, action) expiration = previous_action.from_transfer.lock.expiration in_time = self.block_number < expiration - DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS still_waiting = self.block_number < expiration + DEFAULT_WAIT_BEFORE_LOCK_REMOVAL if in_time and self.channel_opened(sender) and self.channel_opened( recipient): assert event_types_match(result.events, SendSecretReveal, SendBalanceProof, EventUnlockSuccess) self.event("Unlock successful.") self.waiting_for_unlock[secret] = recipient elif still_waiting and self.channel_opened(recipient): assert event_types_match(result.events, SendSecretReveal) self.event("Unlock failed, secret revealed too late.") else: assert not result.events self.event( "ReceiveSecretRevealed after removal of lock - dropped.") return action
def replay_receive_secret_reveal_scrambled_sender( self, previous_action_with_address, invalid_sender ): previous_action, client, _ = self._unwrap(previous_action_with_address) action = ReceiveSecretReveal(previous_action.secret, invalid_sender) result = node.state_transition(client.chain_state, action) assert not result.events
def wrong_secret_receive_secret_reveal(self, previous_action_with_address, secret): previous_action, client, _ = self._unwrap(previous_action_with_address) sender = previous_action.from_transfer.target action = ReceiveSecretReveal(secret, sender) result = node.state_transition(client.chain_state, action) assert not result.events
def _invalid_authentic_secret_request(self, previous, action): result = node.state_transition(self.chain_state, action) if action.secrethash in self.processed_secret_requests or self._is_removed( previous): assert not result.events else: self.processed_secret_requests.add(action.secrethash)
def invalid_authentic_secret_request(self, action): result = node.state_transition(self.chain_state, action) if action.secrethash not in self.processed_secret_requests: assert event_types_match(result.events, EventPaymentSentFailed) else: assert not result.events self.processed_secret_requests.add(action.secrethash)
def new_channel_with_transaction(self, client_address: typing.Address) -> AddressPair: client = self.address_to_client[client_address] address_pair = self.new_channel(client_address) partner_address = address_pair.partner_address channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=client.address_to_channel[partner_address], block_number=self.block_number, block_hash=factories.make_block_hash(), ) node.state_transition(client.chain_state, channel_new_state_change) node.state_transition(client.chain_state, channel_new_state_change) client.chain_state.nodeaddresses_to_networkstates[partner_address] = NetworkState.REACHABLE return address_pair
def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( self.random, self.block_number, self.address, factories.UNIT_CHAIN_ID, ) self.token_network_id = factories.make_address() self.token_id = factories.make_address() self.token_network_state = TokenNetworkState(self.token_network_id, self.token_id) self.payment_network_id = factories.make_payment_network_identifier() self.payment_network_state = PaymentNetworkState( self.payment_network_id, [self.token_network_state], ) self.chain_state.identifiers_to_paymentnetworks[ self.payment_network_id] = self.payment_network_state self.channels = list() for partner_address in self.channels_with: channel = factories.make_channel( our_balance=1000, partner_balance=1000, token_network_identifier=self.token_network_id, our_address=self.address, partner_address=partner_address, ) channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), self.token_network_id, channel, self.block_number, ) node.state_transition(self.chain_state, channel_new_state_change) self.channels.append(channel)
def used_secret_init_initiator(self, previous_action, partner, payment_id, amount): assume(not self._is_removed(previous_action)) secret = previous_action.transfer.secret transfer = self._new_transfer_description(partner, payment_id, amount, secret) action = self._action_init_initiator(transfer) result = node.state_transition(self.chain_state, action) assert not result.events self.event('ActionInitInitiator failed: Secret already in use.')
def exceeded_capacity_init_initiator(self, address_pair, payment_id, excess_amount, secret): amount = self._available_amount(address_pair) + excess_amount transfer = self._new_transfer_description(address_pair, payment_id, amount, secret) action = self._action_init_initiator(transfer) client = self.address_to_client[address_pair.our_address] result = node.state_transition(client.chain_state, action) assert event_types_match(result.events, EventPaymentSentFailed) self.event("ActionInitInitiator failed: Amount exceeded")
def settle_channel(self, partner): channel = self.address_to_channel[partner] channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=factories.make_canonical_identifier( chain_identifier=channel.chain_id, token_network_address=channel.token_network_address, channel_identifier=channel.identifier, ), block_number=self.block_number + 1, block_hash=factories.make_block_hash(), our_onchain_locksroot=LOCKSROOT_OF_NO_LOCKS, partner_onchain_locksroot=LOCKSROOT_OF_NO_LOCKS, ) node.state_transition(self.chain_state, channel_settled_state_change)
def valid_init_initiator(self, transfer): assume(transfer.secret not in self.initiated) assume(transfer.amount <= self._available_amount()) action = self._action_init_initiator(transfer) result = node.state_transition(self.chain_state, action) assert event_types_match(result.events, SendLockedTransfer) self.initiated.add(transfer.secret) return action
def wrong_address_receive_secret_reveal(self, previous_action_with_address, invalid_sender): previous_action, client, our_address = self._unwrap(previous_action_with_address) secret = self.secrethash_to_secret[previous_action.from_transfer.lock.secrethash] invalid_action = ReceiveSecretReveal(secret, invalid_sender) result = node.state_transition(client.chain_state, invalid_action) assert not result.events valid_sender = previous_action.from_transfer.target valid_action = ReceiveSecretReveal(secret, valid_sender) return WithOurAddress(our_address=our_address, data=valid_action)
def wrong_address_receive_secret_reveal(self, previous_action, invalid_sender): secret = self.secrethash_to_secret[ previous_action.from_transfer.lock.secrethash] invalid_action = ReceiveSecretReveal(secret, invalid_sender) result = node.state_transition(self.chain_state, invalid_action) assert not result.events valid_sender = previous_action.from_transfer.target valid_action = ReceiveSecretReveal(secret, valid_sender) return valid_action
def valid_secret_request(self, previous_action): action = self._receive_secret_request(previous_action.transfer) result = node.state_transition(self.chain_state, action) if action.secrethash in self.processed_secret_requests: assert not result.events self.event( 'Valid SecretRequest dropped due to previous invalid one.') else: assert event_types_match(result.events, SendSecretReveal) self.event('Valid SecretRequest accepted.') self.processed_secret_requests.add(action.secrethash)
def new_blocks(self, number): events = list() for _ in range(number): block_state_change = Block( block_number=self.block_number + 1, gas_limit=1, block_hash=factories.make_keccak_hash(), ) result = node.state_transition(self.chain_state, block_state_change) events.extend(result.events) self.block_number += 1
def valid_secret_request(self, previous_action): action = self._receive_secret_request(previous_action.transfer) self._assume_channel_opened(previous_action) result = node.state_transition(self.chain_state, action) if action.secrethash in self.processed_secret_requests: assert not result.events self.event('Valid SecretRequest dropped due to previous invalid one.') elif self._is_removed(previous_action): assert not result.events self.event('Ohterwise valid SecretRequest dropped due to expired lock.') else: assert event_types_match(result.events, SendSecretReveal) self.event('Valid SecretRequest accepted.') self.processed_secret_requests.add(action.secrethash)
def valid_init_initiator(self, partner, payment_id, amount, secret): assume(amount <= self._available_amount(partner)) assume(secret not in self.used_secrets) transfer = self._new_transfer_description(partner, payment_id, amount, secret) action = self._action_init_initiator(transfer) result = node.state_transition(self.chain_state, action) assert event_types_match(result.events, SendLockedTransfer) self.initiated.add(transfer.secret) self.expected_expiry[transfer.secrethash] = self.block_number + 10 return action
def new_blocks(self, number): for _ in range(number): block_state_change = Block( block_number=self.block_number + 1, gas_limit=1, block_hash=factories.make_keccak_hash(), ) for client in self.address_to_client.values(): events = list() result = node.state_transition(client.chain_state, block_state_change) events.extend(result.events) # TODO assert on events self.block_number += 1
def valid_init_mediator(self, initiator_address, target_address, payment_id, amount, secret): assume(initiator_address != target_address) transfer = self._new_mediator_transfer(initiator_address, target_address, payment_id, amount, secret) action = self._action_init_mediator(transfer) result = node.state_transition(self.chain_state, action) assert event_types_match(result.events, SendProcessed, SendLockedTransfer) return action
def test_is_transaction_effect_satisfied(chain_state, token_network_id, netting_channel_state): canonical_identifier = netting_channel_state.canonical_identifier assert token_network_id == canonical_identifier.token_network_address transaction = ContractSendChannelBatchUnlock( canonical_identifier=canonical_identifier, participant=netting_channel_state.partner_state.address, triggered_by_block_hash=make_block_hash(), ) state_change = ContractReceiveChannelBatchUnlock( transaction_hash=UNIT_SECRETHASH, canonical_identifier=canonical_identifier, participant=HOP1, partner=HOP2, locksroot=EMPTY_MERKLE_ROOT, unlocked_amount=0, returned_tokens=0, block_number=1, block_hash=make_block_hash(), ) # unlock for a channel in which this node is not a participant must return False assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) # now call normally with us being the partner and not the participant state_change.partner = netting_channel_state.partner_state.address state_change.participant = netting_channel_state.our_state.address assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) # finally call with us being the participant and not the partner which should check out state_change.participant = netting_channel_state.partner_state.address state_change.partner = netting_channel_state.our_state.address # ContractSendChannelBatchUnlock would only be satisfied if both sides are unlocked # and if the channel was cleared assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) channel_settled = ContractReceiveChannelSettled( transaction_hash=bytes(32), canonical_identifier=canonical_identifier, our_onchain_locksroot=EMPTY_MERKLE_ROOT, partner_onchain_locksroot=EMPTY_MERKLE_ROOT, block_number=1, block_hash=make_block_hash(), ) iteration = state_transition(chain_state=chain_state, state_change=channel_settled) assert is_transaction_effect_satisfied(iteration.new_state, transaction, state_change)
def valid_init_mediator(self, from_channel, to_channel, payment_id, amount, secret): our_address = from_channel.our_address assume(to_channel.our_address == our_address) # FIXME this will be too slow client = self.address_to_client[our_address] from_partner = from_channel.partner_address to_partner = to_channel.partner_address assume(from_partner != to_partner) transfer = self._new_mediator_transfer( from_partner, to_partner, payment_id, amount, secret, our_address ) client_data = self._action_init_mediator(transfer, our_address) result = node.state_transition(client.chain_state, client_data.data) assert event_types_match(result.events, SendProcessed, SendLockedTransfer) return client_data
def test_mediator_clear_pairs_after_batch_unlock( chain_state, token_network_state, our_address, ): """ Regression test for https://github.com/raiden-network/raiden/issues/2932 The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where he is a participant is received. """ open_block_number = 10 pseudo_random_generator = random.Random() pkey, address = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address, token_network_identifier=token_network_state.address, ) payment_network_identifier = factories.make_payment_network_identifier() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, channel_state, open_block_number, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b'test_end_state') lock_secrethash = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_secrethash, ) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock, ) from_route = factories.route_from_channel(channel_state) init_mediator = ActionInitMediator( routes=[from_route], from_route=from_route, from_transfer=mediated_transfer, ) node.state_transition(chain_state, init_mediator) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( factories.make_transaction_hash(), channel_state.partner_state.address, token_network_state.address, channel_state.identifier, closed_block_number, ) channel_closed_iteration = token_network.state_transition( payment_network_identifier, channel_new_iteration.new_state, channel_close_state_change, pseudo_random_generator, closed_block_number, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( factories.make_transaction_hash(), token_network_state.address, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( payment_network_identifier, channel_closed_iteration.new_state, channel_settled_state_change, pseudo_random_generator, closed_block_number, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels block_number = closed_block_number + 1 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, participant=our_address, partner=address, locksroot=lock_secrethash, unlocked_amount=lock_amount, returned_tokens=0, block_number=block_number, ) channel_unlock_iteration = node.state_transition( chain_state=chain_state, state_change=channel_batch_unlock_state_change, ) chain_state = channel_unlock_iteration.new_state token_network_state = views.get_token_network_by_identifier( chain_state=chain_state, token_network_id=token_network_state.address, ) ids_to_channels = token_network_state.channelidentifiers_to_channels assert len(ids_to_channels) == 0 # Make sure that all is fine in the next block block = Block( block_number=block_number + 1, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = node.state_transition( chain_state=chain_state, state_change=block, ) assert iteration.new_state # Make sure that mediator task was cleared during the next block processing # since the channel was removed mediator_task = chain_state.payment_mapping.secrethashes_to_task.get(lock_secrethash) assert not mediator_task
def test_multiple_channel_states( chain_state, token_network_state, our_address, ): open_block_number = 10 pseudo_random_generator = random.Random() pkey, address = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address, token_network_identifier=token_network_state.address, ) payment_network_identifier = factories.make_payment_network_identifier() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, channel_state, open_block_number, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b'test_end_state') lock_secrethash = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_secrethash, ) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock, ) from_route = factories.route_from_channel(channel_state) init_target = ActionInitTarget( from_route, mediated_transfer, ) node.state_transition(chain_state, init_target) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( factories.make_transaction_hash(), channel_state.partner_state.address, token_network_state.address, channel_state.identifier, closed_block_number, ) channel_closed_iteration = token_network.state_transition( payment_network_identifier, channel_new_iteration.new_state, channel_close_state_change, pseudo_random_generator, closed_block_number, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( factories.make_transaction_hash(), token_network_state.address, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( payment_network_identifier, channel_closed_iteration.new_state, channel_settled_state_change, pseudo_random_generator, closed_block_number, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels # Create new channel while the previous one is pending unlock new_channel_state = factories.make_channel( our_balance=our_balance, partner_balance=our_balance, partner_address=address, ) channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, new_channel_state, closed_block_number + 1, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) token_network_state_after_new_open = channel_new_iteration.new_state ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels assert len(ids_to_channels) == 2 assert channel_state.identifier in ids_to_channels
def _unauthentic_secret_request(self, action): result = node.state_transition(self.chain_state, action) assert not result.events
def replay_init_initator(self, previous_action): assume(not self._is_removed(previous_action)) result = node.state_transition(self.chain_state, previous_action) assert not result.events
def wrong_secret_receive_secret_reveal(self, previous_action, secret): sender = previous_action.from_transfer.target action = ReceiveSecretReveal(secret, sender) result = node.state_transition(self.chain_state, action) assert not result.events
def replay_receive_secret_reveal_scrambled_sender(self, previous_action, invalid_sender): action = ReceiveSecretReveal(previous_action.secret, invalid_sender) result = node.state_transition(self.chain_state, action) assert not result.events
def replay_receive_secret_reveal(self, previous_action): result = node.state_transition(self.chain_state, previous_action) assert not result.events