def make_channel( self, token_address=make_address(), partner_address=make_address(), reveal_timeout=20, settle_timeout=800, balance=0, ): our_address = make_address() our_balance = balance partner_balance = balance our_state = ChannelEndState(our_address, our_balance, 1) partner_state = ChannelEndState(partner_address, partner_balance, 1) block_alarm = list() channel_for_hashlock = list() netting_channel = NettingChannelMock(make_address()) external_state = ChannelExternalState( block_alarm.append, lambda *args: channel_for_hashlock.append(args), lambda: 1, netting_channel, ) self.tokens.add(token_address) return Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, )
def make_external_state(): channel_for_hashlock = list() netting_channel = NettingChannelMock() external_state = ChannelExternalState( lambda *args: channel_for_hashlock.append(args), netting_channel, ) return external_state
def test_channel_close_called_only_once(): class MockCheckCallsToClose(): def __init__(self): self.address = 'mockcheckcallstoclosemockcheckcallstoclo' self.close_calls = 0 def opened(self): return 1 def closed(self): return 0 def settled(self): return 0 def close(self, nonce, transferred_amount, locksroot, extra_hash, signature): self.close_calls += 1 netting_channel = NettingChannelMock() token_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 our_state = ChannelEndState(address1, balance1, netting_channel.opened()) partner_state = ChannelEndState(address2, balance2, netting_channel.opened()) channel_for_hashlock = list() netting_channel = MockCheckCallsToClose() external_state = ChannelExternalState( lambda *args: channel_for_hashlock.append(args), netting_channel, ) test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) test_channel.external_state.close('') test_channel.external_state.close('') assert netting_channel.close_calls == 1
def restore_channel(self, serialized_channel): token_address = serialized_channel.token_address netting_channel = self.chain.netting_channel( serialized_channel.channel_address, ) # restoring balances from the BC since the serialized value could be # falling behind. channel_details = netting_channel.detail(self.address) # our_address is checked by detail assert channel_details['partner_address'] == serialized_channel.partner_address opened_block = netting_channel.opened() our_state = ChannelEndState( channel_details['our_address'], channel_details['our_balance'], opened_block, ) partner_state = ChannelEndState( channel_details['partner_address'], channel_details['partner_balance'], opened_block, ) def register_channel_for_hashlock(channel, hashlock): self.register_channel_for_hashlock( token_address, channel, hashlock, ) external_state = ChannelExternalState( register_channel_for_hashlock, netting_channel, ) details = ChannelDetails( serialized_channel.channel_address, our_state, partner_state, external_state, serialized_channel.reveal_timeout, channel_details['settle_timeout'], ) graph = self.token_to_channelgraph[token_address] graph.add_channel(details) channel = graph.address_to_channel.get( serialized_channel.channel_address, ) channel.our_state.balance_proof = serialized_channel.our_balance_proof channel.partner_state.balance_proof = serialized_channel.partner_balance_proof
def make_external_state(): block_alarm = list() channel_for_hashlock = list() netting_channel = NettingChannelMock() netting_channel.address = make_address() external_state = ChannelExternalState( block_alarm.append, lambda *args: channel_for_hashlock.append(args), lambda: 1, netting_channel, ) return external_state
def get_channel_details(self, token_address, netting_channel): channel_details = netting_channel.detail() our_state = ChannelEndState( channel_details['our_address'], channel_details['our_balance'], None, EMPTY_MERKLE_TREE, ) partner_state = ChannelEndState( channel_details['partner_address'], channel_details['partner_balance'], None, EMPTY_MERKLE_TREE, ) def register_channel_for_hashlock(channel, hashlock): self.register_channel_for_hashlock( token_address, channel, hashlock, ) channel_address = netting_channel.address reveal_timeout = self.config['reveal_timeout'] settle_timeout = channel_details['settle_timeout'] external_state = ChannelExternalState( register_channel_for_hashlock, netting_channel, ) channel_detail = ChannelDetails( channel_address, our_state, partner_state, external_state, reveal_timeout, settle_timeout, ) return channel_detail
def make_channel( self, token_address=make_address(), partner_address=make_address(), reveal_timeout=20, settle_timeout=800, balance=0, block_number=1): our_address = make_address() our_balance = balance partner_balance = balance our_state = ChannelEndState( our_address, our_balance, None, EMPTY_MERKLE_TREE, ) partner_state = ChannelEndState( partner_address, partner_balance, None, EMPTY_MERKLE_TREE, ) channel_for_hashlock = list() netting_channel = NettingChannelMock(make_address()) external_state = ChannelExternalState( lambda *args: channel_for_hashlock.append(args), netting_channel, ) self.tokens.add(token_address) return Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, )
def restore_channel(self, serialized_channel): token_address = serialized_channel.token_address netting_channel = self.chain.netting_channel( serialized_channel.channel_address, ) # restoring balances from the blockchain since the serialized # value could be falling behind. channel_details = netting_channel.detail() # our_address is checked by detail assert channel_details[ 'partner_address'] == serialized_channel.partner_address if serialized_channel.our_leaves: our_layers = compute_layers(serialized_channel.our_leaves) our_tree = MerkleTreeState(our_layers) else: our_tree = EMPTY_MERKLE_TREE our_state = ChannelEndState( channel_details['our_address'], channel_details['our_balance'], serialized_channel.our_balance_proof, our_tree, ) if serialized_channel.partner_leaves: partner_layers = compute_layers(serialized_channel.partner_leaves) partner_tree = MerkleTreeState(partner_layers) else: partner_tree = EMPTY_MERKLE_TREE partner_state = ChannelEndState( channel_details['partner_address'], channel_details['partner_balance'], serialized_channel.partner_balance_proof, partner_tree, ) def register_channel_for_hashlock(channel, hashlock): self.register_channel_for_hashlock( token_address, channel, hashlock, ) external_state = ChannelExternalState( register_channel_for_hashlock, netting_channel, ) details = ChannelDetails( serialized_channel.channel_address, our_state, partner_state, external_state, serialized_channel.reveal_timeout, channel_details['settle_timeout'], ) graph = self.token_to_channelgraph[token_address] graph.add_channel(details) channel = graph.address_to_channel.get( serialized_channel.channel_address, ) channel.our_state.balance_proof = serialized_channel.our_balance_proof channel.partner_state.balance_proof = serialized_channel.partner_balance_proof
def register_channel(self, netting_channel, reveal_timeout): """ Register a new channel. Args: netting_channel (network.rpc.client.NettingChannel): The netting channel proxy. reveal_timeout (int): Minimum number of blocks required by this node to see a secret. Raises: ValueError: - If raiden.address is not one of the participants in the netting channel. - If the contract's settle_timeout is smaller than the reveal_timeout. """ # pylint: disable=too-many-locals translator = ContractTranslator(NETTING_CHANNEL_ABI) # Race condition: # - If the filter is installed after the call to `details` a deposit # can be missed, to avoid this the listener is installed first. # - Because of the above a `ChannelNewBalance` event can be polled # after the `details` calls succeds so the effects must be # idempotent. netting_channel_events = netting_channel.all_events_filter() channel_details = netting_channel.detail(self.raiden.address) our_state = ChannelEndState( channel_details['our_address'], channel_details['our_balance'], netting_channel.opened, ) partner_state = ChannelEndState( channel_details['partner_address'], channel_details['partner_balance'], netting_channel.opened, ) external_state = ChannelExternalState( self.raiden.alarm.register_callback, self.register_channel_for_hashlock, self.raiden.get_block_number, netting_channel, ) channel = Channel( our_state, partner_state, external_state, self.token_address, reveal_timeout, channel_details['settle_timeout'], ) self.partneraddress_channel[partner_state.address] = channel self.address_channel[netting_channel.address] = channel self.raiden.start_event_listener( 'NettingChannel Event {}'.format(pex(netting_channel.address)), netting_channel_events, translator, )
def register_channel(self, netting_channel, reveal_timeout): """ Register a new channel. Args: netting_channel (network.rpc.client.NettingChannel): The netting channel proxy. reveal_timeout (int): Minimum number of blocks required by this node to see a secret. Raises: ValueError: If raiden.address is not one of the participants in the netting channel. """ translator = ContractTranslator(NETTING_CHANNEL_ABI) # Race condition: # - If the filter is installed after the call to `details` a deposit # could be missed in the meantime, to avoid this we first install the # filter listener and then call `deposit`. # - Because of the above strategy a `deposit` event could be handled # twice, for this reason we must not use `deposit` in the events but # the resulting `balance`. task_name = 'ChannelNewBalance {}'.format(pex(netting_channel.address)) newbalance = netting_channel.channelnewbalance_filter() newbalance_listener = LogListenerTask( task_name, newbalance, self.raiden.on_event, translator, ) task_name = 'ChannelSecretRevelead {}'.format( pex(netting_channel.address)) secretrevealed = netting_channel.channelsecretrevealed_filter() secretrevealed_listener = LogListenerTask( task_name, secretrevealed, self.raiden.on_event, translator, ) task_name = 'ChannelClosed {}'.format(pex(netting_channel.address)) close = netting_channel.channelclosed_filter() close_listener = LogListenerTask( task_name, close, self.raiden.on_event, translator, ) task_name = 'ChannelSettled {}'.format(pex(netting_channel.address)) settled = netting_channel.channelsettled_filter() settled_listener = LogListenerTask( task_name, settled, self.raiden.on_event, translator, ) channel_details = netting_channel.detail(self.raiden.address) our_state = ChannelEndState( channel_details['our_address'], channel_details['our_balance'], ) partner_state = ChannelEndState( channel_details['partner_address'], channel_details['partner_balance'], ) external_state = ChannelExternalState( self.raiden.alarm.register_callback, self.register_channel_for_hashlock, self.raiden.chain.block_number, netting_channel, ) channel = Channel( our_state, partner_state, external_state, self.asset_address, reveal_timeout, channel_details['settle_timeout'], ) self.partneraddress_channel[partner_state.address] = channel self.address_channel[netting_channel.address] = channel newbalance_listener.start() secretrevealed_listener.start() close_listener.start() settled_listener.start() self.raiden.event_listeners.append(newbalance_listener) self.raiden.event_listeners.append(secretrevealed_listener) self.raiden.event_listeners.append(close_listener) self.raiden.event_listeners.append(settled_listener)
def register_channel(self, netting_channel, reveal_timeout): """ Register a new channel. Args: netting_channel (network.rpc.client.NettingChannel): The netting channel proxy. reveal_timeout (int): Minimum number of blocks required by this node to see a secret. Raises: ValueError: If raiden.address is not one of the participants in the netting channel. """ translator = ContractTranslator(NETTING_CHANNEL_ABI) # race condition: # - if the filter is installed after a deposit is made it could be # missed, to avoid that we first install the filter, then request the # state from the node and then poll the filter. # - with the above strategy the same deposit could be handled twice, # once from the status received from the netting contract and once from # the event, to avoid problems the we use the balance instead of the # deposit is used. newbalance = netting_channel.channelnewbalance_filter() newbalance_listener = LogListenerTask( newbalance, self.raiden.on_event, translator, ) secretrevealed = netting_channel.channelsecretrevealed_filter() secretrevealed_listener = LogListenerTask( secretrevealed, self.raiden.on_event, translator, ) close = netting_channel.channelclosed_filter() close_listener = LogListenerTask( close, self.raiden.on_event, translator, ) settled = netting_channel.channelsettled_filter() settled_listener = LogListenerTask( settled, self.raiden.on_event, translator, ) channel_details = netting_channel.detail(self.raiden.address) our_state = ChannelEndState( channel_details['our_address'], channel_details['our_balance'], ) partner_state = ChannelEndState( channel_details['partner_address'], channel_details['partner_balance'], ) external_state = ChannelExternalState( self.register_channel_for_hashlock, self.raiden.chain.block_number, netting_channel, ) channel = Channel( our_state, partner_state, external_state, self.asset_address, reveal_timeout, channel_details['settle_timeout'], ) self.partneraddress_channel[partner_state.address] = channel self.address_channel[netting_channel.address] = channel self.channelgraph.add_path( channel_details['our_address'], channel_details['partner_address'], ) newbalance_listener.start() secretrevealed_listener.start() close_listener.start() settled_listener.start() self.raiden.event_listeners.append(newbalance_listener) self.raiden.event_listeners.append(secretrevealed_listener) self.raiden.event_listeners.append(close_listener) self.raiden.event_listeners.append(settled_listener)
def test_channel(): class NettingChannelMock(object): def opened(self): return 1 def closed(self): return 0 def settled(self): return 0 asset_address = make_address() privkey1, address1 = make_privkey_address() address2 = make_address() balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 our_state = ChannelEndState(address1, balance1) partner_state = ChannelEndState(address2, balance2) block_alarm = list() channel_for_hashlock = list() netting_channel = NettingChannelMock() external_state = ChannelExternalState( block_alarm.append, lambda *args: channel_for_hashlock.append(args), lambda: 1, netting_channel, ) channel = Channel( our_state, partner_state, external_state, asset_address, reveal_timeout, settle_timeout, ) assert channel.contract_balance == our_state.contract_balance assert channel.balance == our_state.balance(partner_state) assert channel.transfered_amount == our_state.transfered_amount assert channel.distributable == our_state.distributable(partner_state) assert channel.outstanding == our_state.locked() assert channel.outstanding == 0 assert channel.locked == partner_state.locked() assert channel.our_state.locked() == 0 assert channel.partner_state.locked() == 0 with pytest.raises(ValueError): channel.create_directtransfer(-10) with pytest.raises(ValueError): channel.create_directtransfer(balance1 + 10) amount1 = 10 directtransfer = channel.create_directtransfer(amount1) directtransfer.sign(privkey1, address1) channel.register_transfer(directtransfer) assert channel.contract_balance == balance1 assert channel.balance == balance1 - amount1 assert channel.transfered_amount == amount1 assert channel.distributable == balance1 - amount1 assert channel.outstanding == 0 assert channel.locked == 0 assert channel.our_state.locked() == 0 assert channel.partner_state.locked() == 0 secret = sha3('test_channel') hashlock = sha3(secret) amount2 = 10 fee = 0 expiration = settle_timeout - 5 mediatedtransfer = channel.create_mediatedtransfer( address1, address2, fee, amount2, expiration, hashlock, ) mediatedtransfer.sign(privkey1, address1) channel.register_transfer(mediatedtransfer) assert channel.contract_balance == balance1 assert channel.balance == balance1 - amount1 assert channel.transfered_amount == amount1 assert channel.distributable == balance1 - amount1 - amount2 assert channel.outstanding == 0 assert channel.locked == amount2 assert channel.our_state.locked() == 0 assert channel.partner_state.locked() == amount2 channel.claim_lock(secret) assert channel.contract_balance == balance1 assert channel.balance == balance1 - amount1 - amount2 assert channel.transfered_amount == amount1 + amount2 assert channel.distributable == balance1 - amount1 - amount2 assert channel.outstanding == 0 assert channel.locked == 0 assert channel.our_state.locked() == 0 assert channel.partner_state.locked() == 0