def get_actions(): response.content_type = 'application/json' actions = get_actions() if actions is not None: return actions else: return {'error': 'Unable to retrieve action_ids'}
def configure(self, **config): self.created = datetime.fromtimestamp( config['created']) if 'created' in config else datetime.now() if 'trigger_type' in config and valid_trigger_type( config['trigger_type']): self.trigger_type = config['trigger_type'] if 'script' in config and valid_script(config['script']): self.script = config['script'] if 'data' in config and isinstance(config['data'], dict): self.data = config['data'] if 'multi' in config and config['multi'] in [True, False]: self.multi = config['multi'] if 'status' in config and valid_status(config['status']): self.status = config['status'] if 'reset' in config and config['reset'] is True: self.triggered = 0 self.status = 'Active' elif 'triggered' in config and valid_amount(config['triggered']): self.triggered = config['triggered'] if 'description' in config and valid_description( config['description']): self.description = config['description'] if 'creator_name' in config and valid_creator(config['creator_name']): self.creator_name = config['creator_name'] if 'creator_email' in config and valid_email(config['creator_email']): self.creator_email = config['creator_email'] if 'youtube' in config and valid_youtube_id(config['youtube']): self.youtube = config['youtube'] if 'visibility' in config and valid_visibility(config['visibility']): self.visibility = config['visibility'] if 'actions' in config and valid_actions(config['actions']): self.actions = config['actions'] configured_actions = get_actions() for action_id in self.actions: if action_id not in configured_actions: LOG.warning('Trigger %s contains unknown action: %s' % (self.id, action_id)) if 'self_destruct' in config and valid_timestamp( config['self_destruct']): self.self_destruct = config['self_destruct'] if 'destruct_actions' in config and config['destruct_actions'] in [ True, False ]: self.destruct_actions = config['destruct_actions']
def run(self): LOG.info('Running Spellbook Script: %s' % os.path.splitext(os.path.basename(__file__))[0]) trigger = get_trigger(trigger_id=self.trigger_id) LOG.info('Lottery winner is determined at block height %s' % trigger.block_height) # Double check the block at the specified height has been mined already (even though the trigger should not activate before the specified blockheight + number of confirmations) block_data = block_by_height(height=trigger.block_height) if 'block' in block_data: block_hash = block_data['block']['hash'] else: LOG.error( 'Unable to get the block hash of block %s to determine the winner of the lottery' % trigger.block_height) return LOG.info('Picking the winner with block %s (%s)' % (trigger.block_height, block_hash)) action_id = 'Lottery-payout' if action_id not in get_actions(): LOG.error('Can not modify action %s: action not found' % action_id) return action = get_action(action_id=action_id) lottery_address = get_address_from_wallet(account=action.bip44_account, index=action.bip44_index) LOG.info('Getting SIL from lottery address %s' % lottery_address) random_address_data = random_address_from_sil( address=lottery_address, sil_block_height=trigger.block_height, rng_block_height=trigger.block_height) LOG.info('random_address_data: %s' % random_address_data) if 'chosen_address' not in random_address_data: LOG.error('Failed to get winning address') return winning_address = random_address_data['chosen_address'] LOG.info('Winning address: %s' % winning_address) LOG.info('Distribution: %s' % random_address_data['distribution']) LOG.info('Configuring action Lottery-payout') action.receiving_address = winning_address # Also set the amount to send in the payout, just in case someone sends a transaction to the lottery after the winner has been picked # Todo this (how to get the balance at a specific time?) action.save() LOG.info('Action Lottery-payout is configured') self.attach_action('Lottery-payout')
def activate(self): """ Activate all actions on this trigger, if all actions are successful the 'triggered' status will be True If an action fails, the remaining actions will not be executed and the 'triggered' status remains False so another attempt can be made the next time the trigger is checked Important: actions of type SendTransaction should always be the last action in the list and there should only be maximum 1 SendTransaction :return: """ LOG.info('Activating trigger %s' % self.id) script = self.load_script() if script is not None: script.run() if len(script.new_actions) >= 1: LOG.info('Adding actions %s to trigger %s' % (script.new_actions, self.id)) self.actions.extend(script.new_actions) LOG.info('Trigger will run actions: %s' % self.actions) configured_actions = get_actions() for action_id in self.actions: if action_id not in configured_actions: LOG.error('Unknown action id: %s' % action_id) return for i, action_id in enumerate(self.actions): LOG.info('Running action %s: %s' % (i + 1, action_id)) action = get_action(action_id) success = action.run() if not success: self.triggered += 1 self.status = 'Failed' if self.multi is False else 'Active' self.save() return # All actions were successful self.triggered += 1 self.status = 'Succeeded' if self.multi is False else 'Active' self.save() if script is not None: script.cleanup() return script.http_response