Esempio n. 1
0
def configure_homestead_header(vm, **header_params):
    validate_header_params_for_configuration(header_params)

    with vm.block.header.build_changeset(**header_params) as changeset:
        if 'timestamp' in header_params and changeset.block_number > 0:
            parent_header = get_parent_header(changeset.build_rlp(),
                                              vm.chaindb)
            changeset.difficulty = compute_homestead_difficulty(
                parent_header,
                header_params['timestamp'],
            )

        # In geth the modification of the state in the DAO fork block is performed
        # before any transactions are applied, so doing it here is the closest we
        # get to that. Another alternative would be to do it in Block.mine(), but
        # there we'd need to manually instantiate the State and update
        # header.state_root after we're done.
        if vm.support_dao_fork and changeset.block_number == vm.dao_fork_block_number:
            state = vm.state
            with state.mutable_state_db() as state_db:
                for account in dao_drain_list:
                    account = decode_hex(account)
                    balance = state_db.get_balance(account)
                    state_db.delta_balance(dao_refund_contract, balance)
                    state_db.set_balance(account, 0)

            # Update state_root manually
            changeset.state_root = state.state_root

        header = changeset.commit()
    return header
Esempio n. 2
0
def configure_homestead_header(vm, **header_params):
    validate_header_params_for_configuration(header_params)

    for field_name, value in header_params.items():
        setattr(vm.block.header, field_name, value)

    if 'timestamp' in header_params and vm.block.header.block_number > 0:
        parent_header = get_parent_header(vm.block.header, vm.chaindb)
        vm.block.header.difficulty = compute_homestead_difficulty(
            parent_header,
            header_params['timestamp'],
        )

    # In geth the modification of the state in the DAO fork block is performed
    # before any transactions are applied, so doing it here is the closest we
    # get to that. Another alternative would be to do it in Block.mine(), but
    # there we'd need to manually instantiate the State and update
    # header.state_root after we're done.
    if vm.support_dao_fork and vm.block.header.block_number == vm.dao_fork_block_number:
        vm_state = vm.state
        with vm_state.state_db() as state_db:
            for account in dao_drain_list:
                account = decode_hex(account)
                balance = state_db.get_balance(account)
                state_db.delta_balance(dao_refund_contract, balance)
                state_db.set_balance(account, 0)

        # Update state_root manually
        vm.block.header.state_root = vm_state.state_root

    return vm.block.header
Esempio n. 3
0
def configure_homestead_header(vm, **header_params):
    validate_header_params_for_configuration(header_params)

    for field_name, value in header_params.items():
        setattr(vm.block.header, field_name, value)

    if 'timestamp' in header_params and vm.block.header.block_number > 0:
        parent_header = get_parent_header(vm.block.header, vm.chaindb)
        vm.block.header.difficulty = compute_homestead_difficulty(
            parent_header,
            header_params['timestamp'],
        )

    # In geth the modification of the state in the DAO fork block is performed
    # before any transactions are applied, so doing it here is the closest we
    # get to that. Another alternative would be to do it in Block.mine(), but
    # there we'd need to manually instantiate the State and update
    # header.state_root after we're done.
    if vm.support_dao_fork and vm.block.header.block_number == vm.dao_fork_block_number:
        with vm.state.state_db() as state_db:
            for account in dao_drain_list:
                account = decode_hex(account)
                balance = state_db.get_balance(account)
                state_db.delta_balance(dao_refund_contract, balance)
                state_db.set_balance(account, 0)

    return vm.block.header
