Exemple #1
0
    async def _get_block_bodies(
        self,
        peer: ETHPeer,
        headers: Tuple[BlockHeader, ...],
    ) -> Tuple[Tuple[BlockBodyBundle, ...], Tuple[BlockHeader, ...]]:
        """
        Request and return block bodies, pairing them with the associated headers.
        Store the bodies for later use, during block import (or persist).

        Note the difference from _request_block_bodies, which only issues the request,
        and doesn't pair the results with the associated block headers that were successfully
        delivered.
        """
        block_body_bundles = await self.wait(
            self._request_block_bodies(peer, headers))

        if len(block_body_bundles) == 0:
            self.logger.debug(
                "Got block bodies for 0/%d headers from %s, from %r..%r",
                len(headers),
                peer,
                headers[0],
                headers[-1],
            )
            return tuple(), tuple()

        bodies_by_root = {
            (transaction_root, uncles_hash): block_body
            for block_body, (transaction_root,
                             _), uncles_hash in block_body_bundles
        }

        header_roots = {
            header: (header.transaction_root, header.uncles_hash)
            for header in headers
        }

        completed_header_roots = valfilter(lambda root: root in bodies_by_root,
                                           header_roots)

        completed_headers = tuple(completed_header_roots.keys())

        # store bodies for later usage, during block import
        pending_bodies = {
            header: bodies_by_root[root]
            for header, root in completed_header_roots.items()
        }
        self._pending_bodies = merge(self._pending_bodies, pending_bodies)

        self.logger.debug(
            "Got block bodies for %d/%d headers from %s, from %r..%r",
            len(completed_header_roots),
            len(headers),
            peer,
            headers[0],
            headers[-1],
        )

        return block_body_bundles, completed_headers
Exemple #2
0
def _mk_attestations_for_epoch_by_count(number_of_committee_samples, epoch,
                                        block_producer, state, config):
    results = {}
    for _ in range(number_of_committee_samples):
        sample = _mk_attestation_inputs_in_epoch(epoch, block_producer, state,
                                                 config)
        results = merge(results, sample)
    return results
Exemple #3
0
 def _mk_pre_index_from_attestations(
         self, state: BeaconState,
         attestations: Sequence[AttestationLike]) -> PreIndex:
     """
     A 'pre-index' is a Dict[ValidatorIndex, Tuple[Slot, AttestationData]].
     """
     return merge(
         *mapcat(self._mk_pre_index_from_attestation(state), attestations))
Exemple #4
0
 def modifyTransaction(
     self, transaction_hash: _Hash32, **transaction_params: Any
 ) -> HexBytes:
     assert_valid_transaction_params(cast(TxParams, transaction_params))
     current_transaction = get_required_transaction(self.web3, transaction_hash)
     current_transaction_params = extract_valid_transaction_params(current_transaction)
     new_transaction = merge(current_transaction_params, transaction_params)
     return replace_transaction(self.web3, current_transaction, new_transaction)
 def modifyTransaction(self, transaction_hash, **transaction_params):
     assert_valid_transaction_params(transaction_params)
     current_transaction = get_required_transaction(self.web3,
                                                    transaction_hash)
     current_transaction_params = extract_valid_transaction_params(
         current_transaction)
     new_transaction = merge(current_transaction_params, transaction_params)
     return replace_transaction(self.web3, current_transaction,
                                new_transaction)
 def get_subprocess_kwargs(self) -> SubprocessKwargs:
     # This is needed so that pytest can capture the subproc's output. Otherwise it will crash
     # with a "io.UnsupportedOperation: redirected stdin is pseudofile, has no fileno()" error.
     return merge(
         super().get_subprocess_kwargs(), {
             'stdin': subprocess.PIPE,
             'stdout': subprocess.PIPE,
             'stderr': subprocess.PIPE,
         })
Exemple #7
0
def validate_logging(logging_dict: Dict) -> Dict:
    """validate the logging dictionary

    We don't do much here, but instead rely on the main function to
    catch errors from logging.config.dictConfig
    """
    if not isinstance(logging_dict, dict):
        raise ValueError("logging must be a dictionary")
    return merge({"version": 1, "incremental": True}, logging_dict)
