def test_close_valid_tranfer_different_token(tester_state, tester_nettingcontracts, token_amount, tester_events): """ Valid messages from a different channel must be rejected. """ pkey0, pkey1, nettingchannel = tester_nettingcontracts[0] from raiden.tests.fixtures.tester import ( tester_token, tester_token_address, ) private_keys = [pkey0, pkey1] other_token = tester_token( token_amount, private_keys, tester_state, tester_token_address(private_keys, token_amount, tester_state), tester_events, ) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2**32)) direct_transfer_other_token = make_direct_transfer( nonce=nonce, token=other_token.address, ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer_other_token.sign(sign_key, address) direct_transfer_data = direct_transfer_other_token.encode() with pytest.raises(TransactionFailed): nettingchannel.close(direct_transfer_data, sender=pkey1)
def test_decode_tampered_direct_transfer(tester_state, tester_nettingchannel_library_address): privatekey0 = tester.DEFAULT_KEY address0 = privatekey_to_address(privatekey0) decoder = deploy_decoder_tester(tester_state, tester_nettingchannel_library_address) direct_transfer = make_direct_transfer() direct_transfer.sign(PrivateKey(privatekey0), address0) message_encoded = direct_transfer.encode() transfer_raw, _ = decoder.getTransferRawAddress(message_encoded) names_slices = compute_slices(messages.DirectTransfer.fields_spec) for name, slice_ in names_slices.iteritems(): if name == 'signature': continue tampered_transfer = bytearray(transfer_raw) tampered_transfer.pop(slice_.start) tampered_transfer = str(tampered_transfer) with pytest.raises(TransactionFailed): decoder.decodeTransfer(tampered_transfer) tampered_transfer = bytearray(transfer_raw) tampered_transfer.pop(slice_.stop - 1) tampered_transfer = str(tampered_transfer) with pytest.raises(TransactionFailed): decoder.decodeTransfer(tampered_transfer)
def test_withdraw_tampered_lock_amount(tree, tester_channels, tester_state, tester_token, settle_timeout): """ withdraw must fail if the lock amonut is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_state.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] merkle_tree = Merkletree(sha3(lock.as_bytes) for lock in locks) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2**32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.channel_address, locksroot=merkle_tree.merkleroot, token=tester_token.address, recipient=privatekey_to_address(pkey1)) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = merkle_tree.make_proof(sha3(lock_encoded)) tampered_lock = make_lock( amount=lock.amount * 100, hashlock=lock.hashlock, expiration=lock.expiration, ) tampered_lock_encoded = sha3(tampered_lock.as_bytes) with pytest.raises(TransactionFailed): nettingchannel.withdraw( tampered_lock_encoded, ''.join(merkle_proof), secret, sender=pkey1, )
def test_withdraw_fails_with_partial_merkle_proof(tree, tester_channels, tester_chain, settle_timeout): """ withdraw must fail if informed proof is not complete. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2**32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.identifier, locksroot=merkleroot(merkle_tree), recipient=privatekey_to_address(pkey1)) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) # withdraw must fail regardless of which part of the proof is removed for hash_ in merkle_proof: tampered_proof = list(merkle_proof) tampered_proof.remove(hash_) with pytest.raises(TransactionFailed): nettingchannel.withdraw( lock_encoded, b''.join(tampered_proof), secret, sender=pkey1, )
def test_direct_transfer_min_max(identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY, ADDRESS) assert decode(direct_transfer.encode()) == direct_transfer
def test_direct_transfer_min_max(payment_identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY) assert DirectTransfer.from_dict(direct_transfer.to_dict()) == direct_transfer
def test_direct_transfer_min_max(identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY, ADDRESS) assert DirectTransfer.from_dict( direct_transfer.to_dict()) == direct_transfer
def test_direct_transfer_min_max(payment_identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY) assert direct_transfer.sender == ADDRESS assert decode(direct_transfer.encode()) == direct_transfer
def test_direct_transfer_min_max(payment_identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY, UNIT_CHAIN_ID) assert DirectTransfer.from_dict( direct_transfer.to_dict()) == direct_transfer
def test_direct_transfer_min_max(payment_identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY, UNIT_CHAIN_ID) assert direct_transfer.sender == ADDRESS assert decode(direct_transfer.encode()) == direct_transfer
def test_withdraw_tampered_merkle_proof(tree, tester_channels, tester_state, settle_timeout): """ withdraw must fail if the proof is tampered. """ pkey0, pkey1, nettingchannel, _, _ = tester_channels[0] current_block = tester_state.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] merkle_tree = Merkletree(sha3(lock.as_bytes) for lock in locks) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2**32)) direct_transfer = make_direct_transfer( nonce=nonce, locksroot=merkle_tree.merkleroot, recipient=privatekey_to_address(pkey1)) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_data = str(direct_transfer.packed().data) nettingchannel.close(direct_transfer_data, sender=pkey1) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = merkle_tree.make_proof(sha3(lock_encoded)) # withdraw must fail regardless of which part of the proof is tampered for pos, hash_ in enumerate(merkle_proof): # changing arbitrary bytes from the proof tampered_hash = bytearray(hash_) tampered_hash[5], tampered_hash[6] = tampered_hash[ 6], tampered_hash[5] tampered_proof = list(merkle_proof) tampered_proof[pos] = str(tampered_hash) with pytest.raises(TransactionFailed): nettingchannel.withdraw( lock_encoded, ''.join(tampered_proof), secret, sender=pkey1, )
def test_withdraw_fails_with_partial_merkle_proof( tree, tester_channels, tester_state, settle_timeout): """ withdraw must fail if informed proof is not complete. """ pkey0, pkey1, nettingchannel, _, _ = tester_channels[0] current_block = tester_state.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] merkle_tree = Merkletree(sha3(lock.as_bytes) for lock in locks) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer = make_direct_transfer( nonce=nonce, locksroot=merkle_tree.merkleroot, ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_data = str(direct_transfer.packed().data) nettingchannel.close(direct_transfer_data, sender=pkey1) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = merkle_tree.make_proof(sha3(lock_encoded)) # withdraw must fail regardless of which part of the proof is removed for hash_ in merkle_proof: tampered_proof = list(merkle_proof) tampered_proof.remove(hash_) with pytest.raises(TransactionFailed): nettingchannel.withdraw( lock_encoded, ''.join(tampered_proof), secret, sender=pkey1, )
def test_channel_closed_must_clear_ordered_messages( chain_id, chain_state, payment_network_state, token_network_state, netting_channel_state, ): recipient = netting_channel_state.partner_state.address channel_identifier = netting_channel_state.identifier message_identifier = random.randint(0, 2**16) amount = 10 queue_identifier = QueueIdentifier( recipient, channel_identifier, ) # Regression test: # The code delivered_message handler worked only with a queue of one # element message = make_direct_transfer( message_identifier=message_identifier, registry_address=payment_network_state.address, token=token_network_state.token_address, channel_identifier=channel_identifier, transferred_amount=amount, recipient=recipient, ) chain_state.queueids_to_queues[queue_identifier] = [message] closed = state_change.ContractReceiveChannelClosed( transaction_hash=EMPTY_HASH, transaction_from=recipient, token_network_identifier=token_network_state.address, channel_identifier=channel_identifier, block_number=1, ) iteration = node.handle_state_change( chain_state, closed, ) assert queue_identifier not in iteration.new_state.queueids_to_queues
def test_close_valid_tranfer_different_token( tester_chain, tester_nettingcontracts, token_amount, tester_events): """ Valid messages from a different channel must be rejected. """ pkey0, pkey1, nettingchannel = tester_nettingcontracts[0] from raiden.tests.fixtures.tester import ( tester_token, tester_token_address, ) private_keys = [pkey0, pkey1] other_token = tester_token( token_amount, private_keys, tester_chain, tester_token_address(private_keys, token_amount, tester_chain), tester_events, ) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer_other_token = make_direct_transfer( nonce=nonce, token=other_token.address, ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer_other_token.sign(sign_key, address) direct_transfer_other_token_hash = sha3(direct_transfer_other_token.encode()[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( direct_transfer_other_token.nonce, direct_transfer_other_token.transferred_amount, direct_transfer_other_token.locksroot, direct_transfer_other_token_hash, direct_transfer_other_token.signature, sender=pkey1, )
def test_decode_direct_transfer( identifier, nonce, transferred_amount, locksroot, tester_state, tester_nettingchannel_library_address): privatekey0 = tester.DEFAULT_KEY address0 = privatekey_to_address(privatekey0) decoder = deploy_decoder_tester(tester_state, tester_nettingchannel_library_address) direct_transfer = make_direct_transfer( identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, locksroot=locksroot, ) direct_transfer.sign(PrivateKey(privatekey0), address0) assert_decoder_results(direct_transfer, decoder)
def test_withdraw_tampered_lock_amount( tree, tester_channels, tester_chain, tester_token, settle_timeout): """ withdraw must fail if the lock amonut is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.channel_address, locksroot=merkleroot(merkle_tree), token=tester_token.address, recipient=privatekey_to_address(pkey1) ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) tampered_lock = make_lock( amount=lock.amount * 100, hashlock=lock.hashlock, expiration=lock.expiration, ) tampered_lock_encoded = sha3(tampered_lock.as_bytes) with pytest.raises(TransactionFailed): nettingchannel.withdraw( tampered_lock_encoded, b''.join(merkle_proof), secret, sender=pkey1, )
def test_direct_transfer_out_of_bounds_values(args): with pytest.raises(ValueError): make_direct_transfer(**args)
def test_withdraw_tampered_lock_amount( tree, tester_channels, tester_chain, tester_token, settle_timeout, ): """ withdraw must fail if the lock amonut is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( secrethash=secrethash, expiration=expiration, ) for secrethash in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.identifier, locksroot=merkleroot(merkle_tree), token=tester_token.address, recipient=privatekey_to_address(pkey1), ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = SECRETHASHES_SECRESTS[lock.secrethash] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) tampered_lock = make_lock( amount=lock.amount * 100, secrethash=lock.secrethash, expiration=lock.expiration, ) tampered_lock_encoded = sha3(tampered_lock.as_bytes) with pytest.raises(TransactionFailed): nettingchannel.withdraw( tampered_lock_encoded, b''.join(merkle_proof), secret, sender=pkey1, )
def test_withdraw_tampered_merkle_proof(tree, tester_channels, tester_chain, settle_timeout): """ withdraw must fail if the proof is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( secrethash=secrethash, expiration=expiration, ) for secrethash in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.identifier, locksroot=merkleroot(merkle_tree), recipient=privatekey_to_address(pkey1), ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = SECRETHASHES_SECRESTS[lock.secrethash] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) # withdraw must fail regardless of which part of the proof is tampered for pos, hash_ in enumerate(merkle_proof): # changing arbitrary bytes from the proof tampered_hash = bytearray(hash_) tampered_hash[6], tampered_hash[7] = tampered_hash[7], tampered_hash[6] tampered_proof = list(merkle_proof) tampered_proof[pos] = tampered_hash joiner = b'' with pytest.raises(TransactionFailed): nettingchannel.withdraw( lock_encoded, joiner.join(tampered_proof), secret, sender=pkey1, )
def test_direct_transfer_out_of_bounds_values(): for args in DIRECT_TRANSFER_INVALID_VALUES: with pytest.raises(ValueError): make_direct_transfer(**args)
def test_direct_transfer_out_of_bounds_values(): for args in DIRECT_TRANSFER_INVALID_VALUES: with pytest.raises(ValueError): make_direct_transfer(**args)
def test_withdraw_tampered_merkle_proof(tree, tester_channels, tester_chain, settle_timeout): """ withdraw must fail if the proof is tampered. """ pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0] current_block = tester_chain.block.number expiration = current_block + settle_timeout - 1 locks = [ make_lock( hashlock=hashlock, expiration=expiration, ) for hashlock in tree ] leaves = [sha3(lock.as_bytes) for lock in locks] layers = compute_layers(leaves) merkle_tree = MerkleTreeState(layers) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) direct_transfer = make_direct_transfer( nonce=nonce, channel=channel0.channel_address, locksroot=merkleroot(merkle_tree), recipient=privatekey_to_address(pkey1) ) address = privatekey_to_address(pkey0) sign_key = PrivateKey(pkey0) direct_transfer.sign(sign_key, address) direct_transfer_hash = sha3(direct_transfer.packed().data[:-65]) nettingchannel.close( direct_transfer.nonce, direct_transfer.transferred_amount, direct_transfer.locksroot, direct_transfer_hash, direct_transfer.signature, sender=pkey1, ) for lock in locks: secret = HASHLOCKS_SECRESTS[lock.hashlock] lock_encoded = lock.as_bytes merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded)) # withdraw must fail regardless of which part of the proof is tampered for pos, hash_ in enumerate(merkle_proof): # changing arbitrary bytes from the proof tampered_hash = bytearray(hash_) tampered_hash[6], tampered_hash[7] = tampered_hash[7], tampered_hash[6] tampered_proof = list(merkle_proof) tampered_proof[pos] = tampered_hash joiner = b'' with pytest.raises(TransactionFailed): nettingchannel.withdraw( lock_encoded, joiner.join(tampered_proof), secret, sender=pkey1, )