Esempio n. 1
0
def events(general_config, registry_options, contract_name, from_block,
           to_block, event_name):
    """
    Show events associated to NuCypher contracts
    """
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)
    blockchain = BlockchainInterfaceFactory.get_interface(
        provider_uri=registry_options.provider_uri)

    if not contract_name:
        if event_name:
            raise click.BadOptionUsage(
                option_name='--event-name',
                message='--event-name requires --contract-name')
        contract_names = [
            STAKING_ESCROW_CONTRACT_NAME, POLICY_MANAGER_CONTRACT_NAME
        ]
    else:
        contract_names = [contract_name]

    if from_block is None:
        # Sketch of logic for getting the approximate block height of current period start,
        # so by default, this command only shows events of the current period
        last_block = blockchain.client.w3.eth.blockNumber
        staking_agent = ContractAgency.get_agent(StakingEscrowAgent,
                                                 registry=registry)
        current_period = staking_agent.get_current_period()
        current_period_start = datetime_at_period(
            period=current_period,
            seconds_per_period=staking_agent.staking_parameters()[0],
            start_of_period=True)
        seconds_from_midnight = int(
            (maya.now() - current_period_start).total_seconds())
        blocks_from_midnight = seconds_from_midnight // AVERAGE_BLOCK_TIME_IN_SECONDS

        from_block = last_block - blocks_from_midnight

    if to_block is None:
        to_block = 'latest'

    # TODO: additional input validation for block numbers

    emitter.echo(f"Showing events from block {from_block} to {to_block}")
    for contract_name in contract_names:
        title = f" {contract_name} Events ".center(40, "-")
        emitter.echo(f"\n{title}\n", bold=True, color='green')
        agent = ContractAgency.get_agent_by_contract_name(
            contract_name, registry)
        names = agent.events.names if not event_name else [event_name]
        for name in names:
            emitter.echo(f"{name}:", bold=True, color='yellow')
            event_method = agent.events[name]
            for event_record in event_method(from_block=from_block,
                                             to_block=to_block):
                emitter.echo(f"  - {event_record}")
Esempio n. 2
0
def events(general_config, registry_options, contract_name, from_block,
           to_block, event_name):
    """Show events associated to NuCypher contracts."""

    emitter, registry, blockchain = registry_options.setup(
        general_config=general_config)
    if not contract_name:
        if event_name:
            raise click.BadOptionUsage(
                option_name='--event-name',
                message='--event-name requires --contract-name')
        contract_names = [
            STAKING_ESCROW_CONTRACT_NAME, POLICY_MANAGER_CONTRACT_NAME
        ]
    else:
        contract_names = [contract_name]

    if from_block is None:
        # by default, this command only shows events of the current period
        last_block = blockchain.client.block_number
        staking_agent = ContractAgency.get_agent(StakingEscrowAgent,
                                                 registry=registry)
        current_period = staking_agent.get_current_period()
        from_block = estimate_block_number_for_period(
            period=current_period,
            seconds_per_period=staking_agent.staking_parameters()[0],
            latest_block=last_block)
    if to_block is None:
        to_block = 'latest'

    # TODO: additional input validation for block numbers
    emitter.echo(f"Showing events from block {from_block} to {to_block}")
    for contract_name in contract_names:
        title = f" {contract_name} Events ".center(40, "-")
        emitter.echo(f"\n{title}\n", bold=True, color='green')
        agent = ContractAgency.get_agent_by_contract_name(
            contract_name, registry)
        names = agent.events.names if not event_name else [event_name]
        for name in names:
            emitter.echo(f"{name}:", bold=True, color='yellow')
            event_method = agent.events[name]
            for event_record in event_method(from_block=from_block,
                                             to_block=to_block):
                emitter.echo(f"  - {event_record}")