Exemple #8
0
def _expect(post_state: Dict[str, Any], networks: Any,
            transaction: TransactionDict, filler: Dict[str,
                                                       Any]) -> Dict[str, Any]:

    test_name = get_test_name(filler)
    test = filler[test_name]
    test_update: Dict[str, Dict[Any, Any]] = {test_name: {}}

    pre_state = test.get("pre", {})
    post_state = normalize_state(post_state or {})
    defaults = {
        address: {
            "balance": 0,
            "nonce": 0,
            "code": b"",
            "storage": {},
        }
        for address in post_state
    }
    result = deep_merge(defaults, pre_state, normalize_state(post_state))
    new_expect = {"result": result}

    if transaction is not None:
        transaction = normalize_transaction(
            merge(get_default_transaction(networks), transaction))
        if "transaction" not in test:
            transaction_group = apply_formatters_to_dict(
                {
                    "data": wrap_in_list,
                    "gasLimit": wrap_in_list,
                    "value": wrap_in_list,
                }, transaction)
            indexes = {
                index_key: 0
                for transaction_key, index_key in [
                    ("gasLimit", "gas"),
                    ("value", "value"),
                    ("data", "data"),
                ] if transaction_key in transaction_group
            }
        else:
            transaction_group, indexes = add_transaction_to_group(
                test["transaction"], transaction)
        new_expect = assoc(new_expect, "indexes", indexes)
        test_update = assoc_in(test_update, [test_name, "transaction"],
                               transaction_group)

    if networks is not None:
        networks = normalize_networks(networks)
        new_expect = assoc(new_expect, "networks", networks)

    existing_expects = test.get("expect", [])
    expect = existing_expects + [new_expect]
    test_update = assoc_in(test_update, [test_name, "expect"], expect)

    return deep_merge(filler, test_update)
 def formatter_middleware(make_request, w3):
     formatters = merge(
         {
             'request_formatters': {},
             'result_formatters': {},
             'error_formatters': {},
         },
         web3_formatters_builder(w3),
     )
     return apply_formatters(make_request=make_request, **formatters)
def generate_go_ethereum_fixture(destination_dir):
    with contextlib.ExitStack() as stack:
        datadir = stack.enter_context(tempdir())

        keystore_dir = os.path.join(datadir, 'keystore')
        ensure_path_exists(keystore_dir)
        keyfile_path = os.path.join(keystore_dir, KEYFILE_FILENAME)
        with open(keyfile_path, 'w') as keyfile:
            keyfile.write(KEYFILE_DATA)
        genesis_file_path = os.path.join(datadir, 'genesis.json')
        with open(genesis_file_path, 'w') as genesis_file:
            genesis_file.write(json.dumps(GENESIS_DATA))

        geth_ipc_path_dir = stack.enter_context(tempdir())
        geth_ipc_path = os.path.join(geth_ipc_path_dir, 'geth.ipc')

        geth_port = get_open_port()
        geth_binary = get_geth_binary()

        with get_geth_process(
                geth_binary=geth_binary,
                datadir=datadir,
                genesis_file_path=genesis_file_path,
                geth_ipc_path=geth_ipc_path,
                geth_port=geth_port):

            wait_for_socket(geth_ipc_path)
            web3 = Web3(Web3.IPCProvider(geth_ipc_path))
            chain_data = setup_chain_state(web3)
            # close geth by exiting context
            # must be closed before copying data dir
            verify_chain_state(web3, chain_data)

        # verify that chain state is still valid after closing
        # and re-opening geth
        with get_geth_process(
                geth_binary=geth_binary,
                datadir=datadir,
                genesis_file_path=genesis_file_path,
                geth_ipc_path=geth_ipc_path,
                geth_port=geth_port):

            wait_for_socket(geth_ipc_path)
            web3 = Web3(Web3.IPCProvider(geth_ipc_path))
            verify_chain_state(web3, chain_data)

        static_data = {
            'raw_txn_account': RAW_TXN_ACCOUNT,
            'keyfile_pw': KEYFILE_PW,
        }
        config = merge(chain_data, static_data)
        pprint.pprint(config)
        write_config_json(config, datadir)

        shutil.make_archive(destination_dir, 'zip', datadir)