Esempio n. 4
0
    def validate_block(self, block):
        if not block.is_genesis:
            parent_header = get_parent_header(block.header, self.chaindb)

            validate_gas_limit(block.header.gas_limit, parent_header.gas_limit)
            validate_length_lte(block.header.extra_data,
                                32,
                                title="BlockHeader.extra_data")

            # timestamp
            if block.header.timestamp < parent_header.timestamp:
                raise ValidationError(
                    "`timestamp` is before the parent block's timestamp.\n"
                    "- block  : {0}\n"
                    "- parent : {1}. ".format(
                        block.header.timestamp,
                        parent_header.timestamp,
                    ))
            elif block.header.timestamp == parent_header.timestamp:
                raise ValidationError(
                    "`timestamp` is equal to the parent block's timestamp\n"
                    "- block : {0}\n"
                    "- parent: {1}. ".format(
                        block.header.timestamp,
                        parent_header.timestamp,
                    ))

        tx_root_hash, _ = make_trie_root_and_nodes(block.transactions)
        if tx_root_hash != block.header.transaction_root:
            raise ValidationError(
                "Block's transaction_root ({0}) does not match expected value: {1}"
                .format(block.header.transaction_root, tx_root_hash))

        if len(block.uncles) > MAX_UNCLES:
            raise ValidationError(
                "Blocks may have a maximum of {0} uncles.  Found "
                "{1}.".format(MAX_UNCLES, len(block.uncles)))

        for uncle in block.uncles:
            self.validate_uncle(block, uncle)

        if not self.state.is_key_exists(block.header.state_root):
            raise ValidationError("`state_root` was not found in the db.\n"
                                  "- state_root: {0}".format(
                                      block.header.state_root, ))
        local_uncle_hash = keccak(rlp.encode(block.uncles))
        if local_uncle_hash != block.header.uncles_hash:
            raise ValidationError(
                "`uncles_hash` and block `uncles` do not match.\n"
                " - num_uncles       : {0}\n"
                " - block uncle_hash : {1}\n"
                " - header uncle_hash: {2}".format(
                    len(block.uncles),
                    local_uncle_hash,
                    block.header.uncle_hash,
                ))
Esempio n. 5
0
    def validate_block(self, block):
        if not block.is_genesis:
            parent_header = get_parent_header(block.header, self.chaindb)

            validate_gas_limit(block.header.gas_limit, parent_header.gas_limit)
            validate_length_lte(block.header.extra_data, 32, title="BlockHeader.extra_data")

            # timestamp
            if block.header.timestamp < parent_header.timestamp:
                raise ValidationError(
                    "`timestamp` is before the parent block's timestamp.\n"
                    "- block  : {0}\n"
                    "- parent : {1}. ".format(
                        block.header.timestamp,
                        parent_header.timestamp,
                    )
                )
            elif block.header.timestamp == parent_header.timestamp:
                raise ValidationError(
                    "`timestamp` is equal to the parent block's timestamp\n"
                    "- block : {0}\n"
                    "- parent: {1}. ".format(
                        block.header.timestamp,
                        parent_header.timestamp,
                    )
                )

        if len(block.uncles) > MAX_UNCLES:
            raise ValidationError(
                "Blocks may have a maximum of {0} uncles.  Found "
                "{1}.".format(MAX_UNCLES, len(block.uncles))
            )

        for uncle in block.uncles:
            self.validate_uncle(block, uncle)

        if not self.state.is_key_exists(block.header.state_root):
            raise ValidationError(
                "`state_root` was not found in the db.\n"
                "- state_root: {0}".format(
                    block.header.state_root,
                )
            )
        local_uncle_hash = keccak(rlp.encode(block.uncles))
        if local_uncle_hash != block.header.uncles_hash:
            raise ValidationError(
                "`uncles_hash` and block `uncles` do not match.\n"
                " - num_uncles       : {0}\n"
                " - block uncle_hash : {1}\n"
                " - header uncle_hash: {2}".format(
                    len(block.uncles),
                    local_uncle_hash,
                    block.header.uncle_hash,
                )
            )
Esempio n. 6
0
    def get_prev_hashes(cls, last_block_hash, db):
        if last_block_hash == GENESIS_PARENT_HASH:
            return

        block_header = get_block_header_by_hash(last_block_hash, db)

        for _ in range(MAX_PREV_HEADER_DEPTH):
            yield block_header.hash
            try:
                block_header = get_parent_header(block_header, db)
            except (IndexError, BlockNotFound):
                break
