Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
unlock on chain.
"""
# reveal timeout will not ever be larger than the lock_expiration otherwise
# the expected block_number is negative
assert block_number > 0
assert reveal_timeout > 0
assert lock_expiration > reveal_timeout
lock_timeout = lock_expiration - block_number
# A node may wait for a new balance proof while there are reveal_timeout
# blocks left, at that block and onwards it is not safe to wait.
if lock_timeout > reveal_timeout:
return SuccessOrError()
return SuccessOrError(
f"lock timeout is unsafe."
f" timeout must be larger than {reveal_timeout}, but it is {lock_timeout}."
def is_valid_signature(
data: bytes, signature: Signature, sender_address: Address
) -> SuccessOrError:
try:
signer_address = recover(data=data, signature=signature)
# InvalidSignature is raised by raiden.utils.signer.recover if signature
# is not bytes or has the incorrect length.
# ValueError is raised if the PublicKey instantiation failed.
# Exception is raised if the public key recovery failed.
except Exception: # pylint: disable=broad-except
return SuccessOrError("Signature invalid, could not be recovered.")
is_correct_sender = sender_address == signer_address
if is_correct_sender:
return SuccessOrError()
return SuccessOrError("Signature was valid but the expected address does not match.")
data: bytes, signature: Signature, sender_address: Address
) -> SuccessOrError:
try:
signer_address = recover(data=data, signature=signature)
# InvalidSignature is raised by raiden.utils.signer.recover if signature
# is not bytes or has the incorrect length.
# ValueError is raised if the PublicKey instantiation failed.
# Exception is raised if the public key recovery failed.
except Exception: # pylint: disable=broad-except
return SuccessOrError("Signature invalid, could not be recovered.")
is_correct_sender = sender_address == signer_address
if is_correct_sender:
return SuccessOrError()
return SuccessOrError("Signature was valid but the expected address does not match.")
withdraw_expired = is_withdraw_expired(
block_number=block_number,
expiration_threshold=get_receiver_expiration_threshold(
expiration=withdraw_state.expiration
),
)
if not withdraw_expired:
return SuccessOrError(
f"WithdrawExpired for withdraw that has not yet expired {state_change.total_withdraw}."
)
elif channel_state.canonical_identifier != state_change.canonical_identifier:
return SuccessOrError(f"Invalid canonical identifier provided in WithdrawExpire")
elif state_change.sender != channel_state.partner_state.address:
return SuccessOrError("Expired withdraw not from partner.")
elif state_change.total_withdraw != withdraw_state.total_withdraw:
return SuccessOrError(
f"WithdrawExpired and local withdraw amounts do not match. Received "
f"{state_change.total_withdraw}, local amount "
f"{withdraw_state.total_withdraw}"
)
elif state_change.nonce != expected_nonce:
return SuccessOrError(
f"Nonce did not change sequentially, expected: {expected_nonce} "
f"got: {state_change.nonce}."
)
else:
return SuccessOrError()
fields locksroot, transferred_amount, and locked_amount **MUST** be
validated elsewhere based on the message type.
"""
expected_nonce = get_next_nonce(sender_state)
is_valid_signature = is_valid_balanceproof_signature(
received_balance_proof, sender_state.address
)
# TODO: Accept unlock messages if the node has not yet sent a transaction
# with the balance proof to the blockchain, this will save one call to
# unlock on-chain for the non-closing party.
if get_status(channel_state) != ChannelState.STATE_OPENED:
# The channel must be opened, otherwise if receiver is the closer, the
# balance proof cannot be used onchain.
return SuccessOrError("The channel is already closed.")
elif received_balance_proof.channel_identifier != channel_state.identifier:
# Informational message, the channel_identifier **validated by the
# signature** must match for the balance_proof to be valid.
return SuccessOrError(
f"channel_identifier does not match. "
f"expected: {channel_state.identifier} "
f"got: {received_balance_proof.channel_identifier}."
)
elif received_balance_proof.token_network_address != channel_state.token_network_address:
# Informational message, the token_network_address **validated by
# the signature** must match for the balance_proof to be valid.
return SuccessOrError(
f"token_network_address does not match. "
f"expected: {channel_state.token_network_address} "
withdraw_overflow = not is_valid_channel_total_withdraw(
TokenAmount(withdraw_request.total_withdraw + channel_state.our_total_withdraw)
)
# The confirming node must accept an expired withdraw request. This is
# necessary to clear the requesting node's queue. This is not a security
# flaw because the smart contract will not allow the withdraw to happen.
if channel_state.canonical_identifier != withdraw_request.canonical_identifier:
return SuccessOrError(f"Invalid canonical identifier provided in withdraw request")
elif withdraw_request.participant != channel_state.partner_state.address:
return SuccessOrError(f"Invalid participant, it must be the partner address")
elif withdraw_request.sender != channel_state.partner_state.address:
return SuccessOrError(f"Invalid sender, withdraw request must be sent by the partner.")
elif withdraw_amount <= 0:
return SuccessOrError(f"Total withdraw {withdraw_request.total_withdraw} did not increase")
elif balance < withdraw_amount:
return SuccessOrError(
f"Insufficient balance: {balance}. Requested {withdraw_amount} for withdraw"
)
elif withdraw_request.nonce != expected_nonce:
return SuccessOrError(
f"Nonce did not change sequentially, expected: {expected_nonce} "
f"got: {withdraw_request.nonce}."
)
elif withdraw_overflow:
return SuccessOrError(
f"The new total_withdraw {withdraw_request.total_withdraw} will cause an overflow"
)
else:
return is_valid
The lock has expired if both:
- The secret was not registered on-chain in time.
- The current block exceeds lock's expiration + confirmation blocks.
"""
secret_registered_on_chain = lock.secrethash in end_state.secrethashes_to_onchain_unlockedlocks
if secret_registered_on_chain:
return SuccessOrError("lock has been unlocked on-chain")
if block_number < lock_expiration_threshold:
return SuccessOrError(
f"current block number ({block_number}) is not larger than "
f"lock.expiration + confirmation blocks ({lock_expiration_threshold})"
)
return SuccessOrError()
def is_valid_signature(
data: bytes, signature: Signature, sender_address: Address
) -> SuccessOrError:
try:
signer_address = recover(data=data, signature=signature)
# InvalidSignature is raised by raiden.utils.signer.recover if signature
# is not bytes or has the incorrect length.
# ValueError is raised if the PublicKey instantiation failed.
# Exception is raised if the public key recovery failed.
except Exception: # pylint: disable=broad-except
return SuccessOrError("Signature invalid, could not be recovered.")
is_correct_sender = sender_address == signer_address
if is_correct_sender:
return SuccessOrError()
return SuccessOrError("Signature was valid but the expected address does not match.")