Esempio n. 1
0
 def validate(self):
     """
     Hook called during instantiation to ensure that all transaction
     parameters pass validation rules.
     """
     if self.intrinsic_gas > self.gas:
         raise ValidationError("Insufficient gas")
     self.check_signature_validity()
Esempio n. 2
0
def validate_transaction_signature(transaction: BaseTransaction) -> None:
    if is_eip_155_signed_transaction(transaction):
        v = extract_signature_v(transaction.v)
    else:
        v = transaction.v

    canonical_v = v - 27
    vrs = (canonical_v, transaction.r, transaction.s)
    signature = keys.Signature(vrs=vrs)
    message = transaction.get_message_for_signing()
    try:
        public_key = signature.recover_public_key_from_msg(message)
    except BadSignature as e:
        raise ValidationError("Bad Signature: {0}".format(str(e)))

    if not signature.verify_msg(message, public_key):
        raise ValidationError("Invalid Signature")
Esempio n. 3
0
def validate_header_params_for_configuration(header_params):
    extra_fields = set(header_params.keys()).difference(ALLOWED_HEADER_FIELDS)
    if extra_fields:
        raise ValidationError(
            "The `configure_header` method may only be used with the fields ({0}). "
            "The provided fields ({1}) are not supported".format(
                ", ".join(tuple(sorted(ALLOWED_HEADER_FIELDS))),
                ", ".join(tuple(sorted(extra_fields))),
            ))
Esempio n. 4
0
def validate_length(value, length):
    if not len(value) == length:
        raise ValidationError(
            "Value must be of length {0}.  Got {1} of length {2}".format(
                length,
                value,
                len(value),
            )
        )
Esempio n. 5
0
def validate_length(value, length, title="Value"):
    if not len(value) == length:
        raise ValidationError(
            "{title} must be of length {0}.  Got {1} of length {2}".format(
                length,
                value,
                len(value),
                title=title,
            ))
Esempio n. 6
0
def validate_gte(value, minimum, title="Value"):
    if value < minimum:
        raise ValidationError(
            "{title} {0} is not greater than or equal to {1}".format(
                value,
                minimum,
                title=title,
            ))
    validate_is_integer(value)
Esempio n. 7
0
def validate_length_lte(value, maximum_length):
    if len(value) > maximum_length:
        raise ValidationError(
            "Value must be of length less than or equal to {0}.  "
            "Got {1} of length {2}".format(
                maximum_length,
                value,
                len(value),
            ))
Esempio n. 8
0
def validate_lte(value, maximum, title="Value"):
    if value > maximum:
        raise ValidationError(
            "{title} {0} is not less than or equal to {1}".format(
                value,
                maximum,
                title=title,
            ))
    validate_is_integer(value, title=title)
Esempio n. 9
0
def validate_frontier_transaction_against_header(_vm, base_header, transaction):
    if base_header.gas_used + transaction.gas > base_header.gas_limit:
        raise ValidationError(
            "Transaction exceeds gas limit: using {}, bringing total to {}, but limit is {}".format(
                transaction.gas,
                base_header.gas_used + transaction.gas,
                base_header.gas_limit,
            )
        )
Esempio n. 10
0
    def validate(self):
        if not self.is_genesis:
            parent_header = self.get_parent_header()

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

        super(FrontierBlock, self).validate()
Esempio n. 11
0
 def validate_chain(self, chain: Tuple[BlockHeader, ...]) -> None:
     parent = self.chaindb.get_block_header_by_hash(chain[0].parent_hash)
     for header in chain:
         if header.parent_hash != parent.hash:
             raise ValidationError(
                 "Invalid header chain; {} has parent {}, but expected {}".
                 format(header, header.parent_hash, parent.hash))
         vm_class = self.get_vm_class_for_block_number(header.block_number)
         vm_class.validate_header(header, parent)
         parent = header
Esempio n. 12
0
def validate_transaction_access_list(access_list, title="Access List"):
    for item in access_list:
        if len(item) == 0:
            raise ValidationError(
                "{0} entry must at least specify an account address.".format(
                    title))
        address, *prefixes = item
        validate_canonical_address(address,
                                   title="Address in {0}".format(title))
        for prefix in prefixes:
            validate_is_bytes(prefix,
                              title="Storage prefix in {0}".format(title))
            if len(prefix) > 32:
                raise ValidationError(
                    "Storage prefix in {0} must be 32 bytes or shorter. Got: {1}"
                    .format(
                        title,
                        prefix,
                    ))