Exemple #11
0
 def formatter_middleware(
         make_request: Callable[[RPCEndpoint, Any], Any],
         w3: "Web3") -> Callable[[RPCEndpoint, Any], RPCResponse]:
     formatters = merge(
         {
             "request_formatters": {},
             "result_formatters": {},
             "error_formatters": {},
         },
         web3_formatters_builder(w3),
     )
     return apply_formatters(make_request=make_request, **formatters)
def merge_genesis_overrides(defaults, overrides):
    allowed_fields = set(defaults.keys())
    override_fields = set(overrides.keys())
    unexpected_fields = tuple(
        sorted(override_fields.difference(allowed_fields)))

    if unexpected_fields:
        err = "The following invalid fields were supplied to override default genesis values: {0}."
        raise ValueError(err.format(unexpected_fields))

    merged_params = merge(defaults, overrides)
    return merged_params
Exemple #13
0
def load_config(path: str) -> Dict[str, Any]:
    if path is None:
        user_config = {}
    else:
        user_config = toml.load(path)

    environment_config = load_config_from_environment()

    config = merge(OPTIONAL_CONFIG_ENTRIES_WITH_DEFAULTS, user_config,
                   environment_config)

    return validate_config(config)
Exemple #14
0
        def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
            formatters = merge(
                FORMATTER_DEFAULTS,
                web3_formatters_builder(w3, method),
            )
            request_formatters = formatters.pop('request_formatters')

            if method in request_formatters:
                formatter = request_formatters[method]
                params = formatter(params)
            response = make_request(method, params)

            return _apply_response_formatters(method=method, response=response, **formatters)
Exemple #15
0
 def commit_changeset(self, changeset_id: uuid.UUID) -> Dict[bytes, bytes]:
     """
     Collapses all changes for the given changeset into the previous
     changesets if it exists.
     """
     changeset_data = self.pop_changeset(changeset_id)
     if not self.is_empty():
         # we only have to merge the changes into the latest changeset if
         # there is one.
         self.latest = merge(
             self.latest,
             changeset_data,
         )
     return changeset_data
Exemple #16
0
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": SERENITY_CONFIG.GENESIS_SLOT,
        "previous_block_root": ZERO_HASH32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "signature": EMPTY_SIGNATURE,
        "body": BeaconBlockBody.create_empty_body()
    }

    if parent is not None:
        kwargs["previous_block_root"] = parent.signing_root
        kwargs["slot"] = parent.slot + 1

    return BeaconBlock(**merge(defaults, kwargs))
Exemple #17
0
def normalize_unsigned_transaction(transaction: TransactionDict,
                                   indexes: Dict[str, Any]) -> TransactionDict:

    normalized = normalize_transaction_group(transaction)
    return merge(normalized, {
        # Dynamic key access not yet allowed with TypedDict
        # https://github.com/python/mypy/issues/5359
        transaction_key: normalized[transaction_key][indexes[index_key]]  # type: ignore
        for transaction_key, index_key in [
            ("gasLimit", "gas"),
            ("value", "value"),
            ("data", "data"),
        ]
        if index_key in indexes
    })
Exemple #18
0
def execution(execution: Dict[str, Any], filler: Dict[str,
                                                      Any]) -> Dict[str, Any]:
    """
    For VM tests, specify the code that is being run as well as the current state of
    the EVM. State tests don't support this object. The parameter is a dictionary specifying some
    or all of the following keys:

    +--------------------+------------------------------------------------------------+
    |  key               | description                                                |
    +====================+============================================================+
    | ``"address"``      | the address of the account executing the code              |
    +--------------------+------------------------------------------------------------+
    | ``"caller"``       | the caller address                                         |
    +--------------------+------------------------------------------------------------+
    | ``"origin"``       | the origin address (defaulting to the caller address)      |
    +--------------------+------------------------------------------------------------+
    | ``"value"``        | the value of the call                                      |
    +--------------------+------------------------------------------------------------+
    | ``"data"``         | the data passed with the call                              |
    +--------------------+------------------------------------------------------------+
    | ``"gasPrice"``     | the gas price of the call                                  |
    +--------------------+------------------------------------------------------------+
    | ``"gas"``          | the amount of gas allocated for the call                   |
    +--------------------+------------------------------------------------------------+
    | ``"code"``         | the bytecode to execute                                    |
    +--------------------+------------------------------------------------------------+
    | ``"vyperLLLCode"`` | the code in Vyper LLL (compiled to bytecode automatically) |
    +--------------------+------------------------------------------------------------+
    """
    execution = normalize_execution(execution or {})

    # user caller as origin if not explicitly given
    if "caller" in execution and "origin" not in execution:
        execution = assoc(execution, "origin", execution["caller"])

    if "vyperLLLCode" in execution:
        code = compile_vyper_lll(execution["vyperLLLCode"])
        if "code" in execution:
            if code != execution["code"]:
                raise ValueError("Compiled Vyper LLL code does not match")
        execution = assoc(execution, "code", code)

    execution = merge(DEFAULT_EXECUTION, execution)

    test_name = get_test_name(filler)
    return deep_merge(filler, {test_name: {
        "exec": execution,
    }})