Esempio n. 7
0
    def get_prev_hashes(cls, last_block_hash, db):
        if last_block_hash == GENESIS_PARENT_HASH:
            return

        block_header = get_block_header_by_hash(last_block_hash, db)

        for _ in range(MAX_PREV_HEADER_DEPTH):
            yield block_header.hash
            try:
                block_header = get_parent_header(block_header, db)
            except (IndexError, BlockNotFound):
                break
Esempio n. 8
0
def configure_byzantium_header(vm, **header_params):
    validate_header_params_for_configuration(header_params)

    with vm.block.header.build_changeset(**header_params) as changeset:
        if 'timestamp' in header_params and changeset.block_number > 0:
            parent_header = get_parent_header(changeset.build_rlp(),
                                              vm.chaindb)
            changeset.difficulty = compute_byzantium_difficulty(
                parent_header,
                header_params['timestamp'],
            )

        header = changeset.commit()
    return header
Esempio n. 9
0
def configure_byzantium_header(vm, **header_params):
    validate_header_params_for_configuration(header_params)

    for field_name, value in header_params.items():
        setattr(vm.block.header, field_name, value)

    if 'timestamp' in header_params and vm.block.header.block_number > 0:
        parent_header = get_parent_header(vm.block.header, vm.chaindb)
        vm.block.header.difficulty = compute_byzantium_difficulty(
            parent_header,
            header_params['timestamp'],
        )

    return vm.block.header
Esempio n. 10
0
def configure_frontier_header(vm, **header_params):
    validate_header_params_for_configuration(header_params)

    for field_name, value in header_params.items():
        setattr(vm.block.header, field_name, value)

    if 'timestamp' in header_params and vm.block.header.block_number > 0:
        parent_header = get_parent_header(vm.block.header, vm.chaindb)
        vm.block.header.difficulty = compute_frontier_difficulty(
            parent_header,
            header_params['timestamp'],
        )

    return vm.block.header
Esempio n. 11
0
    def validate_block(self, block):
        """
        Validate the the given block.
        """
        if not isinstance(block, self.get_block_class()):
            raise ValidationError(
                "This vm ({0!r}) is not equipped to validate a block of type {1!r}".format(
                    self,
                    block,
                )
            )

        if block.is_genesis:
            validate_length_lte(block.header.extra_data, 32, title="BlockHeader.extra_data")
        else:
            parent_header = get_parent_header(block.header, self.chaindb)
            self.validate_header(block.header, parent_header)

        tx_root_hash, _ = make_trie_root_and_nodes(block.transactions)
        if tx_root_hash != block.header.transaction_root:
            raise ValidationError(
                "Block's transaction_root ({0}) does not match expected value: {1}".format(
                    block.header.transaction_root, tx_root_hash))

        if len(block.uncles) > MAX_UNCLES:
            raise ValidationError(
                "Blocks may have a maximum of {0} uncles.  Found "
                "{1}.".format(MAX_UNCLES, len(block.uncles))
            )

        if not self.chaindb.exists(block.header.state_root):
            raise ValidationError(
                "`state_root` was not found in the db.\n"
                "- state_root: {0}".format(
                    block.header.state_root,
                )
            )
        local_uncle_hash = keccak(rlp.encode(block.uncles))
        if local_uncle_hash != block.header.uncles_hash:
            raise ValidationError(
                "`uncles_hash` and block `uncles` do not match.\n"
                " - num_uncles       : {0}\n"
                " - block uncle_hash : {1}\n"
                " - header uncle_hash: {2}".format(
                    len(block.uncles),
                    local_uncle_hash,
                    block.header.uncle_hash,
                )
            )
Esempio n. 12
0
    def get_prev_headers(cls, last_block_hash, db):
        prev_headers = []

        if last_block_hash == GENESIS_PARENT_HASH:
            return prev_headers

        block_header = get_block_header_by_hash(last_block_hash, db)

        for _ in range(MAX_PREV_HEADER_DEPTH):
            prev_headers.append(block_header)
            try:
                block_header = get_parent_header(block_header, db)
            except (IndexError, BlockNotFound):
                break
        return prev_headers