Esempio n. 13
0
File: chain.py Progetto: ofek/py-evm
    def get_parent_chain(self, block):
        try:
            parent_header = self.get_block_header_by_hash(
                block.header.parent_hash)
        except BlockNotFound:
            raise ValidationError("Parent ({0}) of block {1} not found".format(
                block.header.parent_hash, block.header.hash))

        init_header = self.create_header_from_parent(parent_header)
        return type(self)(self.db, init_header)
Esempio n. 14
0
def check_shard_id(
        shard: Shard, header_or_collation: Union[CollationHeader,
                                                 Collation]) -> None:
    if header_or_collation.shard_id != shard.shard_id:
        raise ValidationError(
            "Header or collation belongs to shard {} instead of shard {}".
            format(
                header_or_collation.shard_id,
                shard.shard_id,
            ))
Esempio n. 15
0
def validate_frontier_transaction(state, transaction):
    gas_cost = transaction.gas * transaction.gas_price
    sender_balance = state.account_db.get_balance(transaction.sender)

    if sender_balance < gas_cost:
        raise ValidationError(
            "Sender account balance cannot afford txn gas: `{0}`".format(
                transaction.sender))

    total_cost = transaction.value + gas_cost

    if sender_balance < total_cost:
        raise ValidationError("Sender account balance cannot afford txn")

    if state.gas_used + transaction.gas > state.gas_limit:
        raise ValidationError("Transaction exceeds gas limit")

    if state.account_db.get_nonce(transaction.sender) != transaction.nonce:
        raise ValidationError("Invalid transaction nonce")
Esempio n. 16
0
    def validate_transaction(self, transaction):

        # Validate the transaction

        if transaction.intrinsic_gas > transaction.gas:
            raise ValidationError("Insufficient gas")

        transaction.validate()
        self.vm_state.validate_transaction(transaction)

        return transaction
Esempio n. 17
0
    def validate_uncle(self, block, uncle, uncle_parent):
        """
        Validate the given uncle in the context of the given block.
        """
        if uncle.block_number >= block.number:
            raise ValidationError(
                "Uncle number ({0}) is higher than block number ({1})".format(
                    uncle.block_number, block.number))

        if uncle.block_number != uncle_parent.block_number + 1:
            raise ValidationError(
                "Uncle number ({0}) is not one above ancestor's number ({1})".format(
                    uncle.block_number, uncle_parent.block_number))
        if uncle.timestamp < uncle_parent.timestamp:
            raise ValidationError(
                "Uncle timestamp ({0}) is before ancestor's timestamp ({1})".format(
                    uncle.timestamp, uncle_parent.timestamp))
        if uncle.gas_used > uncle.gas_limit:
            raise ValidationError(
                "Uncle's gas usage ({0}) is above the limit ({1})".format(
                    uncle.gas_used, uncle.gas_limit))
