def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.block_hash = factories.make_block_hash() self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( pseudo_random_generator=self.random, block_number=self.block_number, block_hash=self.block_hash, our_address=self.address, chain_id=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 return self.new_channel_with_transaction()
def handle_tokennetwork_new2(raiden, event, current_block_number): """ Handles a `TokenNetworkCreated` event. """ data = event.event_data token_network_address = data['token_network_address'] token_network_registry_address = event.originating_contract token_network_registry_proxy = raiden.chain.token_network_registry( token_network_registry_address, ) token_network_proxy = token_network_registry_proxy.token_network( token_network_address) raiden.blockchain_events.add_token_network_listener( token_network_proxy, from_block=data['blockNumber'], ) token_address = data_decoder(event.event_data['args']['token_address']) token_network_state = TokenNetworkState( token_network_address, token_address, ) new_token_network = ContractReceiveNewTokenNetwork( event.originating_contract, token_network_state, ) raiden.handle_state_change(new_token_network, current_block_number)
def initialize(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.block_hash = factories.make_block_hash() self.random = random self.private_key, self.address = factories.make_privkey_address() self.chain_state = ChainState( pseudo_random_generator=self.random, block_number=self.block_number, block_hash=self.block_hash, our_address=self.address, chain_id=factories.UNIT_CHAIN_ID, ) self.token_network_id = factories.UNIT_TOKEN_NETWORK_ADDRESS self.token_id = factories.UNIT_TOKEN_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.chain_state.tokennetworkaddresses_to_paymentnetworkaddresses[ self.token_network_id] = self.payment_network_id channels = [ self.new_channel_with_transaction() for _ in range(self.initial_number_of_channels) ] return multiple(*channels)
def handle_channelnew( token_network_state: TokenNetworkState, state_change: ContractReceiveChannelNew ) -> TransitionResult: events: List[Event] = list() channel_state = state_change.channel_state channel_identifier = channel_state.identifier our_address = channel_state.our_state.address partner_address = channel_state.partner_state.address token_network_state.network_graph.network.add_edge(our_address, partner_address) token_network_state.network_graph.channel_identifier_to_participants[ state_change.channel_identifier ] = (our_address, partner_address) if our_address not in token_network_state.channelidentifiers_to_channels: token_network_state.channelidentifiers_to_channels[our_address]: Dict[AddressHex, NettingChannelState] = dict() # Ignore duplicated channelnew events. For this to work properly on channel # reopens the blockchain events ChannelSettled and ChannelOpened must be # processed in correct order, this should be guaranteed by the filters in # the ethereum node if channel_identifier not in token_network_state.channelidentifiers_to_channels[our_address]: token_network_state.channelidentifiers_to_channels[our_address][channel_identifier] = channel_state addresses_to_ids = token_network_state.partneraddresses_to_channelidentifiers addresses_to_ids[our_address].append(channel_identifier) addresses_to_ids[partner_address].append(channel_identifier) return TransitionResult(token_network_state, events)
def contractreceivenewtokennetwork_from_event( event: DecodedEvent, pendingtokenregistration: Dict[TokenNetworkAddress, Tuple[TokenNetworkRegistryAddress, TokenAddress]], ) -> ContractReceiveNewTokenNetwork: data = event.event_data args = data["args"] token_network_address = args["token_network_address"] token_address = TokenAddress(args["token_address"]) token_network_registry_address = TokenNetworkRegistryAddress( event.originating_contract) pendingtokenregistration[token_network_address] = ( token_network_registry_address, token_address, ) return ContractReceiveNewTokenNetwork( token_network_registry_address=token_network_registry_address, token_network=TokenNetworkState( address=token_network_address, token_address=token_address, network_graph=TokenNetworkGraphState(token_network_address), ), transaction_hash=event.transaction_hash, block_number=event.block_number, block_hash=event.block_hash, )
def handle_tokennetwork_new(raiden, event, current_block_number): """ Handles a `TokenNetworkCreated` event. """ data = event.event_data token_network_address = data['token_network_address'] token_network_proxy = raiden.chain.token_network(token_network_address) raiden.blockchain_events.add_token_network_listener( token_network_proxy, from_block=data['blockNumber'], ) token_address = data_decoder(event.event_data['args']['token_address']) token_network_state = TokenNetworkState( token_network_address, token_address, ) transaction_hash = event.event_data['transactionHash'] assert transaction_hash, 'A mined transaction must have the hash field' new_token_network = ContractReceiveNewTokenNetwork( transaction_hash, event.originating_contract, token_network_state, ) raiden.handle_state_change(new_token_network, current_block_number)
def test_get_networks(chain_state, token_network_address): orig_chain_state = deepcopy(chain_state) token_address = factories.make_address() token_network_registry_empty = TokenNetworkRegistryState( address=factories.make_address(), token_network_list=[]) chain_state.identifiers_to_tokennetworkregistries[ token_network_registry_empty.address] = token_network_registry_empty assert get_networks( chain_state=chain_state, token_network_registry_address=token_network_registry_empty.address, token_address=token_address, ) == (token_network_registry_empty, None) chain_state = orig_chain_state token_network = TokenNetworkState( address=token_network_address, token_address=token_address, network_graph=TokenNetworkGraphState( token_network_address=token_network_address), ) token_network_registry = TokenNetworkRegistryState( address=factories.make_address(), token_network_list=[token_network]) assert get_networks( chain_state=chain_state, token_network_registry_address=token_network_registry.address, token_address=token_address, ) == (None, None) chain_state.identifiers_to_tokennetworkregistries[ token_network_registry.address] = token_network_registry assert get_networks( chain_state=chain_state, token_network_registry_address=token_network_registry.address, token_address=token_address, ) == (token_network_registry, token_network)
def handle_tokennetwork_new(raiden, event, current_block_number): data = event.event_data manager_address = data['channel_manager_address'] registry_address = data['registry_address'] registry = raiden.chain.registry(registry_address) manager_proxy = registry.manager(manager_address) netting_channel_proxies = get_channel_proxies(raiden.chain, raiden.address, manager_proxy) # Install the filters first to avoid missing changes, as a consequence # some events might be applied twice. raiden.blockchain_events.add_channel_manager_listener( manager_proxy, from_block=data['blockNumber'], ) for channel_proxy in netting_channel_proxies: raiden.blockchain_events.add_netting_channel_listener( channel_proxy, from_block=data['blockNumber'], ) token_address = data_decoder(data['args']['token_address']) token_network_state = TokenNetworkState( manager_address, token_address, ) new_payment_network = ContractReceiveNewTokenNetwork( event.originating_contract, token_network_state, ) raiden.handle_state_change(new_payment_network, current_block_number)
def test_handle_new_token_network(chain_state, token_network_address): token_address = factories.make_address() token_network = TokenNetworkState( address=token_network_address, token_address=token_address, network_graph=TokenNetworkGraphState(token_network_address=token_network_address), ) token_network_registry_address = factories.make_address() state_change = ContractReceiveNewTokenNetwork( token_network_registry_address=token_network_registry_address, token_network=token_network, transaction_hash=factories.make_transaction_hash(), block_hash=factories.make_block_hash(), block_number=factories.make_block_number(), ) transition_result = handle_contract_receive_new_token_network( chain_state=chain_state, state_change=state_change ) new_chain_state = transition_result.new_state token_network_registry = new_chain_state.identifiers_to_tokennetworkregistries[ token_network_registry_address ] assert token_network_registry.address == token_network_registry_address assert not transition_result.events assert get_networks( chain_state=chain_state, token_network_registry_address=token_network_registry_address, token_address=token_address, ) == (token_network_registry, token_network)
def get_token_network_state_from_proxies(raiden, manager_proxy, netting_channel_proxies): manager_address = manager_proxy.address token_address = manager_proxy.token_address() edge_list = manager_proxy.channels_addresses() graph = make_graph(edge_list) network_graph = TokenNetworkGraphState(graph) partner_channels = list() for channel_proxy in netting_channel_proxies: channel_state = get_channel_state( token_address, raiden.config['reveal_timeout'], channel_proxy, ) partner_channels.append(channel_state) network = TokenNetworkState( manager_address, token_address, network_graph, partner_channels, ) return network
def handle_tokennetwork_new(raiden: 'RaidenService', event: Event): """ Handles a `TokenNetworkCreated` event. """ data = event.event_data args = data['args'] block_number = data['block_number'] token_network_address = args['token_network_address'] token_address = typing.TokenAddress(args['token_address']) block_hash = data['block_hash'] token_network_proxy = raiden.chain.token_network(token_network_address) raiden.blockchain_events.add_token_network_listener( token_network_proxy=token_network_proxy, contract_manager=raiden.contract_manager, from_block=block_number, ) token_network_state = TokenNetworkState( token_network_address, token_address, ) transaction_hash = event.event_data['transaction_hash'] new_token_network = ContractReceiveNewTokenNetwork( transaction_hash=transaction_hash, payment_network_identifier=event.originating_contract, token_network=token_network_state, block_number=block_number, block_hash=block_hash, ) raiden.handle_and_track_state_change(new_token_network)
def test_contract_receive_channelnew_must_be_idempotent(): block_number = 10 block_hash = factories.make_block_hash() pseudo_random_generator = random.Random() token_network_id = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState(token_network_id, token_id) payment_network_identifier = factories.make_payment_network_identifier() amount = 30 our_balance = amount + 50 channel_state1 = factories.make_channel(our_balance=our_balance) channel_state2 = copy.deepcopy(channel_state1) state_change1 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_id, channel_state=channel_state1, block_number=block_number, block_hash=block_hash, ) token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=token_network_state, state_change=state_change1, pseudo_random_generator=pseudo_random_generator, block_number=block_number, block_hash=block_hash, ) state_change2 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_id, channel_state=channel_state2, block_number=block_number + 1, block_hash=factories.make_block_hash(), ) # replay the ContractReceiveChannelNew state change iteration = token_network.state_transition( payment_network_identifier=payment_network_identifier, token_network_state=token_network_state, state_change=state_change2, pseudo_random_generator=pseudo_random_generator, block_number=block_number, block_hash=block_hash, ) msg = 'the channel must not have been overwritten' channelmap_by_id = iteration.new_state.channelidentifiers_to_channels assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg channelmap_by_address = iteration.new_state.partneraddresses_to_channelidentifiers partner_channels_ids = channelmap_by_address[ channel_state1.partner_state.address] assert channel_state1.identifier in partner_channels_ids, msg
def token_network_state(payment_network_state, token_network_id, token_id): token_network = TokenNetworkState( token_network_id, token_id, ) payment_network_state.tokenidentifiers_to_tokennetworks[token_network_id] = token_network payment_network_state.tokenaddresses_to_tokenidentifiers[token_id] = token_network_id return token_network
def test_contract_receive_channelnew_must_be_idempotent(channel_properties): block_number = 10 block_hash = factories.make_block_hash() token_network_address = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState( address=token_network_address, token_address=token_id, network_graph=TokenNetworkGraphState(token_network_address), ) pseudo_random_generator = random.Random() properties, _ = channel_properties channel_state1 = factories.create(properties) channel_state2 = deepcopy(channel_state1) state_change1 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state1, block_number=block_number, block_hash=block_hash, ) token_network.state_transition( token_network_state=token_network_state, state_change=state_change1, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) state_change2 = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state2, block_number=block_number + 1, block_hash=factories.make_block_hash(), ) # replay the ContractReceiveChannelNew state change iteration = token_network.state_transition( token_network_state=token_network_state, state_change=state_change2, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) msg = "the channel must not have been overwritten" channelmap_by_id = iteration.new_state.channelidentifiers_to_channels assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg channelmap_by_address = iteration.new_state.partneraddresses_to_channelidentifiers partner_channels_ids = channelmap_by_address[ channel_state1.partner_state.address] assert channel_state1.identifier in partner_channels_ids, msg
def test_channel_settle_must_properly_cleanup(): open_block_number = 10 pseudo_random_generator = random.Random() token_network_id = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState(token_network_id, token_id) amount = 30 our_balance = amount + 50 channel_state = factories.make_channel(our_balance=our_balance) channel_new_state_change = ContractReceiveChannelNew( token_network_id, channel_state) channel_new_iteration = token_network.state_transition( token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( token_network_id, channel_state.identifier, channel_state.partner_state.address, closed_block_number, ) channel_closed_iteration = token_network.state_transition( 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( token_network_id, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( 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 channel_state.identifier not in ids_to_channels
def token_network_state(chain_state, payment_network_state, payment_network_id, token_network_id, token_id): token_network = TokenNetworkState(token_network_id, token_id) payment_network_state.tokenidentifiers_to_tokennetworks[ token_network_id] = token_network payment_network_state.tokenaddresses_to_tokenidentifiers[ token_id] = token_network_id mapping = chain_state.tokennetworkaddresses_to_paymentnetworkaddresses mapping[token_network_id] = payment_network_id return token_network
def test_contract_receive_channelnew_must_be_idempotent(): block_number = 10 pseudo_random_generator = random.Random() token_network_id = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState(token_network_id, token_id) amount = 30 our_balance = amount + 50 channel_state1 = factories.make_channel(our_balance=our_balance) channel_state2 = copy.deepcopy(channel_state1) state_change1 = ContractReceiveChannelNew(token_network_id, channel_state1) token_network.state_transition( token_network_state, state_change1, pseudo_random_generator, block_number, ) # change the existing channel payment_identifier = 1 message_identifier = random.randint(0, UINT64_MAX) channel.send_directtransfer( channel_state1, amount, message_identifier, payment_identifier, ) state_change2 = ContractReceiveChannelNew(token_network_id, channel_state2) # replay the ContractReceiveChannelNew state change iteration = token_network.state_transition( token_network_state, state_change2, pseudo_random_generator, block_number, ) msg = 'the channel must not been overwritten' channelmap_by_id = iteration.new_state.channelidentifiers_to_channels assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg channelmap_by_address = iteration.new_state.partneraddresses_to_channels assert channelmap_by_address[ channel_state1.partner_state.address] == channel_state1, msg
def initialize_all(self, block_number, random, random_seed): self.random_seed = random_seed self.block_number = block_number self.block_hash = factories.make_block_hash() self.random = random self.token_network_address = factories.UNIT_TOKEN_NETWORK_ADDRESS self.token_id = factories.UNIT_TOKEN_ADDRESS self.token_network_state = TokenNetworkState( address=self.token_network_address, token_address=self.token_id, network_graph=TokenNetworkGraphState(self.token_network_address), ) self.token_network_registry_address = factories.make_token_network_registry_address() self.token_network_registry_state = TokenNetworkRegistryState( self.token_network_registry_address, [self.token_network_state] ) channels = [] for _ in range(self.number_of_clients): private_key, address = factories.make_privkey_address() self.address_to_privkey[address] = private_key chain_state = ChainState( pseudo_random_generator=self.random, block_number=self.block_number, block_hash=self.block_hash, our_address=address, chain_id=factories.UNIT_CHAIN_ID, ) chain_state.identifiers_to_tokennetworkregistries[ self.token_network_registry_address ] = self.token_network_registry_state chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[ self.token_network_address ] = self.token_network_registry_address self.address_to_client[address] = Client(chain_state=chain_state) channels.extend( self.new_channel_with_transaction(client_address=address) for _ in range(self.initial_number_of_channels) ) return multiple(*channels)
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 token_network_state( chain_state, token_network_registry_state, token_network_registry_address, token_network_address, token_id, ): token_network = TokenNetworkState( address=token_network_address, token_address=token_id, ) token_network_registry_state.add_token_network(token_network) mapping = chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses mapping[token_network_address] = token_network_registry_address return token_network
def contractreceivenewtokennetwork_from_event( event: DecodedEvent ) -> ContractReceiveNewTokenNetwork: data = event.event_data args = data["args"] token_network_address = args["token_network_address"] return ContractReceiveNewTokenNetwork( token_network_registry_address=TokenNetworkRegistryAddress(event.originating_contract), token_network=TokenNetworkState( address=token_network_address, token_address=args["token_address"], network_graph=TokenNetworkGraphState(token_network_address), ), transaction_hash=event.transaction_hash, block_number=event.block_number, block_hash=event.block_hash, )
def test_maybe_add_tokennetwork_unknown_token_network_registry( chain_state, token_network_address): token_network_registry_address = factories.make_address() token_address = factories.make_address() token_network = TokenNetworkState( address=token_network_address, token_address=token_address, ) msg = "test state invalid, token_network_registry already in chain_state" assert (token_network_registry_address not in chain_state.identifiers_to_tokennetworkregistries), msg maybe_add_tokennetwork( chain_state=chain_state, token_network_registry_address=token_network_registry_address, token_network_state=token_network, ) # new token network registry should have been added to chain_state token_network_registry_state = chain_state.identifiers_to_tokennetworkregistries[ token_network_registry_address] assert token_network_registry_state.address == token_network_registry_address
def test_handle_new_token_network_registry(chain_state, token_network_address): token_address = factories.make_address() token_network = TokenNetworkState( address=token_network_address, token_address=token_address, ) token_network_registry = TokenNetworkRegistryState( address=factories.make_address(), token_network_list=[token_network]) state_change = ContractReceiveNewTokenNetworkRegistry( transaction_hash=factories.make_transaction_hash(), token_network_registry=token_network_registry, block_hash=make_block_hash(), block_number=1, ) assert token_network_registry.address not in chain_state.identifiers_to_tokennetworkregistries transition_result = handle_contract_receive_new_token_network_registry( chain_state, state_change) assert transition_result.new_state == chain_state msg = "handle_new_token_network_registry did not add to chain_state mapping" assert token_network_registry.address in chain_state.identifiers_to_tokennetworkregistries, msg
def token_network_state( chain_state, token_network_registry_state, token_network_registry_address, token_network_address, token_id, ): token_network_graph_state = TokenNetworkGraphState(token_network_address) token_network = TokenNetworkState( address=token_network_address, token_address=token_id, network_graph=token_network_graph_state, ) token_network_registry_state.tokennetworkaddresses_to_tokennetworks[ token_network_address] = token_network token_network_registry_state.tokenaddresses_to_tokennetworkaddresses[ token_id] = token_network_address mapping = chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses mapping[token_network_address] = token_network_registry_address return token_network
def test_detect_balance_proof_change(): prng = random.Random() block_hash = factories.make_block_hash() old = ChainState( pseudo_random_generator=prng, block_number=1, block_hash=block_hash, our_address=2, chain_id=3, ) new = ChainState( pseudo_random_generator=prng, block_number=1, block_hash=block_hash, our_address=2, chain_id=3, ) def diff(): return list(detect_balance_proof_change(old, new)) assert len(diff()) == 0 payment_network = PaymentNetworkState(b'x', []) payment_network_copy = deepcopy(payment_network) new.identifiers_to_paymentnetworks['a'] = payment_network assert len(diff()) == 0 token_network = TokenNetworkState(b'a', b'a') token_network_copy = deepcopy(token_network) payment_network.tokenidentifiers_to_tokennetworks['a'] = token_network assert len(diff()) == 0 channel = NettingChannelState( canonical_identifier=factories.make_canonical_identifier(), token_address=b'a', payment_network_identifier=1, reveal_timeout=1, settle_timeout=2, mediation_fee=0, our_state=None, partner_state=None, open_transaction=TransactionExecutionStatus(result='success'), settle_transaction=None, update_transaction=None, close_transaction=None, ) channel_copy = deepcopy(channel) token_network.channelidentifiers_to_channels['a'] = channel our_state = NettingChannelEndState(address=b'b', balance=1) our_state_copy = deepcopy(our_state) partner_state = NettingChannelEndState(address=b'a', balance=0) partner_state_copy = deepcopy(partner_state) channel.our_state = our_state channel.partner_state = partner_state assert len(diff()) == 0 balance_proof = object() partner_state.balance_proof = balance_proof assert len(diff()) == 1 old.identifiers_to_paymentnetworks['a'] = payment_network_copy assert len(diff()) == 1 payment_network_copy.tokenidentifiers_to_tokennetworks[ 'a'] = token_network_copy assert len(diff()) == 1 token_network_copy.channelidentifiers_to_channels['a'] = channel_copy channel_copy.partner_state = partner_state_copy assert len(diff()) == 1 channel_copy.partner_state.balance_proof = balance_proof assert len(diff()) == 0 channel_copy.partner_state.balance_proof = object() assert len(diff()) == 1 assert diff() == [balance_proof] # check our_state BP changes channel_copy.partner_state.balance_proof = balance_proof assert len(diff()) == 0 channel.our_state.balance_proof = object() channel_copy.our_state = our_state_copy assert len(diff()) == 1 assert diff() == [channel.our_state.balance_proof] channel_copy.our_state.balance_proof = channel.our_state.balance_proof assert len(diff()) == 0
def test_detect_balance_proof_change(): prng = random.Random() block_hash = factories.make_block_hash() old = ChainState( pseudo_random_generator=prng, block_number=1, block_hash=block_hash, our_address=2, chain_id=3, ) new = ChainState( pseudo_random_generator=prng, block_number=1, block_hash=block_hash, our_address=2, chain_id=3, ) def diff(): return list(detect_balance_proof_change(old, new)) assert len(diff()) == 0 payment_network = PaymentNetworkState(b'x', []) payment_network_copy = deepcopy(payment_network) new.identifiers_to_paymentnetworks['a'] = payment_network assert len(diff()) == 0 token_network = TokenNetworkState(b'a', b'a') token_network_copy = deepcopy(token_network) payment_network.tokenidentifiers_to_tokennetworks['a'] = token_network assert len(diff()) == 0 channel = NettingChannelState( 1, 0, b'a', 1, 1, 1, 2, None, None, TransactionExecutionStatus(result='success'), ) channel_copy = deepcopy(channel) token_network.channelidentifiers_to_channels['a'] = channel partner_state = NettingChannelEndState(b'a', 0) partner_state_copy = deepcopy(partner_state) channel.partner_state = partner_state assert len(diff()) == 0 balance_proof = object() partner_state.balance_proof = balance_proof assert len(diff()) == 1 old.identifiers_to_paymentnetworks['a'] = payment_network_copy assert len(diff()) == 1 payment_network_copy.tokenidentifiers_to_tokennetworks[ 'a'] = token_network_copy assert len(diff()) == 1 token_network_copy.channelidentifiers_to_channels['a'] = channel_copy channel_copy.partner_state = partner_state_copy assert len(diff()) == 1 channel_copy.partner_state.balance_proof = balance_proof assert len(diff()) == 0 channel_copy.partner_state.balance_proof = object() assert len(diff()) == 1 assert diff() == [balance_proof]
def test_channel_settle_must_properly_cleanup(channel_properties): open_block_number = 10 open_block_hash = factories.make_block_hash() token_network_id = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState(token_network_id, token_id) properties, _ = channel_properties channel_state = factories.create(properties) channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state, block_number=open_block_number, block_hash=open_block_hash, ) channel_new_iteration = token_network.state_transition( token_network_state=token_network_state, state_change=channel_new_state_change, block_number=open_block_number, block_hash=open_block_hash, ) closed_block_number = open_block_number + 10 closed_block_hash = factories.make_block_hash() channel_close_state_change = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, canonical_identifier=channel_state.canonical_identifier, block_number=closed_block_number, block_hash=closed_block_hash, ) channel_closed_iteration = token_network.state_transition( token_network_state=channel_new_iteration.new_state, state_change=channel_close_state_change, block_number=closed_block_number, block_hash=closed_block_hash, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, block_number=settle_block_number, block_hash=factories.make_block_hash(), our_onchain_locksroot=EMPTY_MERKLE_ROOT, partner_onchain_locksroot=EMPTY_MERKLE_ROOT, ) channel_settled_iteration = token_network.state_transition( token_network_state=channel_closed_iteration.new_state, state_change=channel_settled_state_change, block_number=closed_block_number, block_hash=closed_block_hash, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert channel_state.identifier not in ids_to_channels
def test_detect_balance_proof_change(): prng = random.Random() block_hash = make_block_hash() our_address = make_address() empty_chain = ChainState( pseudo_random_generator=prng, block_number=1, block_hash=block_hash, our_address=our_address, chain_id=3, ) assert empty(detect_balance_proof_change(empty_chain, empty_chain)), MSG_NO_CHANGE assert empty( detect_balance_proof_change(empty_chain, deepcopy(empty_chain))), MSG_NO_CHANGE token_network_registry_address = make_address() chain_with_registry_no_bp = deepcopy(empty_chain) chain_with_registry_no_bp.identifiers_to_tokennetworkregistries[ token_network_registry_address] = TokenNetworkRegistryState( token_network_registry_address, []) assert empty( detect_balance_proof_change(empty_chain, chain_with_registry_no_bp)), MSG_NO_CHANGE assert empty( detect_balance_proof_change( chain_with_registry_no_bp, deepcopy(chain_with_registry_no_bp))), MSG_NO_CHANGE token_network_address = make_address() token_address = make_address() chain_with_token_network_no_bp = deepcopy(chain_with_registry_no_bp) chain_with_token_network_no_bp.identifiers_to_tokennetworkregistries[ token_network_registry_address].tokennetworkaddresses_to_tokennetworks[ token_network_address] = TokenNetworkState( address=token_network_address, token_address=token_address, network_graph=TokenNetworkGraphState(token_network_address), ) assert empty( detect_balance_proof_change( empty_chain, chain_with_token_network_no_bp)), MSG_NO_CHANGE assert empty( detect_balance_proof_change( chain_with_registry_no_bp, chain_with_token_network_no_bp)), MSG_NO_CHANGE assert empty( detect_balance_proof_change( chain_with_token_network_no_bp, deepcopy(chain_with_token_network_no_bp))), MSG_NO_CHANGE partner_address = make_address() canonical_identifier = make_canonical_identifier() channel_no_bp = NettingChannelState( canonical_identifier=canonical_identifier, token_address=token_address, token_network_registry_address=token_network_registry_address, reveal_timeout=1, settle_timeout=2, our_state=NettingChannelEndState(address=our_address, contract_balance=1), partner_state=NettingChannelEndState(address=partner_address, contract_balance=0), open_transaction=TransactionExecutionStatus(result="success"), settle_transaction=None, update_transaction=None, close_transaction=None, fee_schedule=FeeScheduleState(), ) chain_with_channel_no_bp = deepcopy(chain_with_token_network_no_bp) chain_with_token_network_no_bp.identifiers_to_tokennetworkregistries[ token_network_registry_address].tokennetworkaddresses_to_tokennetworks[ token_network_address].channelidentifiers_to_channels[ canonical_identifier.channel_identifier] = channel_no_bp assert empty( detect_balance_proof_change(empty_chain, chain_with_channel_no_bp)), MSG_NO_CHANGE assert empty( detect_balance_proof_change(chain_with_registry_no_bp, chain_with_channel_no_bp)), MSG_NO_CHANGE assert empty( detect_balance_proof_change(chain_with_token_network_no_bp, chain_with_channel_no_bp)), MSG_NO_CHANGE assert empty( detect_balance_proof_change( chain_with_channel_no_bp, deepcopy(chain_with_channel_no_bp))), MSG_NO_CHANGE channel_with_sent_bp = deepcopy(channel_no_bp) channel_with_sent_bp.our_state.balance_proof = create( BalanceProofUnsignedState) chain_with_sent_bp = deepcopy(chain_with_token_network_no_bp) chain_with_sent_bp.identifiers_to_tokennetworkregistries[ token_network_registry_address].tokennetworkaddresses_to_tokennetworks[ token_network_address].channelidentifiers_to_channels[ canonical_identifier.channel_identifier] = channel_with_sent_bp assert not empty( detect_balance_proof_change( empty_chain, chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change( chain_with_registry_no_bp, chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change( chain_with_token_network_no_bp, chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change( chain_with_channel_no_bp, chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert empty( detect_balance_proof_change( chain_with_sent_bp, deepcopy(chain_with_sent_bp))), MSG_NO_CHANGE channel_with_received_bp = deepcopy(channel_no_bp) channel_with_received_bp.partner_state.balance_proof = create( BalanceProofUnsignedState) chain_with_received_bp = deepcopy(chain_with_token_network_no_bp) chain_with_received_bp.identifiers_to_tokennetworkregistries[ token_network_registry_address].tokennetworkaddresses_to_tokennetworks[ token_network_address].channelidentifiers_to_channels[ canonical_identifier.channel_identifier] = channel_with_sent_bp # asserting with `channel_with_received_bp` and `channel_with_sent_bp` # doesn't make sense, because one of the balance proofs would have to # disappear (which is a bug) assert not empty( detect_balance_proof_change( empty_chain, chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change( chain_with_registry_no_bp, chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change( chain_with_token_network_no_bp, chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change( chain_with_channel_no_bp, chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert empty( detect_balance_proof_change( chain_with_received_bp, deepcopy(chain_with_received_bp))), MSG_NO_CHANGE chain_with_sent_and_received_bp = deepcopy(chain_with_token_network_no_bp) ta_to_tn = chain_with_sent_and_received_bp.identifiers_to_tokennetworkregistries channel_with_sent_and_recived_bp = ( ta_to_tn[token_network_registry_address]. tokennetworkaddresses_to_tokennetworks[token_network_address]. channelidentifiers_to_channels[canonical_identifier.channel_identifier] ) channel_with_sent_and_recived_bp.partner_state.balance_proof = deepcopy( channel_with_received_bp.partner_state.balance_proof) channel_with_sent_and_recived_bp.our_state.balance_proof = deepcopy( channel_with_received_bp.our_state.balance_proof) assert not empty( detect_balance_proof_change(empty_chain, chain_with_sent_and_received_bp) ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change(chain_with_registry_no_bp, chain_with_sent_and_received_bp) ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change(chain_with_token_network_no_bp, chain_with_sent_and_received_bp) ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change(chain_with_channel_no_bp, chain_with_sent_and_received_bp) ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change(chain_with_received_bp, chain_with_sent_and_received_bp) ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert not empty( detect_balance_proof_change(chain_with_sent_bp, chain_with_sent_and_received_bp) ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED assert empty( detect_balance_proof_change( chain_with_sent_and_received_bp, deepcopy(chain_with_sent_and_received_bp))), MSG_NO_CHANGE
def test_channel_settle_must_properly_cleanup(channel_properties): open_block_number = 10 open_block_hash = factories.make_block_hash() pseudo_random_generator = random.Random() token_network_address = factories.make_address() token_id = factories.make_address() token_network_state = TokenNetworkState( address=token_network_address, token_address=token_id, network_graph=TokenNetworkGraphState(token_network_address), ) properties, _ = channel_properties channel_state = factories.create(properties) channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state, block_number=open_block_number, block_hash=open_block_hash, ) channel_new_iteration = token_network.state_transition( token_network_state=token_network_state, state_change=channel_new_state_change, block_number=open_block_number, block_hash=open_block_hash, pseudo_random_generator=pseudo_random_generator, ) closed_block_number = open_block_number + 10 closed_block_hash = factories.make_block_hash() channel_close_state_change = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, canonical_identifier=channel_state.canonical_identifier, block_number=closed_block_number, block_hash=closed_block_hash, ) channel_closed_iteration = token_network.state_transition( token_network_state=channel_new_iteration.new_state, state_change=channel_close_state_change, block_number=closed_block_number, block_hash=closed_block_hash, pseudo_random_generator=pseudo_random_generator, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, block_number=settle_block_number, block_hash=factories.make_block_hash(), our_onchain_locksroot=LOCKSROOT_OF_NO_LOCKS, partner_onchain_locksroot=LOCKSROOT_OF_NO_LOCKS, ) channel_settled_iteration = token_network.state_transition( token_network_state=channel_closed_iteration.new_state, state_change=channel_settled_state_change, block_number=closed_block_number, block_hash=closed_block_hash, pseudo_random_generator=pseudo_random_generator, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert channel_state.identifier not in ids_to_channels
def test_subdispatch_by_canonical_id(chain_state): our_model, _ = create_model(balance=10, num_pending_locks=1) partner_model, _ = create_model(balance=0, num_pending_locks=0) channel_state = create_channel_from_models( our_model, partner_model, factories.make_privatekey_bin() ) canonical_identifier = channel_state.canonical_identifier token_network = TokenNetworkState( address=canonical_identifier.token_network_address, token_address=factories.make_address(), network_graph=TokenNetworkGraphState( token_network_address=channel_state.token_network_address ), ) token_network.partneraddresses_to_channelidentifiers[ partner_model.participant_address ] = canonical_identifier.channel_identifier token_network.channelidentifiers_to_channels[ canonical_identifier.channel_identifier ] = channel_state token_network_registry = TokenNetworkRegistryState( address=factories.make_address(), token_network_list=[token_network] ) chain_state.identifiers_to_tokennetworkregistries[ token_network_registry.address ] = token_network_registry chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[ canonical_identifier.token_network_address ] = token_network_registry.address # dispatching a Block will be ignored previous_state = deepcopy(chain_state) state_change = Block( block_number=chain_state.block_number, gas_limit=GAS_LIMIT, block_hash=chain_state.block_hash, ) transition_result = subdispatch_by_canonical_id( chain_state=chain_state, canonical_identifier=canonical_identifier, state_change=state_change, ) assert transition_result.new_state == previous_state assert transition_result.events == [] state_change = ActionChannelClose(canonical_identifier=canonical_identifier) # dispatching for an unknown canonical_identifier will not emit events transition_result = subdispatch_by_canonical_id( chain_state=chain_state, canonical_identifier=CanonicalIdentifier( chain_identifier=chain_state.chain_id, token_network_address=factories.make_address(), channel_identifier=factories.make_channel_identifier(), ), state_change=state_change, ) assert not transition_result.events, transition_result assert get_status(channel_state) == ChannelState.STATE_OPENED transition_result = subdispatch_by_canonical_id( chain_state=chain_state, canonical_identifier=canonical_identifier, state_change=state_change, ) assert get_status(channel_state) == ChannelState.STATE_CLOSING assert transition_result.new_state == chain_state, transition_result