def test_settled_lock(token_addresses, raiden_network, settle_timeout, reveal_timeout): """ Any transfer following a secret revealed must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ token = token_addresses[0] amount = 30 app0, app1, app2, _ = raiden_network # pylint: disable=unbalanced-tuple-unpacking address0 = app0.raiden.address address1 = app1.raiden.address forward_channel = channel(app0, app1, token) back_channel = channel(app1, app0, token) deposit0 = forward_channel.contract_balance deposit1 = back_channel.contract_balance token_contract = app0.raiden.chain.token(token) balance0 = token_contract.balance_of(address0) balance1 = token_contract.balance_of(address1) # A pending mediated transfer identifier = 1 expiration = app0.raiden.chain.block_number() + settle_timeout - reveal_timeout secret = pending_mediated_transfer( raiden_network, token, amount, identifier, expiration, ) hashlock = sha3(secret) # Get the proof to unlock the pending lock secret_transfer = get_received_transfer(back_channel, 0) lock = back_channel.partner_state.get_lock_by_hashlock(hashlock) unlock_proof = back_channel.partner_state.compute_proof_for_lock(secret, lock) # Update the hashlock claim_lock(raiden_network, identifier, token, secret) direct_transfer(app0, app1, token, amount, identifier=1) # The direct transfer locksroot must remove the unlocked lock and update # the transferred amount, the withdraw must fail. balance_proof = back_channel.partner_state.balance_proof back_channel.external_state.close(balance_proof) with pytest.raises(Exception): back_channel.external_state.netting_channel.withdraw( [(unlock_proof, secret_transfer.lock.as_bytes, secret)], ) settle_expiration = app2.raiden.chain.block_number() + settle_timeout wait_until_block(app2.raiden.chain, settle_expiration) back_channel.external_state.netting_channel.settle() assert token_contract.balance_of(address0) == balance0 + deposit0 - amount * 2 assert token_contract.balance_of(address1) == balance1 + deposit1 + amount * 2
def test_settled_lock(assets_addresses, raiden_network, settle_timeout): """ Any transfer following a secret revealed must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ asset = assets_addresses[0] amount = 30 app0, app1, app2, app3 = raiden_network # pylint: disable=unbalanced-tuple-unpacking # mediated transfer secret = pending_mediated_transfer(raiden_network, asset, amount) hashlock = sha3(secret) # get a proof for the pending transfer back_channel = channel(app1, app0, asset) secret_transfer = get_received_transfer(back_channel, 0) lock = back_channel.our_state.balance_proof.get_lock_by_hashlock(hashlock) unlock_proof = back_channel.our_state.balance_proof.compute_proof_for_lock( secret, lock) # reveal the secret claim_lock(raiden_network, asset, secret) # a new transfer to update the hashlock direct_transfer(app0, app1, asset, amount) forward_channel = channel(app0, app1, asset) last_transfer = get_sent_transfer(forward_channel, 1) # call close giving the secret for a transfer that has being revealed back_channel.external_state.netting_channel.close(app1.raiden.address, last_transfer, None) # check that the double unlock will failed with pytest.raises(Exception): back_channel.external_state.netting_channel.unlock( app1.raiden.address, [(unlock_proof, secret_transfer.lock.as_bytes, secret)], ) # forward the block number to allow settle settle_expiration = app2.raiden.chain.block_number() + settle_timeout wait_until_block(app2.raiden.chain, settle_expiration) back_channel.external_state.netting_channel.settle() participant0 = back_channel.external_state.netting_channel.contract.participants[ app0.raiden.address] participant1 = back_channel.external_state.netting_channel.contract.participants[ app1.raiden.address] assert participant0.netted == participant0.deposit - amount * 2 assert participant1.netted == participant1.deposit + amount * 2
def test_settled_lock(assets_addresses, raiden_network, settle_timeout, reveal_timeout): """ Any transfer following a secret revealed must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ asset = assets_addresses[0] amount = 30 app0, app1, app2, _ = raiden_network # pylint: disable=unbalanced-tuple-unpacking address0 = app0.raiden.address address1 = app1.raiden.address # mediated transfer identifier = 1 expiration = app0.raiden.chain.block_number() + settle_timeout - reveal_timeout secret = pending_mediated_transfer( raiden_network, asset, amount, identifier, expiration, ) hashlock = sha3(secret) # get a proof for the pending transfer back_channel = channel(app1, app0, asset) secret_transfer = get_received_transfer(back_channel, 0) lock = back_channel.our_state.balance_proof.get_lock_by_hashlock(hashlock) unlock_proof = back_channel.our_state.balance_proof.compute_proof_for_lock(secret, lock) # reveal the secret claim_lock(raiden_network, asset, secret) # a new transfer to update the hashlock direct_transfer(app0, app1, asset, amount) forward_channel = channel(app0, app1, asset) last_transfer = get_sent_transfer(forward_channel, 1) # call close giving the secret for a transfer that has being revealed back_channel.external_state.netting_channel.close( app1.raiden.address, last_transfer, None ) # check that the double unlock will failed with pytest.raises(Exception): back_channel.external_state.netting_channel.unlock( app1.raiden.address, [(unlock_proof, secret_transfer.lock.as_bytes, secret)], ) # forward the block number to allow settle settle_expiration = app2.raiden.chain.block_number() + settle_timeout wait_until_block(app2.raiden.chain, settle_expiration) back_channel.external_state.netting_channel.settle() participant0 = back_channel.external_state.netting_channel.contract.participants[address0] participant1 = back_channel.external_state.netting_channel.contract.participants[address1] assert participant0.netted == participant0.deposit - amount * 2 assert participant1.netted == participant1.deposit + amount * 2
def test_settled_lock(token_addresses, raiden_network, deposit): """ Any transfer following a secret revealed must update the locksroot, so hat an attacker cannot reuse a secret to double claim a lock.""" app0, app1 = raiden_network registry_address = app0.raiden.default_registry.address token_address = token_addresses[0] amount = 30 token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address, ) address0 = app0.raiden.address address1 = app1.raiden.address deposit0 = deposit deposit1 = deposit token_proxy = app0.raiden.chain.token(token_address) initial_balance0 = token_proxy.balance_of(address0) initial_balance1 = token_proxy.balance_of(address1) # Using a pending mediated transfer because this allows us to compute the # merkle proof identifier = 1 secret = pending_mediated_transfer( raiden_network, token_network_identifier, amount, identifier, ) # Save the merkle tree leaves from the pending transfer, used to test the unlock channelstate_0_1 = get_channelstate(app0, app1, token_network_identifier) batch_unlock = channel.get_batch_unlock(channelstate_0_1.our_state) assert batch_unlock claim_lock(raiden_network, identifier, token_network_identifier, secret) # Make a new transfer direct_transfer(app0, app1, token_network_identifier, amount, identifier=1) RaidenAPI(app1.raiden).channel_close( registry_address, token_address, app0.raiden.address, ) waiting.wait_for_settle( app1.raiden, app1.raiden.default_registry.address, token_address, [channelstate_0_1.identifier], app1.raiden.alarm.sleep_time, ) netting_channel = app1.raiden.chain.payment_channel( token_network_identifier, channelstate_0_1.identifier, ) # The direct transfer locksroot must not contain the unlocked lock, the # unlock must fail. with pytest.raises(Exception): netting_channel.unlock( channelstate_0_1.partner_state.address, batch_unlock, ) expected_balance0 = initial_balance0 + deposit0 - amount * 2 expected_balance1 = initial_balance1 + deposit1 + amount * 2 assert token_proxy.balance_of(address0) == expected_balance0 assert token_proxy.balance_of(address1) == expected_balance1
def test_settled_lock(token_addresses, raiden_network, settle_timeout, reveal_timeout): """ Any transfer following a secret revealed must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ token = token_addresses[0] amount = 30 app0, app1, app2, _ = raiden_network # pylint: disable=unbalanced-tuple-unpacking address0 = app0.raiden.address address1 = app1.raiden.address forward_channel = channel(app0, app1, token) back_channel = channel(app1, app0, token) deposit0 = forward_channel.contract_balance deposit1 = back_channel.contract_balance token_contract = app0.raiden.chain.token(token) balance0 = token_contract.balance_of(address0) balance1 = token_contract.balance_of(address1) # mediated transfer identifier = 1 expiration = app0.raiden.chain.block_number( ) + settle_timeout - reveal_timeout secret = pending_mediated_transfer( raiden_network, token, amount, identifier, expiration, ) hashlock = sha3(secret) # get a proof for the pending transfer secret_transfer = get_received_transfer(back_channel, 0) lock = back_channel.our_state.balance_proof.get_lock_by_hashlock(hashlock) unlock_proof = back_channel.our_state.balance_proof.compute_proof_for_lock( secret, lock) # reveal the secret claim_lock(raiden_network, token, secret) # a new transfer to update the hashlock direct_transfer(app0, app1, token, amount) last_transfer = get_sent_transfer(forward_channel, 1) # call close giving the secret for a transfer that has being revealed back_channel.external_state.netting_channel.close(last_transfer) # check that the double unlock will fail with pytest.raises(Exception): back_channel.external_state.netting_channel.withdraw( [(unlock_proof, secret_transfer.lock.as_bytes, secret)], ) # forward the block number to allow settle settle_expiration = app2.raiden.chain.block_number() + settle_timeout wait_until_block(app2.raiden.chain, settle_expiration) back_channel.external_state.netting_channel.settle() assert token_contract.balance_of( address0) == balance0 + deposit0 - amount * 2 assert token_contract.balance_of( address1) == balance1 + deposit1 + amount * 2
def test_settled_lock(token_addresses, raiden_network, deposit): """ Any transfer following a secret revealed must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock.""" app0, app1 = raiden_network token_address = token_addresses[0] amount = 30 address0 = app0.raiden.address address1 = app1.raiden.address deposit0 = deposit deposit1 = deposit token_proxy = app0.raiden.chain.token(token_address) initial_balance0 = token_proxy.balance_of(address0) initial_balance1 = token_proxy.balance_of(address1) # Using a pending mediated transfer because this allows us to compute the # merkle proof identifier = 1 secret = pending_mediated_transfer( raiden_network, token_address, amount, identifier, ) hashlock = sha3(secret) # Compute the merkle proof for the pending transfer, and then unlock channelstate_0_1 = get_channelstate(app0, app1, token_address) lock = channel.get_lock(channelstate_0_1.our_state, hashlock) unlock_proof = channel.compute_proof_for_lock( channelstate_0_1.our_state, secret, lock, ) claim_lock(raiden_network, identifier, token_address, secret) # Make a new transfer direct_transfer(app0, app1, token_address, amount, identifier=1) RaidenAPI(app1.raiden).channel_close(token_address, app0.raiden.address) # The direct transfer locksroot must not contain the unlocked lock, the # withdraw must fail. netting_channel = app1.raiden.chain.netting_channel( channelstate_0_1.identifier) with pytest.raises(Exception): netting_channel.withdraw( UnlockProofState(unlock_proof, lock.encoded, secret)) waiting.wait_for_settle( app1.raiden, app1.raiden.default_registry.address, token_address, [channelstate_0_1.identifier], app1.raiden.alarm.wait_time, ) expected_balance0 = initial_balance0 + deposit0 - amount * 2 expected_balance1 = initial_balance1 + deposit1 + amount * 2 assert token_proxy.balance_of(address0) == expected_balance0 assert token_proxy.balance_of(address1) == expected_balance1
def test_settled_lock(token_addresses, raiden_network, settle_timeout, reveal_timeout): """ Any transfer following a secret revealed must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ token = token_addresses[0] amount = 30 app0, app1, app2, _ = raiden_network # pylint: disable=unbalanced-tuple-unpacking address0 = app0.raiden.address address1 = app1.raiden.address forward_channel = channel(app0, app1, token) back_channel = channel(app1, app0, token) deposit0 = forward_channel.contract_balance deposit1 = back_channel.contract_balance token_contract = app0.raiden.chain.token(token) balance0 = token_contract.balance_of(address0) balance1 = token_contract.balance_of(address1) # A pending mediated transfer identifier = 1 expiration = app0.raiden.chain.block_number( ) + settle_timeout - reveal_timeout secret = pending_mediated_transfer( raiden_network, token, amount, identifier, expiration, ) hashlock = sha3(secret) # Get the proof to unlock the pending lock secret_transfer = get_received_transfer(back_channel, 0) lock = back_channel.partner_state.balance_proof.get_lock_by_hashlock( hashlock) unlock_proof = back_channel.partner_state.balance_proof.compute_proof_for_lock( secret, lock) # Update the hashlock claim_lock(raiden_network, identifier, token, secret) direct_transfer(app0, app1, token, amount, identifier=1) # The direct transfer locksroot must remove the unlocked lock and update # the transferred amount, the withdraw must fail. balance_proof = back_channel.partner_state.balance_proof.balance_proof back_channel.external_state.close(balance_proof) with pytest.raises(Exception): back_channel.external_state.netting_channel.withdraw( [(unlock_proof, secret_transfer.lock.as_bytes, secret)], ) settle_expiration = app2.raiden.chain.block_number() + settle_timeout wait_until_block(app2.raiden.chain, settle_expiration) back_channel.external_state.netting_channel.settle() assert token_contract.balance_of( address0) == balance0 + deposit0 - amount * 2 assert token_contract.balance_of( address1) == balance1 + deposit1 + amount * 2
def test_settled_lock(token_addresses, raiden_network, deposit): """ Any transfer following a secret reveal must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ app0, app1 = raiden_network registry_address = app0.raiden.default_registry.address token_address = token_addresses[0] amount = 30 token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address, ) hold_event_handler = HoldOffChainSecretRequest() app1.raiden.raiden_event_handler = hold_event_handler address0 = app0.raiden.address address1 = app1.raiden.address deposit0 = deposit deposit1 = deposit token_proxy = app0.raiden.chain.token(token_address) initial_balance0 = token_proxy.balance_of(address0) initial_balance1 = token_proxy.balance_of(address1) identifier = 1 target = app1.raiden.address secret = sha3(target) secrethash = sha3(secret) hold_event_handler.hold_secret_for(secrethash=secrethash) app0.raiden.start_mediated_transfer_with_secret( token_network_identifier, amount, target, identifier, secret, ) gevent.sleep(1) # wait for the messages to be exchanged # Save the merkle tree leaves from the pending transfer, used to test the unlock channelstate_0_1 = get_channelstate(app0, app1, token_network_identifier) batch_unlock = channel.get_batch_unlock(channelstate_0_1.our_state) assert batch_unlock claim_lock(raiden_network, identifier, token_network_identifier, secret) # Make a new transfer direct_transfer(app0, app1, token_network_identifier, amount, identifier=2) RaidenAPI(app1.raiden).channel_close( registry_address, token_address, app0.raiden.address, ) waiting.wait_for_settle( app1.raiden, app1.raiden.default_registry.address, token_address, [channelstate_0_1.identifier], app1.raiden.alarm.sleep_time, ) netting_channel = app1.raiden.chain.payment_channel( token_network_identifier, channelstate_0_1.identifier, ) # The direct transfer locksroot must not contain the unlocked lock, the # unlock must fail. with pytest.raises(Exception): netting_channel.unlock( channelstate_0_1.partner_state.address, batch_unlock, ) expected_balance0 = initial_balance0 + deposit0 - amount * 2 expected_balance1 = initial_balance1 + deposit1 + amount * 2 assert token_proxy.balance_of(address0) == expected_balance0 assert token_proxy.balance_of(address1) == expected_balance1