Esempio n. 3
0
def events(general_config, registry_options, contract_name, from_block,
           to_block, event_name, csv, csv_file, event_filters, legacy):
    """Show events associated with NuCypher contracts."""

    if csv or csv_file:
        if csv and csv_file:
            raise click.BadOptionUsage(
                option_name='--event-filter',
                message=click.style(
                    'Pass either --csv or --csv-file, not both.', fg="red"))

        # ensure that event name is specified - different events would have different columns in the csv file
        if csv_file and not all((event_name, contract_name)):
            # TODO consider a single csv that just gets appended to for each event
            #  - each appended event adds their column names first
            #  - single report-type functionality, see #2561
            raise click.BadOptionUsage(
                option_name='--csv-file, --event-name, --contract_name',
                message=click.style(
                    '--event-name and --contract-name must be specified when outputting to '
                    'specific file using --csv-file; alternatively use --csv',
                    fg="red"))
    if not contract_name:
        if event_name:
            raise click.BadOptionUsage(
                option_name='--event-name',
                message=click.style('--event-name requires --contract-name',
                                    fg="red"))
        # FIXME should we force a contract name to be specified?
        # default to PREApplication contract
        contract_names = [PREApplicationAgent.contract_name]
    else:
        contract_names = [contract_name]

    emitter, registry, blockchain = registry_options.setup(
        general_config=general_config)

    if from_block is None:
        # by default, this command only shows events of the current period
        blocks_since_yesterday_kinda = ((60 * 60 * 24) //
                                        AVERAGE_BLOCK_TIME_IN_SECONDS)
        from_block = blockchain.client.block_number - blocks_since_yesterday_kinda
    if to_block is None:
        to_block = 'latest'
    else:
        # validate block range
        if from_block > to_block:
            raise click.BadOptionUsage(
                option_name='--to-block, --from-block',
                message=click.style(
                    f'Invalid block range provided, '
                    f'from-block ({from_block}) > to-block ({to_block})',
                    fg="red"))

    # event argument filters
    argument_filters = None
    if event_filters:
        try:
            argument_filters = parse_event_filters_into_argument_filters(
                event_filters)
        except ValueError as e:
            raise click.BadOptionUsage(
                option_name='--event-filter',
                message=click.style(
                    f'Event filter must be specified as name-value pairs of '
                    f'the form `<name>=<value>` - {str(e)}',
                    fg="red"))

    emitter.echo(f"Retrieving events from block {from_block} to {to_block}")

    contract_version = None
    if legacy and contract_name in LEGACY_CONTRACT_VERSIONS:
        contract_version = LEGACY_CONTRACT_VERSIONS[contract_name]

    for contract_name in contract_names:
        if legacy:
            versioned_contract = blockchain.get_contract_by_name(
                registry=registry,
                contract_name=contract_name,
                contract_version=contract_version,
                proxy_name='Dispatcher',
                use_proxy_address=True)
            agent = EthereumContractAgent(contract=versioned_contract)
            agent.contract_name = contract_name
        else:
            agent = ContractAgency.get_agent_by_contract_name(
                contract_name=contract_name,
                contract_version=contract_version,
                registry=registry)

        if event_name and event_name not in agent.events.names:
            raise click.BadOptionUsage(
                option_name='--event-name, --contract_name',
                message=click.style(
                    f'{contract_name} contract does not have an event named {event_name}',
                    fg="red"))

        title = f" {agent.contract_name} Events ".center(40, "-")
        emitter.echo(f"\n{title}\n", bold=True, color='green')
        names = agent.events.names if not event_name else [event_name]
        for name in names:
            # csv output file - one per (contract_name, event_name) pair
            csv_output_file = csv_file
            if csv or csv_output_file:
                if not csv_output_file:
                    csv_output_file = generate_events_csv_filepath(
                        contract_name=agent.contract_name, event_name=name)

            retrieve_events(
                emitter=emitter,
                agent=agent,
                event_name=name,  # None is fine - just means all events
                from_block=from_block,
                to_block=to_block,
                argument_filters=argument_filters,
                csv_output_file=csv_output_file)
Esempio n. 4
0
def events(general_config, registry_options, contract_name, from_block,
           to_block, event_name, csv, csv_file, event_filters):
    """Show events associated with NuCypher contracts."""

    if csv or csv_file:
        if csv and csv_file:
            raise click.BadOptionUsage(
                option_name='--event-filter',
                message=f'Pass either --csv or --csv-file, not both.')

        # ensure that event name is specified - different events would have different columns in the csv file
        if csv_file and not all((event_name, contract_name)):
            # TODO consider a single csv that just gets appended to for each event
            #  - each appended event adds their column names first
            #  - single report-type functionality, see #2561
            raise click.BadOptionUsage(
                option_name='--csv-file, --event-name, --contract_name',
                message=
                '--event-name and --contract-name must be specified when outputting to '
                'specific file using --csv-file; alternatively use --csv')
    if not contract_name:
        if event_name:
            raise click.BadOptionUsage(
                option_name='--event-name',
                message='--event-name requires --contract-name')
        # FIXME should we force a contract name to be specified?
        contract_names = [
            STAKING_ESCROW_CONTRACT_NAME, POLICY_MANAGER_CONTRACT_NAME
        ]
    else:
        contract_names = [contract_name]

    emitter, registry, blockchain = registry_options.setup(
        general_config=general_config)

    if from_block is None:
        # by default, this command only shows events of the current period
        last_block = blockchain.client.block_number
        staking_agent = ContractAgency.get_agent(StakingEscrowAgent,
                                                 registry=registry)
        current_period = staking_agent.get_current_period()
        from_block = estimate_block_number_for_period(
            period=current_period,
            seconds_per_period=staking_agent.staking_parameters()[1],
            latest_block=last_block)
    if to_block is None:
        to_block = 'latest'
    else:
        # validate block range
        if from_block > to_block:
            raise click.BadOptionUsage(
                option_name='--to-block, --from-block',
                message=f'Invalid block range provided, '
                f'from-block ({from_block}) > to-block ({to_block})')

    # event argument filters
    argument_filters = None
    if event_filters:
        try:
            argument_filters = parse_event_filters_into_argument_filters(
                event_filters)
        except ValueError as e:
            raise click.BadOptionUsage(
                option_name='--event-filter',
                message=f'Event filter must be specified as name-value pairs of '
                f'the form `<name>=<value>` - {str(e)}')

    emitter.echo(f"Retrieving events from block {from_block} to {to_block}")
    for contract_name in contract_names:
        agent = ContractAgency.get_agent_by_contract_name(
            contract_name, registry)
        if event_name and event_name not in agent.events.names:
            raise click.BadOptionUsage(
                option_name='--event-name, --contract_name',
                message=
                f'{contract_name} contract does not have an event named {event_name}'
            )

        title = f" {agent.contract_name} Events ".center(40, "-")
        emitter.echo(f"\n{title}\n", bold=True, color='green')
        names = agent.events.names if not event_name else [event_name]
        for name in names:
            # csv output file - one per (contract_name, event_name) pair
            csv_output_file = csv_file
            if csv or csv_output_file:
                if not csv_output_file:
                    csv_output_file = generate_events_csv_filepath(
                        contract_name=agent.contract_name, event_name=name)

            retrieve_events(
                emitter=emitter,
                agent=agent,
                event_name=name,  # None is fine - just means all events
                from_block=from_block,
                to_block=to_block,
                argument_filters=argument_filters,
                csv_output_file=csv_output_file)