def execute(self, block_height, invoker='', channel_name='', hashcode='', invoker_key=''): """ :param block_height: :param invoker: :param channel_name: :param hashcode: :param invoker_key: :return: """ super(ChannelSettleHtlcUnlockEvent, self).execute(block_height) # close channel event result = self.contract_event_api.settle_after_htlc_unlock_payment( invoker_key, channel_name, hashcode, invoker_key) # set channel settling if result is not None and 'success' in result.values(): Channel.update_channel(self.channel_name, state=EnumChannelState.SETTLED.name) self.next_stage()
def prepare(self, block_height, address='', deposit=0.0, key=''): super(ChannelDepositEvent, self).prepare(block_height) # if this transaction id is approved, it means successful by eth block chain if self.approved_tx_id: checked = self.check_transaction_success(self.approved_tx_id) if checked: LOG.debug('Approved asset by address<{}:{}>'.format(address, deposit)) Channel.update_channel(self.channel_name, state=EnumChannelState.OPENING.name) LOG.info('Start to create channel<{}>. State: OPENING.'.format(self.channel_name)) console_log.info('Channel<{}> is opening'.format(self.channel_name)) # go to next stage self.next_stage() return True elif checked is False: return False else: # new transaction is pushed to chain self.approved_tx_id = None else: approved_deposit = self.contract_event_api.get_approved_asset(address) if approved_deposit >= int(deposit): LOG.debug('Has already approved: {}'.format(approved_deposit)) # go to next stage self.next_stage() return True # make transaction to chain result = self.contract_event_api.approve(address, int(deposit), key, gwei_coef=self.gwei_coef) if result: self.approved_tx_id = '0x'+result.strip() return False
def execute(self, block_height, invoker='', channel_name='', invoker_key=''): """ :param block_height: :param invoker_uri: :param channel_name: :param trade: :param invoker_key: :param gwei: :return: """ super(ChannelEndSettleEvent, self).execute(block_height) # close channel event result = self.contract_event_api.end_close_channel( invoker, channel_name, invoker_key, gwei_coef=self.gwei_coef) # set channel settling if result is not None and 'success' in result.values(): Channel.update_channel(self.channel_name, state=EnumChannelState.SETTLED.name) self.next_stage()
def error_handler(self, block_height, *args, **kwargs): super(ChannelQuickSettleEvent, self).error_handler(block_height, *args, **kwargs) # if running here, it means the channel is still OPENED total_deposit = self.contract_event_api.get_channel_total_balance(self.channel_name) if 0 < total_deposit: Channel.update_channel(self.channel_name, state=EnumChannelState.OPENED.name) sync_channel_info_to_gateway(self.channel_name, 'AddChannel', self.asset_type)
def terminate(self, block_height, *args, asset_type='TNC'): super(ChannelQuickSettleEvent, self).terminate(block_height) # to check the total deposit of the channel total_deposit = self.contract_event_api.get_channel_total_balance(self.channel_name) if 0 >= total_deposit: Channel.update_channel(self.channel_name, state=EnumChannelState.CLOSED.name) APIStatistics.update_statistics(self.wallet_address, state=EnumChannelState.CLOSED.name) console_log.info('Channel {} state is {}'.format(self.channel_name, EnumChannelState.CLOSED.name)) self.next_stage()
def prepare(self, block_height, *args, **kwargs): super(ChannelQuickSettleEvent, self).prepare(block_height, *args, **kwargs) # update the channel OPENING State after trigger the deposit event, wait for OPENED if self.retry is False: Channel.update_channel(self.channel_name, state=EnumChannelState.CLOSING.name) LOG.info('Start to quick-close channel<{}>. State: CLOSING.'.format(self.channel_name)) console_log.info('Channel<{}> is closing'.format(self.channel_name)) # go to next stage self.next_stage()
def execute(self, block_height, channel_name='', **kwargs): """ :param block_height: :param channel_name: :param kwargs: :return: """ super(ChannelSettledEvent, self).execute(block_height) # if monitor this event, close channel directly if channel_name: Channel.update_channel(channel_name, state=EnumChannelState.SETTLED.name)
def terminate(self, block_height, *args, asset_type='TNC'): super(ChannelDepositEvent, self).terminate(block_height, *args) # check the deposit of the contract address total_deposit = self.contract_event_api.get_channel_total_balance(self.channel_name) if total_deposit >= self.deposit + self.partner_deposit: Channel.update_channel(self.channel_name, state=EnumChannelState.OPENED.name) Channel.update_trade(self.channel_name, self.nonce, state=EnumTradeState.confirmed.name) sync_channel_info_to_gateway(self.channel_name, 'AddChannel', asset_type) console_log.info('Channel {} state is {}'.format(self.channel_name, EnumChannelState.OPENED.name)) # to trigger monitor event for closing channel event_monitor_close_channel(self.channel_name) event_monitor_settle(self.channel_name) # to trigger monitor event for unlocking htlc locked payment event_monitor_withdraw(self.channel_name) event_monitor_withdraw_update(self.channel_name) event_monitor_withdraw_settle(self.channel_name) self.next_stage()
def execute(self, block_height, invoker_uri='', channel_name='', invoker_key='', nonce=None): """ :param block_height: :param invoker_uri: :param channel_name: :param trade: :param invoker_key: :param gwei: :return: """ super(ChannelUpdateSettleEvent, self).execute(block_height) # close channel event # ToDo uncomment below codes in future # latest_trade = Channel.latest_confirmed_trade() # if isinstance(nonce, int) and int(nonce) == latest_trade.nonce: # or check balance: # self.next_stage() # return result = Channel.force_release_rsmc( invoker_uri, channel_name, nonce, invoker_key, gwei_coef=self.gwei_coef, trigger=self.contract_event_api.update_close_channel) # set channel settling if result is not None and 'success' in result.values(): Channel.update_channel(self.channel_name, state=EnumChannelState.SETTLED.name) APIStatistics.update_statistics( self.wallet_address, state=EnumChannelState.SETTLED.name) self.next_stage()
def execute(self, block_height, invoker_uri='', channel_name='', nonce=None, invoker_key='', is_debug=False): """ :param block_height: :param invoker_uri: :param channel_name: :param trade: :param invoker_key: :param gwei: :return: """ super(ChannelForceSettleEvent, self).execute(block_height) LOG.debug('parameter: {}, {}, {}, {}'.format(invoker_uri, channel_name, nonce, invoker_key)) LOG.debug('event args: {}, kwargs'.format(self.event_arguments.args, self.event_arguments.kwargs)) # close channel event result = Channel.force_release_rsmc( invoker_uri, channel_name, nonce, invoker_key, gwei_coef=self.gwei_coef, trigger=self.contract_event_api.close_channel, is_debug=is_debug) # set channel settling if result is not None and 'success' in result.values(): Channel.update_channel(self.channel_name, state=EnumChannelState.SETTLED.name) self.next_stage()
def execute(self, block_height, invoker_uri='', channel_name='', hashcode='', rcode='', invoker_key=''): """ :param block_height: :param invoker_uri: :param channel_name: :param hashcode: :param rcode: :param invoker_key: :return: """ super(ChannelPunishHtlcUnlockEvent, self).execute(block_height) # punishment when other want to release the htlc-locked payment result = Channel.force_release_htlc( invoker_uri, channel_name, hashcode, rcode, invoker_key, gwei_coef=self.gwei_coef, trigger=self.contract_event_api.punish_when_htlc_unlock_payment, is_debug=False, is_pubnishment=True, htcl_to_rsmc=self.transfer_htlc_to_rsmc) self.transfer_htlc_to_rsmc = False # set channel settling if result is not None and 'success' in result.values(): Channel.update_channel(self.channel_name, state=EnumChannelState.SETTLED.name) self.next_stage()
def execute(self, block_height, channel_name='', **kwargs): """ :param block_height: :param channel_name: :param kwargs: :return: """ super(ChannelStateManageEvent, self).execute(block_height) # check whether the contract asset try: if channel_name: balance_of_channel = self.contract_event_api.get_channel_total_balance( channel_name) if 0 >= balance_of_channel: Channel.update_channel(channel_name, state=EnumChannelState.SETTLED.name) except Exception as error: LOG.exception( 'Keep the channel current state because of exception: {}'. format(error)) return
def update_balance_for_channel(cls, channel_name, asset_type, payer_address, payee_address, payment, is_hlock_to_rsmc=False, is_htlc_type=False): """ :param channel_name: :param payer_address: :param payee_address: :param asset_type: :param payment: :param is_hlock_to_rsmc: :return: """ channel = Channel(channel_name) try: asset_type = asset_type.upper() channel_balance = channel.balance channel_hlock = channel.hlock # calculate the left balance payer_balance = channel_balance.get(payer_address).get(asset_type) payee_balance = channel_balance.get(payee_address).get(asset_type) if is_hlock_to_rsmc: payer_hlock = channel_hlock.get(payer_address).get(asset_type) payer_hlock = cls.big_number_calculate(payer_hlock, payment, False) if 0 > payer_hlock: raise GoTo( EnumResponseStatus. RESPONSE_TRADE_LOCKED_ASSET_LESS_THAN_PAYMENT, 'Why here? Payment<{}> should less than locked asset'. format(payment)) channel_hlock.update( {payer_address: { asset_type: str(payer_hlock) }}) payee_balance = cls.big_number_calculate( payee_balance, payment) elif is_htlc_type: payer_hlock = channel_hlock.get(payer_address).get(asset_type) payer_hlock = cls.big_number_calculate(payer_hlock, payment) channel_hlock.update( {payer_address: { asset_type: str(payer_hlock) }}) payer_balance = cls.big_number_calculate( payer_balance, payment, False) else: payer_balance = cls.big_number_calculate( payer_balance, payment, False) payee_balance = cls.big_number_calculate( payee_balance, payment) if int(payer_balance) >= 0 and int(payee_balance) >= 0: Channel.update_channel(channel_name, balance={ payer_address: { asset_type: str(payer_balance) }, payee_address: { asset_type: str(payee_balance) } }, hlock=channel_hlock) else: raise GoTo( EnumResponseStatus. RESPONSE_TRADE_NO_ENOUGH_BALANCE_FOR_PAYMENT, 'Payer has not enough balance for this payment<{}>'.format( payment)) except Exception as error: raise GoTo( EnumResponseStatus.RESPONSE_TRADE_BALANCE_UPDATE_FAILED, 'Update channel<{}> balance error. payment<{}>. Exception: {}'. format(channel_name, payment, error))
def handle_resign_body(cls, wallet, channel_name, resign_body): """""" if not resign_body: return None if not (wallet and channel_name): raise GoTo( EnumResponseStatus.RESPONSE_ILLEGAL_INPUT_PARAMETER, 'Void wallet<{}> or Illegal channel name<{}>'.format( wallet, channel_name)) resign_nonce = int(resign_body.get('Nonce')) update_channel_db = {} update_trade_db = {} # get transaction by the resign_nonce resign_trade = Channel.query_trade(channel_name, resign_nonce) asset_type = resign_trade.asset_type channel = Channel(channel_name) self_address, _, _ = uri_parser(wallet.url) peer_address, _, _ = uri_parser(channel.peer_uri(wallet.url)) # Is this wallet sender side of this trade ????? if EnumTradeRole.TRADE_ROLE_PARTNER.name == resign_trade.role: payer_address = peer_address payee_address = self_address payer_balance = resign_trade.peer_balance payee_balance = resign_trade.balance elif EnumTradeRole.TRADE_ROLE_FOUNDER.name == resign_trade.role: payer_address = self_address payee_address = peer_address payer_balance = resign_trade.balance payee_balance = resign_trade.peer_balance else: raise GoTo( EnumResponseStatus.RESPONSE_DATABASE_ERROR_TRADE_ROLE, 'Error trade role<{}> for nonce<{}>'.format( resign_trade.role, resign_nonce)) if EnumTradeType.TRADE_TYPE_HTLC.name == resign_trade.type: rsmc_sign_hashcode, rsmc_sign_rcode = cls.get_default_rcode() elif EnumTradeType.TRADE_TYPE_RSMC.name == resign_trade.type: rsmc_sign_hashcode, rsmc_sign_rcode = resign_trade.hashcode, resign_trade.rcode else: raise GoTo( EnumResponseStatus.RESPONSE_TRADE_RESIGN_NOT_SUPPORTED_TYPE, 'Only support HTLC and RSMC resign. Current transaction type: {}' .format(resign_trade.type)) rsmc_list = [ channel_name, resign_nonce, payer_address, int(payer_balance), payee_address, int(payee_balance), rsmc_sign_hashcode, rsmc_sign_rcode ] # self commitment is None if not resign_trade.commitment: commitment = cls.sign_content(wallet, cls._rsmc_sign_type_list, rsmc_list) update_trade_db.update({'commitment': commitment}) # self lock commitment is none htlc_list = None if EnumTradeType.TRADE_TYPE_HTLC.name == resign_trade.type: htlc_list = [ channel_name, payer_address, payee_address, int(resign_trade.delay_block), int(resign_trade.payment), resign_trade.hashcode ] delay_commitment = cls.sign_content(wallet, cls._htlc_sign_type_list, htlc_list) update_trade_db.update({'delay_commitment': delay_commitment}) # check whether the trade need update or not if resign_trade.state not in [ EnumTradeState.confirmed.name, EnumTradeState.confirmed_onchain.name ]: peer_commitment = resign_body.get('Commitment') peer_delay_commitment = resign_body.get('DelayCommitment') # check peer signature cls.check_signature(wallet, peer_address, cls._rsmc_sign_type_list, rsmc_list, peer_commitment) # update transaction and channel balance update_trade_db.update({'peer_commitment': peer_commitment}) update_channel_db = { 'balance': { payer_address: { asset_type: payer_balance }, payee_address: { asset_type: payee_balance } } } # check the htlc part signature if EnumTradeType.TRADE_TYPE_HTLC.name == resign_trade.type: cls.check_signature(wallet, peer_address, cls._htlc_sign_type_list, htlc_list, peer_delay_commitment) update_trade_db.update( {'peer_delay_commitment': peer_delay_commitment}) update_trade_db.update( {'state': EnumTradeState.confirming.name}) # need update the hlock part if payer_address == self_address: channel = Channel(channel_name) channel_hlock = channel.hlock if channel_hlock and channel_hlock.get(payer_address): payer_hlock = int(resign_trade.payment) + int( channel_hlock.get(payer_address).get(asset_type)) channel_hlock.update( {payer_address: { asset_type: str(payer_hlock) }}) update_channel_db.update({'hlock': channel_hlock}) else: # RSMC type transaction update_trade_db.update( {'state': EnumTradeState.confirmed.name}) # update transaction Channel.update_trade(channel_name, resign_nonce, **update_trade_db) # update Channel balance to new one Channel.update_channel(channel_name, **update_channel_db) # return resign message body return cls.create_resign_message_body(wallet.url, channel_name, resign_nonce, True)