def handle_secretreveal( target_state: TargetTransferState, state_change: ReceiveSecretReveal, channel_state: NettingChannelState, pseudo_random_generator: random.Random, ): """ Validates and handles a ReceiveSecretReveal state change. """ valid_secret = state_change.secrethash == target_state.transfer.lock.secrethash waiting_for_secret = target_state.state == 'secret_request' if valid_secret and waiting_for_secret: if isinstance(state_change, ReceiveSecretReveal): channel.register_secret( channel_state, state_change.secret, state_change.secrethash, ) elif isinstance(state_change, ContractReceiveSecretReveal): channel.register_onchain_secret( channel_state=channel_state, secret=state_change.secret, secrethash=state_change.secrethash, secret_reveal_block_number=state_change.block_number, ) else: assert False, 'Got unexpected StateChange' route = target_state.route message_identifier = message_identifier_from_prng( pseudo_random_generator) target_state.state = 'reveal_secret' target_state.secret = state_change.secret recipient = route.node_address # Send the secret reveal message only once, delivery is guaranteed by # the transport and not by the state machine reveal = SendSecretReveal( recipient=recipient, channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE, message_identifier=message_identifier, secret=target_state.secret, ) iteration = TransitionResult(target_state, [reveal]) else: # TODO: event for byzantine behavior iteration = TransitionResult(target_state, list()) return iteration
def handle_offchain_secretreveal( target_state: TargetTransferState, state_change: ReceiveSecretReveal, channel_state: NettingChannelState, pseudo_random_generator: random.Random, block_number: BlockNumber, ): """ Validates and handles a ReceiveSecretReveal state change. """ valid_secret = is_valid_secret_reveal( state_change=state_change, transfer_secrethash=target_state.transfer.lock.secrethash, secret=state_change.secret, ) has_transfer_expired = channel.transfer_expired( transfer=target_state.transfer, affected_channel=channel_state, block_number=block_number, ) if valid_secret and not has_transfer_expired: channel.register_offchain_secret( channel_state=channel_state, secret=state_change.secret, secrethash=state_change.secrethash, ) route = target_state.route message_identifier = message_identifier_from_prng( pseudo_random_generator) target_state.state = TargetTransferState.OFFCHAIN_SECRET_REVEAL target_state.secret = state_change.secret recipient = route.node_address reveal = SendSecretReveal( recipient=recipient, channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE, message_identifier=message_identifier, secret=target_state.secret, ) iteration = TransitionResult(target_state, [reveal]) else: # TODO: event for byzantine behavior iteration = TransitionResult(target_state, list()) return iteration
def handle_offchain_secretreveal( target_state: TargetTransferState, state_change: ReceiveSecretReveal, channel_state: NettingChannelState, pseudo_random_generator: random.Random, block_number: BlockNumber, ): """ Validates and handles a ReceiveSecretReveal state change. """ valid_secret = is_valid_secret_reveal( state_change=state_change, transfer_secrethash=target_state.transfer.lock.secrethash, secret=state_change.secret, ) has_transfer_expired = channel.transfer_expired( transfer=target_state.transfer, affected_channel=channel_state, block_number=block_number, ) if valid_secret and not has_transfer_expired: channel.register_offchain_secret( channel_state=channel_state, secret=state_change.secret, secrethash=state_change.secrethash, ) route = target_state.route message_identifier = message_identifier_from_prng(pseudo_random_generator) target_state.state = TargetTransferState.OFFCHAIN_SECRET_REVEAL target_state.secret = state_change.secret recipient = route.node_address reveal = SendSecretReveal( recipient=recipient, channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE, message_identifier=message_identifier, secret=target_state.secret, ) iteration = TransitionResult(target_state, [reveal]) else: # TODO: event for byzantine behavior iteration = TransitionResult(target_state, list()) return iteration
def handle_onchain_secretreveal( target_state: TargetTransferState, state_change: ContractReceiveSecretReveal, channel_state: NettingChannelState, ): """ Validates and handles a ContractReceiveSecretReveal state change. """ valid_secret = state_change.secrethash == target_state.transfer.lock.secrethash if valid_secret: channel.register_onchain_secret( channel_state=channel_state, secret=state_change.secret, secrethash=state_change.secrethash, secret_reveal_block_number=state_change.block_number, ) target_state.state = 'reveal_secret' target_state.secret = state_change.secret return TransitionResult(target_state, list())
def handle_offchain_secretreveal( target_state: TargetTransferState, state_change: ReceiveSecretReveal, channel_state: NettingChannelState, pseudo_random_generator: random.Random, ): """ Validates and handles a ReceiveSecretReveal state change. """ valid_secret = state_change.secrethash == target_state.transfer.lock.secrethash if valid_secret: channel.register_offchain_secret( channel_state=channel_state, secret=state_change.secret, secrethash=state_change.secrethash, ) route = target_state.route message_identifier = message_identifier_from_prng( pseudo_random_generator) target_state.state = 'reveal_secret' target_state.secret = state_change.secret recipient = route.node_address reveal = SendSecretReveal( recipient=recipient, channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE, message_identifier=message_identifier, secret=target_state.secret, ) iteration = TransitionResult(target_state, [reveal]) else: # TODO: event for byzantine behavior iteration = TransitionResult(target_state, list()) return iteration
def handle_onchain_secretreveal( target_state: TargetTransferState, state_change: ContractReceiveSecretReveal, channel_state: NettingChannelState, ): """ Validates and handles a ContractReceiveSecretReveal state change. """ valid_secret = is_valid_secret_reveal( state_change=state_change, transfer_secrethash=target_state.transfer.lock.secrethash, secret=state_change.secret, ) if valid_secret: channel.register_onchain_secret( channel_state=channel_state, secret=state_change.secret, secrethash=state_change.secrethash, secret_reveal_block_number=state_change.block_number, ) target_state.state = TargetTransferState.ONCHAIN_UNLOCK target_state.secret = state_change.secret return TransitionResult(target_state, list())
def handle_offchain_secretreveal_light( target_state: TargetTransferState, state_change: ReceiveSecretRevealLight, channel_state: NettingChannelState, pseudo_random_generator: random.Random, block_number: BlockNumber, ) -> TransitionResult[TargetTransferState]: """ Validates and handles a ReceiveSecretReveal state change. """ valid_secret = is_valid_secret_reveal( state_change=state_change, transfer_secrethash=target_state.transfer.lock.secrethash, secret=state_change.secret, ) has_transfer_expired = channel.is_transfer_expired( transfer=target_state.transfer, affected_channel=channel_state, block_number=block_number ) if valid_secret and not has_transfer_expired: # TODO mmarcosmartinez7 this cannot be done without LC interaction # channel.register_offchain_secret( # channel_state=channel_state, # secret=state_change.secret, # secrethash=state_change.secrethash, # ) route = target_state.route message_identifier = message_identifier_from_prng(pseudo_random_generator) target_state.state = TargetTransferState.OFFCHAIN_SECRET_REVEAL target_state.secret = state_change.secret recipient = route.node_address # Store reveal secret 7, create reveal secret 9 and store it for LC signing. received_reveal_secret = state_change.secret_reveal_message reveal_secret_to_send_event = SendSecretReveal( recipient=recipient, channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE, message_identifier=message_identifier, secret=target_state.secret, ) reveal_secret_to_send_msg = message_from_sendevent(reveal_secret_to_send_event) store_received_reveal = StoreMessageEvent( received_reveal_secret.message_identifier, target_state.transfer.payment_identifier, 7, received_reveal_secret, True ) store_reveal_to_send = StoreMessageEvent( message_identifier, target_state.transfer.payment_identifier, 9, reveal_secret_to_send_msg, False ) iteration = TransitionResult(target_state, [store_received_reveal, store_reveal_to_send]) else: # TODO: event for byzantine behavior iteration = TransitionResult(target_state, list()) return iteration