Esempio n. 1
0
def _select_capabilities(
        remote_capabilities: Capabilities,
        local_capabilities: Capabilities) -> Iterable[Capability]:
    """
    Select the appropriate shared capabilities between local and remote.

    https://github.com/ethereum/devp2p/blob/master/rlpx.md#capability-messaging
    """
    # Determine the remote capabilities that intersect with our own.
    matching_capabilities = tuple(
        sorted(
            set(local_capabilities).intersection(remote_capabilities),
            key=operator.itemgetter(0),
        ))
    # generate a dictionary of each capability grouped by name and sorted by
    # version in descending order.
    sort_by_version = functools.partial(sorted,
                                        key=operator.itemgetter(1),
                                        reverse=True)
    capabilities_by_name = valmap(
        tuple,
        valmap(
            sort_by_version,
            groupby(operator.itemgetter(0), matching_capabilities),
        ),
    )

    # now we loop over the names that have a matching capability and return the
    # *highest* version one.
    for name in sorted(capabilities_by_name.keys()):
        yield capabilities_by_name[name][0]
def _prepare_selector_collision_msg(duplicates):
    dup_sel = valmap(apply_formatter_to_array(abi_to_signature), duplicates)
    joined_funcs = valmap(lambda funcs: ', '.join(funcs), dup_sel)
    func_sel_msg_list = [
        funcs + ' have selector ' + sel for sel, funcs in joined_funcs.items()
    ]
    return ' and\n'.join(func_sel_msg_list)
Esempio n. 3
0
    def _build_attestation_index(
            self, state: BeaconState,
            attestation_pool: AttestationPool) -> AttestationIndex:
        """
        Assembles a dictionary of latest attestations keyed by validator index.
        Any attestation made by a validator in the ``attestation_pool`` that occur after the
        last known attestation according to the state take precedence.

        We start by building a 'pre-index' from all known attestations which map validator
        indices to a pair of slot and attestation data. A final index is built from all
        pre-indices by keeping the entry with the highest slot across the set of all
        duplicates in the pre-indices keyed by validator index.
        """
        previous_epoch_index = self._mk_pre_index_from_attestations(
            state, state.previous_epoch_attestations)

        current_epoch_index = self._mk_pre_index_from_attestations(
            state, state.current_epoch_attestations)

        pool_index = self._mk_pre_index_from_attestations(
            state, tuple(attestation for _, attestation in attestation_pool))

        index_by_latest_slot = merge_with(
            _take_latest_attestation_by_slot,
            previous_epoch_index,
            current_epoch_index,
            pool_index,
        )
        # convert the index to a mapping of ValidatorIndex -> (latest) Attestation
        return valmap(
            second,
            index_by_latest_slot,
        )
def find_matching_fn_abi(abi,
                         abi_codec,
                         fn_identifier=None,
                         args=None,
                         kwargs=None):
    args = args or tuple()
    kwargs = kwargs or dict()
    num_arguments = len(args) + len(kwargs)

    if fn_identifier is FallbackFn:
        return get_fallback_func_abi(abi)

    if not is_text(fn_identifier):
        raise TypeError("Unsupported function identifier")

    name_filter = functools.partial(filter_by_name, fn_identifier)
    arg_count_filter = functools.partial(filter_by_argument_count,
                                         num_arguments)
    encoding_filter = functools.partial(filter_by_encodability, abi_codec,
                                        args, kwargs)

    function_candidates = pipe(abi, name_filter, arg_count_filter,
                               encoding_filter)

    if len(function_candidates) == 1:
        return function_candidates[0]
    else:
        matching_identifiers = name_filter(abi)
        matching_function_signatures = [
            abi_to_signature(func) for func in matching_identifiers
        ]

        arg_count_matches = len(arg_count_filter(matching_identifiers))
        encoding_matches = len(encoding_filter(matching_identifiers))

        if arg_count_matches == 0:
            diagnosis = "\nFunction invocation failed due to improper number of arguments."
        elif encoding_matches == 0:
            diagnosis = "\nFunction invocation failed due to no matching argument types."
        elif encoding_matches > 1:
            diagnosis = (
                "\nAmbiguous argument encoding. "
                "Provided arguments can be encoded to multiple functions matching this call."
            )

        message = (
            "\nCould not identify the intended function with name `{name}`, "
            "positional argument(s) of type `{arg_types}` and "
            "keyword argument(s) of type `{kwarg_types}`."
            "\nFound {num_candidates} function(s) with the name `{name}`: {candidates}"
            "{diagnosis}").format(
                name=fn_identifier,
                arg_types=tuple(map(type, args)),
                kwarg_types=valmap(type, kwargs),
                num_candidates=len(matching_identifiers),
                candidates=matching_function_signatures,
                diagnosis=diagnosis,
            )

        raise ValidationError(message)
Esempio n. 5
0
def write_config_json(config, datadir):
    bytes_to_hex = apply_formatter_if(is_bytes, to_hex)
    config_json_dict = valmap(bytes_to_hex, config)

    config_path = os.path.join(datadir, 'config.json')
    with open(config_path, 'w') as config_file:
        config_file.write(json.dumps(config_json_dict))
        config_file.write('\n')
Esempio n. 6
0
    def _serialize(self):
        """
        Persist the expensive data to the backing cache.

        NOTE: we currently use an inexpensive determinstic computation
        for the private keys so all we need to persist are the expensive
        pubkeys and the index data (which allows derivation of the privkey).
        """
        return {
            "pubkeys_by_index":
            toolz.valmap(_serialize_bls_pubkeys, self.all_pubkeys_by_index)
        }
Esempio n. 7
0
def _mk_raw_params(**kwargs):
    return {
        'genesis': merge(PARAMS_DEFAULTS, valmap(hexstr_if_str(to_hex), kwargs)),
    }
Esempio n. 8
0
def _load_parts(parts: Iterable[Path]) -> Dict[str, TestPart]:
    parts_by_name = toolz.groupby(_group_paths_by_name, parts)
    return toolz.valmap(_mk_test_part, parts_by_name)