Exemple #19
0
def fill_transaction_defaults(web3, transaction):
    """
    if web3 is None, fill as much as possible while offline
    """
    defaults = {}
    for key, default_getter in TRANSACTION_DEFAULTS.items():
        if key not in transaction:
            if callable(default_getter):
                if web3 is not None:
                    default_val = default_getter(web3, transaction)
                else:
                    raise ValueError("You must specify %s in the transaction" % key)
            else:
                default_val = default_getter
            defaults[key] = default_val
    return merge(defaults, transaction)
Exemple #20
0
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": 0,
        "parent_root": ZERO_HASH32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "randao_reveal": ZERO_HASH32,
        "candidate_pow_receipt_root": ZERO_HASH32,
        "signature": (0, 0),
        "body": empty_body()
    }

    if parent is not None:
        kwargs["parent_root"] = parent.root
        kwargs["slot"] = parent.slot + 1

    return BeaconBlock(**merge(defaults, kwargs))
Exemple #21
0
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": 0,
        "parent_root": ZERO_HASH32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "randao_reveal": EMPTY_SIGNATURE,
        "eth1_data": Eth1Data.create_empty_data(),
        "signature": EMPTY_SIGNATURE,
        "body": BeaconBlockBody.create_empty_body()
    }

    if parent is not None:
        kwargs["parent_root"] = parent.root
        kwargs["slot"] = parent.slot + 1

    return BeaconBlock(**merge(defaults, kwargs))
Exemple #22
0
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": 0,
        "randao_reveal": ZERO_HASH32,
        "candidate_pow_receipt_root": ZERO_HASH32,
        "ancestor_hashes": [ZERO_HASH32] * 32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "attestations": [],
        "specials": [],
        "proposer_signature": None,
    }

    if parent is not None:
        kwargs["ancestor_hashes"] = [parent.hash] + [ZERO_HASH32] * 31
        kwargs["slot"] = parent.slot + 1

    return BaseBeaconBlock(**merge(defaults, kwargs))
Exemple #23
0
def buildBuyTicketTx(transaction, defaultChainId):
    defaults = {}
    alreadygot = {}
    for key, default_val in BUYTICKET_DEFAULTS.items():
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_BUYTICKET_PARAMS:
            alreadygot[key] = transaction[key]

    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_buyticket_formatter(transaction_merged)

    assert_check_buyticket_params(transaction_new)

    return transaction_new
Exemple #24
0
def buildTakeSwapTx(transaction, defaultChainId):
    defaults = {}
    alreadygot = {}
    for key, default_val in TAKESWAP_DEFAULTS.items():
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_TAKESWAP_PARAMS:
            alreadygot[key] = transaction[key]

    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_takeswap_formatter(transaction_merged)

    assert_check_takeswap_params(transaction_new)

    return transaction_new
Exemple #25
0
def buildGenAssetTx(transaction, defaultChainId):
    defaults = {}
    alreadygot = {}
    for key, default_val in GENASSET_DEFAULTS.items():
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_GENASSETTX_PARAMS:
            alreadygot[key] = transaction[key]

    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_assetcreate_formatter(transaction_merged)

    assert_check_gen_asset_params(transaction_new)

    return transaction_new
Exemple #26
0
def buildTimeLockToAssetTx(transaction, defaultChainId):
    defaults = {}
    alreadygot = {}
    for key, default_val in TLTOASSET_DEFAULTS.items():
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_TLTOASSET_PARAMS:
            alreadygot[key] = transaction[key]
            
    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_tltoasset_formatter(transaction_merged)
    
    assert_check_tltoasset_params(transaction_new)
    
    return transaction_new