Esempio n. 18
0
def check_pow(block_number, mining_hash, mix_hash, nonce, difficulty):
    validate_length(mix_hash, 32)
    validate_length(mining_hash, 32)
    validate_length(nonce, 8)
    cache = get_cache(block_number)
    mining_output = hashimoto_light(block_number, cache, mining_hash,
                                    big_endian_to_int(nonce))
    if mining_output[b'mix digest'] != mix_hash:
        raise ValidationError("mix hash mistmatch; {0} != {1}".format(
            encode_hex(mining_output[b'mix digest']), encode_hex(mix_hash)))
    result = big_endian_to_int(mining_output[b'result'])
    validate_lte(result, 2**256 // difficulty)
Esempio n. 19
0
    async def _validate_header(self, header):
        if header.is_genesis:
            raise ValidationError("Peer sent a genesis header {} that we didn't ask for".format(
                header,
            ))
        else:
            async_header = self.headerdb.coro_get_block_header_by_hash(header.parent_hash)
            parent_header = await self.wait(async_header)

            VM = self.chain_class.get_vm_class_for_block_number(header.block_number)
            # TODO push validation into process pool executor
            VM.validate_header(header, parent_header)
Esempio n. 20
0
    def refund_gas(self, amount):
        if amount < 0:
            raise ValidationError("Gas refund amount must be positive")

        self.gas_refunded += amount

        self.logger.trace(
            'GAS REFUND: %s + %s -> %s',
            self.gas_refunded - amount,
            amount,
            self.gas_refunded,
        )
Esempio n. 21
0
def validate_frontier_transaction(vm, transaction):
    gas_cost = transaction.gas * transaction.gas_price
    with vm.state.state_db(read_only=True) as state_db:
        sender_balance = state_db.get_balance(transaction.sender)

    if sender_balance < gas_cost:
        raise ValidationError(
            "Sender account balance cannot afford txn gas: `{0}`".format(
                transaction.sender))

    total_cost = transaction.value + gas_cost

    if sender_balance < total_cost:
        raise ValidationError("Sender account balance cannot afford txn")

    if vm.block.header.gas_used + transaction.gas > vm.block.header.gas_limit:
        raise ValidationError("Transaction exceeds gas limit")

    with vm.state.state_db(read_only=True) as state_db:
        if state_db.get_nonce(transaction.sender) != transaction.nonce:
            raise ValidationError("Invalid transaction nonce")
Esempio n. 22
0
    def return_gas(self, amount):
        if amount < 0:
            raise ValidationError("Gas return amount must be positive")

        self.gas_remaining += amount

        self.logger.trace(
            'GAS RETURNED: %s + %s -> %s',
            self.gas_remaining - amount,
            amount,
            self.gas_remaining,
        )
Esempio n. 23
0
def check_pow(block_number: int, mining_hash: Hash32, mix_hash: Hash32,
              nonce: bytes, difficulty: int) -> None:
    validate_length(mix_hash, 32, title="Mix Hash")
    validate_length(mining_hash, 32, title="Mining Hash")
    validate_length(nonce, 8, title="POW Nonce")
    cache = get_cache(block_number)
    mining_output = hashimoto_light(block_number, cache, mining_hash,
                                    big_endian_to_int(nonce))
    if mining_output[b'mix digest'] != mix_hash:
        raise ValidationError("mix hash mismatch; {0} != {1}".format(
            encode_hex(mining_output[b'mix digest']), encode_hex(mix_hash)))
    result = big_endian_to_int(mining_output[b'result'])
    validate_lte(result, 2**256 // difficulty, title="POW Difficulty")
Esempio n. 24
0
    def validate_uncles(self, block: BaseBlock) -> None:
        """
        Validate the uncles for the given block.
        """
        # Check for duplicates
        uncle_groups = groupby(operator.attrgetter('hash'), block.uncles)
        duplicate_uncles = tuple(sorted(
            hash for hash, twins in uncle_groups.items() if len(twins) > 1
        ))
        if duplicate_uncles:
            raise ValidationError(
                "Block contains duplicate uncles:\n"
                " - {0}".format(' - '.join(duplicate_uncles))
            )

        recent_ancestors = tuple(
            ancestor
            for ancestor
            in self.get_ancestors(MAX_UNCLE_DEPTH + 1, header=block.header)
        )
        recent_ancestor_hashes = {ancestor.hash for ancestor in recent_ancestors}
        recent_uncle_hashes = _extract_uncle_hashes(recent_ancestors)

        for uncle in block.uncles:
            if uncle.hash == block.hash:
                raise ValidationError("Uncle has same hash as block")

            # ensure the uncle has not already been included.
            if uncle.hash in recent_uncle_hashes:
                raise ValidationError(
                    "Duplicate uncle: {0}".format(encode_hex(uncle.hash))
                )

            # ensure that the uncle is not one of the canonical chain blocks.
            if uncle.hash in recent_ancestor_hashes:
                raise ValidationError(
                    "Uncle {0} cannot be an ancestor of {1}".format(
                        encode_hex(uncle.hash), encode_hex(block.hash)))

            # ensure that the uncle was built off of one of the canonical chain
            # blocks.
            if uncle.parent_hash not in recent_ancestor_hashes or (
               uncle.parent_hash == block.header.parent_hash):
                raise ValidationError(
                    "Uncle's parent {0} is not an ancestor of {1}".format(
                        encode_hex(uncle.parent_hash), encode_hex(block.hash)))

            # Now perform VM level validation of the uncle
            self.validate_seal(uncle)

            try:
                uncle_parent = self.get_block_header_by_hash(uncle.parent_hash)
            except HeaderNotFound:
                raise ValidationError(
                    "Uncle ancestor not found: {0}".format(uncle.parent_hash)
                )

            uncle_vm_class = self.get_vm_class_for_block_number(uncle.block_number)
            uncle_vm_class.validate_uncle(block, uncle, uncle_parent)
Esempio n. 25
0
 def validate_uncle(self, block, uncle):
     if uncle.block_number >= block.number:
         raise ValidationError(
             "Uncle number ({0}) is higher than block number ({1})".format(
                 uncle.block_number, block.number))
     try:
         parent_header = get_block_header_by_hash(uncle.parent_hash, self.chaindb)
     except BlockNotFound:
         raise ValidationError(
             "Uncle ancestor not found: {0}".format(uncle.parent_hash))
     if uncle.block_number != parent_header.block_number + 1:
         raise ValidationError(
             "Uncle number ({0}) is not one above ancestor's number ({1})".format(
                 uncle.block_number, parent_header.block_number))
     if uncle.timestamp < parent_header.timestamp:
         raise ValidationError(
             "Uncle timestamp ({0}) is before ancestor's timestamp ({1})".format(
                 uncle.timestamp, parent_header.timestamp))
     if uncle.gas_used > uncle.gas_limit:
         raise ValidationError(
             "Uncle's gas usage ({0}) is above the limit ({1})".format(
                 uncle.gas_used, uncle.gas_limit))
Esempio n. 26
0
    def get_chain_at_block_parent(self, block: BaseBlock) -> BaseChain:
        """
        Returns a `Chain` instance with the given block's parent at the chain head.
        """
        try:
            parent_header = self.get_block_header_by_hash(
                block.header.parent_hash)
        except HeaderNotFound:
            raise ValidationError("Parent ({0}) of block {1} not found".format(
                block.header.parent_hash, block.header.hash))

        init_header = self.create_header_from_parent(parent_header)
        return type(self)(self.chaindb.db, init_header)
Esempio n. 27
0
def validate_unique(values):
    if not isdistinct(values):
        duplicates = pipe(
            values,
            frequencies,  # get the frequencies
            partial(valfilter,
                    lambda v: v > 1),  # filter to ones that occure > 1
            sorted,  # sort them
            tuple,  # cast them to an immutiable form
        )
        raise ValidationError(
            "The values provided are not unique.  Duplicates: {0}".format(
                ', '.join((str(value) for value in duplicates))))
Esempio n. 28
0
def _process_point(data_buffer, exponent):
    x1, y1, x2_i, x2_r, y2_i, y2_r = _extract_point(data_buffer)
    p1 = validate_point(x1, y1)

    for v in (x2_i, x2_r, y2_i, y2_r):
        if v >= bn128.field_modulus:
            raise ValidationError("value greater than field modulus")

    fq2_x = bn128.FQ2([x2_r, x2_i])
    fq2_y = bn128.FQ2([y2_r, y2_i])

    if (fq2_x, fq2_y) != (bn128.FQ2.zero(), bn128.FQ2.zero()):
        p2 = (fq2_x, fq2_y, bn128.FQ2.one())
        if not bn128.is_on_curve(p2, bn128.b2):
            raise ValidationError("point is not on curve")
    else:
        p2 = ZERO

    if bn128.multiply(p2, bn128.curve_order)[-1] != bn128.FQ2.zero():
        raise ValidationError("TODO: what case is this?????")

    return exponent * bn128.pairing(p2, p1, final_exponentiate=False)
Esempio n. 29
0
 def validate_uncle(self, uncle):
     if uncle.block_number >= self.number:
         raise ValidationError(
             "Uncle number ({0}) is higher than block number ({1})".format(
                 uncle.block_number, self.number))
     try:
         uncle_parent = self.db.get(uncle.parent_hash)
     except KeyError:
         raise ValidationError("Uncle ancestor not found: {0}".format(
             uncle.parent_hash))
     parent_header = rlp.decode(uncle_parent, sedes=BlockHeader)
     if uncle.block_number != parent_header.block_number + 1:
         raise ValidationError(
             "Uncle number ({0}) is not one above ancestor's number ({1})".
             format(uncle.block_number, parent_header.block_number))
     if uncle.timestamp < parent_header.timestamp:
         raise ValidationError(
             "Uncle timestamp ({0}) is before ancestor's timestamp ({1})".
             format(uncle.timestamp, parent_header.timestamp))
     if uncle.gas_used > uncle.gas_limit:
         raise ValidationError(
             "Uncle's gas usage ({0}) is above the limit ({1})".format(
                 uncle.gas_used, uncle.gas_limit))
Esempio n. 30
0
    async def fetch_headers(self, start_block: int, peer: LESPeer) -> List[BlockHeader]:
        if start_block == GENESIS_BLOCK_NUMBER:
            raise ValidationError("Must not attempt to download genesis header")

        for i in range(self.max_consecutive_timeouts):
            try:
                return await self._fetch_headers_starting_at(peer, start_block)
            except TimeoutError:
                self.logger.info(
                    "Timeout when fetching headers from %s (attempt %d of %d)",
                    peer, i + 1, self.max_consecutive_timeouts)
                # TODO: Figure out what's a good value to use here.
                await asyncio.sleep(0.5)
        raise TooManyTimeouts()