Exemple #27
0
def buildSendToTimeLockTx(transaction, defaultChainId):
    defaults = {}
    alreadygot = {}
    for key, default_val in SENDTOTL_DEFAULTS.items():
        if key not in transaction:
            defaults[key] = default_val
    for key, val in transaction.items():
        if key in VALID_SENDTOTL_PARAMS:
            alreadygot[key] = transaction[key]
            
    transaction_merged = merge(defaults, alreadygot)
    transaction_merged['chainId'] = defaultChainId
    transaction_new = unsigned_sendtotl_formatter(transaction_merged)
    
    assert_check_sendtotl_params(transaction_new)
    
    return transaction_new
def test_signed_transaction(w3, fund_account, transaction, expected,
                            key_object, from_):
    w3.middleware_onion.add(construct_sign_and_send_raw_middleware(key_object))

    # Drop any falsy addresses
    to_from = valfilter(bool, {'to': w3.eth.accounts[0], 'from': from_})

    _transaction = merge(transaction, to_from)

    if isinstance(expected, type) and issubclass(expected, Exception):
        with pytest.raises(expected):
            w3.eth.send_transaction(_transaction)
    else:
        start_balance = w3.eth.get_balance(
            _transaction.get('from', w3.eth.accounts[0]))
        w3.eth.send_transaction(_transaction)
        assert w3.eth.get_balance(
            _transaction.get('from')) <= start_balance + expected
Exemple #29
0
    def set_text(
        self,
        name: str,
        key: str,
        value: str,
        transact: "TxParams" = None
    ) -> HexBytes:
        """
        Set the value of a text record of an ENS name.

        :param str name: ENS name
        :param str key: Name of the attribute to set
        :param str value: Value to set the attribute to
        :param dict transact: The transaction configuration, like in
            :meth:`~web3.eth.Eth.send_transaction`
        :return: Transaction hash
        :rtype: HexBytes
        :raises UnsupportedFunction: If the resolver does not support the "0x59d1d43c" interface id
        :raises ResolverNotFound: If no resolver is found for the provided name
        """
        if not transact:
            transact = {}

        owner = self.owner(name)
        node = raw_name_to_hash(name)
        normal_name = normalize_name(name)

        transaction_dict = merge({'from': owner}, transact)

        r = self.resolver(normal_name)
        if r:
            if _resolver_supports_interface(r, GET_TEXT_INTERFACE_ID):
                return r.functions.setText(node, key, value).transact(transaction_dict)
            else:
                raise UnsupportedFunction(
                    f"Resolver for name `{name}` does not support `text` function"
                )
        else:
            raise ResolverNotFound(
                f"No resolver found for name `{name}`. It is likely the name contains an "
                "unsupported top level domain (tld)."
            )
Exemple #30
0
    def __init__(
        self,
        private_key: keys.PrivateKey,
        enr_db: ENRDatabaseAPI,
        kv_pairs: Optional[Mapping[bytes, bytes]] = None,
        identity_scheme_registry: IdentitySchemeRegistryAPI = default_identity_scheme_registry,  # noqa: E501
    ) -> None:
        self._identity_scheme_registry = identity_scheme_registry
        self._private_key = private_key
        self._enr_db = enr_db

        if kv_pairs is None:
            kv_pairs = {}

        if b"id" in kv_pairs:
            identity_kv_pairs = {}
        else:
            identity_kv_pairs = {
                b"id": b"v4",
                b"secp256k1": self._private_key.public_key.to_compressed_bytes(),
            }

        minimal_enr = UnsignedENR(
            sequence_number=1,
            kv_pairs=merge(identity_kv_pairs, kv_pairs),
            identity_scheme_registry=self._identity_scheme_registry,
        ).to_signed_enr(self._private_key.to_bytes())
        self._node_id = minimal_enr.node_id

        try:
            base_enr = self._enr_db.get_enr(minimal_enr.node_id)
        except KeyError:
            self.logger.info(
                "ENR created: seq=%d  enr=%r",
                minimal_enr.sequence_number,
                minimal_enr,
            )
            self._enr = minimal_enr
            self._enr_db.set_enr(self._enr)
        else:
            self._enr = base_enr
            self.update(*tuple(kv_pairs.items()))