Пример #1
0
def test_storage_restriction(valid_shard_chain, funded_address):  # noqa: F811
    shard_chain = valid_shard_chain
    vm = shard_chain.get_vm()
    address = funded_address
    other_address = b'\xaa' * 20
    access_list = to_prefix_list_form([[address, b'\x00', b'\xff' * 32]])

    tests = (
        (True, 'get_storage', [address, big_endian_to_int(b'\x00' * 32)]),
        (True, 'get_storage', [address, big_endian_to_int(b'\x00' * 31 + b'\xff')]),
        (True, 'get_storage', [address, big_endian_to_int(b'\xff' * 32)]),
        (False, 'get_storage', [address, big_endian_to_int(b'\xaa' * 32)]),
        (False, 'get_storage', [other_address, big_endian_to_int(b'\x00' * 32)]),

        (True, 'set_storage', [address, big_endian_to_int(b'\x00' * 32), 0]),
        (True, 'set_storage', [address, big_endian_to_int(b'\x00' * 31 + b'\xff'), 0]),
        (True, 'set_storage', [address, big_endian_to_int(b'\xff' * 32), 0]),
        (False, 'set_storage', [address, big_endian_to_int(b'\xaa' * 32), 0]),
        (False, 'set_storage', [other_address, big_endian_to_int(b'\x00' * 32), 0]),
    )

    for valid, method, args in tests:
        if valid:
            with vm.state.state_db(access_list=access_list) as state_db:
                getattr(state_db, method)(*args)
        else:
            with pytest.raises(UnannouncedStateAccess):
                with vm.state.state_db(access_list=access_list) as state_db:
                    getattr(state_db, method)(*args)

        # without access list everything is invalid
        with pytest.raises(UnannouncedStateAccess):
            with vm.state.state_db(access_list=[]) as state_db:
                getattr(state_db, method)(*args)
Пример #2
0
def precompile_ecrecover(computation):
    computation.gas_meter.consume_gas(constants.GAS_ECRECOVER, reason="ECRecover Precompile")
    raw_message_hash = computation.msg.data[:32]
    message_hash = pad32r(raw_message_hash)

    v_bytes = pad32r(computation.msg.data[32:64])
    v = big_endian_to_int(v_bytes)

    r_bytes = pad32r(computation.msg.data[64:96])
    r = big_endian_to_int(r_bytes)

    s_bytes = pad32r(computation.msg.data[96:128])
    s = big_endian_to_int(s_bytes)

    try:
        validate_lt_secpk1n(r)
        validate_lt_secpk1n(s)
        validate_lte(v, 28)
        validate_gte(v, 27)
    except ValidationError:
        return computation

    try:
        raw_public_key = ecdsa_raw_recover(message_hash, (v, r, s))
    except ValueError:
        return computation

    public_key = encode_raw_public_key(raw_public_key)
    address = public_key_to_address(public_key)
    padded_address = pad32(address)

    computation.output = padded_address
    return computation
Пример #3
0
def ecrecover(computation):
    computation.gas_meter.consume_gas(constants.GAS_ECRECOVER, reason="ECRecover Precompile")
    raw_message_hash = computation.msg.data[:32]
    message_hash = pad32r(raw_message_hash)

    v_bytes = pad32r(computation.msg.data[32:64])
    v = big_endian_to_int(v_bytes)

    r_bytes = pad32r(computation.msg.data[64:96])
    r = big_endian_to_int(r_bytes)

    s_bytes = pad32r(computation.msg.data[96:128])
    s = big_endian_to_int(s_bytes)

    try:
        validate_lt_secpk1n(r, title="ECRecover: R")
        validate_lt_secpk1n(s, title="ECRecover: S")
        validate_lte(v, 28, title="ECRecover: V")
        validate_gte(v, 27, title="ECRecover: V")
    except ValidationError:
        return computation

    canonical_v = v - 27

    try:
        signature = keys.Signature(vrs=(canonical_v, r, s))
        public_key = signature.recover_public_key_from_msg_hash(message_hash)
    except BadSignature:
        return computation

    address = public_key.to_canonical_address()
    padded_address = pad32(address)

    computation.output = padded_address
    return computation
Пример #4
0
def _modexp(data):
    base_length, exponent_length, modulus_length = _extract_lengths(data)

    if base_length == 0:
        return 0
    elif modulus_length == 0:
        return 0

    # compute start:end indexes
    base_end_idx = 96 + base_length
    exponent_end_idx = base_end_idx + exponent_length
    modulus_end_dx = exponent_end_idx + modulus_length

    # extract arguments
    modulus_bytes = zpad_right(
        data[exponent_end_idx:modulus_end_dx],
        to_size=modulus_length,
    )
    modulus = big_endian_to_int(modulus_bytes)
    if modulus == 0:
        return 0

    base_bytes = zpad_right(data[96:base_end_idx], to_size=base_length)
    base = big_endian_to_int(base_bytes)

    exponent_bytes = zpad_right(
        data[base_end_idx:exponent_end_idx],
        to_size=exponent_length,
    )
    exponent = big_endian_to_int(exponent_bytes)
    print('base', base, 'exponent', exponent, 'modulus', modulus)

    result = pow(base, exponent, modulus)

    return result
Пример #5
0
def _modexp(data):
    base_length, exponent_length, modulus_length = _extract_lengths(data)

    if base_length == 0:
        return 0
    elif modulus_length == 0:
        return 0

    # compute start:end indexes
    base_end_idx = 96 + base_length
    exponent_end_idx = base_end_idx + exponent_length
    modulus_end_dx = exponent_end_idx + modulus_length

    # extract arguments
    modulus_bytes = zpad_right(
        data[exponent_end_idx:modulus_end_dx],
        to_size=modulus_length,
    )
    modulus = big_endian_to_int(modulus_bytes)
    if modulus == 0:
        return 0

    base_bytes = zpad_right(data[96:base_end_idx], to_size=base_length)
    base = big_endian_to_int(base_bytes)

    exponent_bytes = zpad_right(
        data[base_end_idx:exponent_end_idx],
        to_size=exponent_length,
    )
    exponent = big_endian_to_int(exponent_bytes)
    print('base', base, 'exponent', exponent, 'modulus', modulus)

    result = pow(base, exponent, modulus)

    return result
Пример #6
0
 def ecdsa_raw_sign(self, msg_hash, private_key):
     signature = self.keys.PrivateKey(private_key).sign_recoverable(
         msg_hash, hasher=None)
     v = safe_ord(signature[64]) + 27
     r = big_endian_to_int(signature[0:32])
     s = big_endian_to_int(signature[32:64])
     return v, r, s
Пример #7
0
def _compute_adjusted_exponent_length(exponent_length,
                                      first_32_exponent_bytes):
    exponent = big_endian_to_int(first_32_exponent_bytes)

    if exponent_length <= 32 and exponent == 0:
        return 0
    elif exponent_length <= 32:
        return get_highest_bit_index(exponent)
    else:
        first_32_bytes_as_int = big_endian_to_int(first_32_exponent_bytes)
        return (8 * (exponent_length - 32) +
                get_highest_bit_index(first_32_bytes_as_int))
Пример #8
0
def parse_collation_added_log(log):
    # here assume `shard_id` is the first indexed , which is the second element in topics
    shard_id_bytes32 = log['topics'][1]
    data_hex = log['data']
    data_bytes = decode_hex(data_hex)
    score = big_endian_to_int(data_bytes[-32:])
    is_new_head = bool(big_endian_to_int(data_bytes[-64:-32]))
    header_bytes = shard_id_bytes32 + data_bytes[:-64]
    collation_header = CollationHeader.from_bytes(header_bytes)
    yield 'header', collation_header
    yield 'is_new_head', is_new_head
    yield 'score', score
Пример #9
0
def _extract_lengths(data):
    # extract argument lengths
    base_length_bytes = pad32r(data[:32])
    base_length = big_endian_to_int(base_length_bytes)

    exponent_length_bytes = pad32r(data[32:64])
    exponent_length = big_endian_to_int(exponent_length_bytes)

    modulus_length_bytes = pad32r(data[64:96])
    modulus_length = big_endian_to_int(modulus_length_bytes)

    return base_length, exponent_length, modulus_length
Пример #10
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)
Пример #11
0
def _extract_lengths(data):
    # extract argument lengths
    base_length_bytes = pad32r(data[:32])
    base_length = big_endian_to_int(base_length_bytes)

    exponent_length_bytes = pad32r(data[32:64])
    exponent_length = big_endian_to_int(exponent_length_bytes)

    modulus_length_bytes = pad32r(data[64:96])
    modulus_length = big_endian_to_int(modulus_length_bytes)

    return base_length, exponent_length, modulus_length
Пример #12
0
def check_pow(block_number, mining_hash, mix_hash, nonce, difficulty):
    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")
Пример #13
0
def _ecmull(data):
    x_bytes = pad32r(data[:32])
    y_bytes = pad32r(data[32:64])
    m_bytes = pad32r(data[64:96])

    x = big_endian_to_int(x_bytes)
    y = big_endian_to_int(y_bytes)
    m = big_endian_to_int(m_bytes)

    p = validate_point(x, y)

    result = bn128.normalize(bn128.multiply(p, m))
    return result
Пример #14
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")
Пример #15
0
def _ecmull(data):
    x_bytes = pad32r(data[:32])
    y_bytes = pad32r(data[32:64])
    m_bytes = pad32r(data[64:96])

    x = big_endian_to_int(x_bytes)
    y = big_endian_to_int(y_bytes)
    m = big_endian_to_int(m_bytes)

    p = validate_point(x, y)

    result = bn128.normalize(bn128.multiply(p, m))
    return result
Пример #16
0
def populated_shard_chaindb_and_root_hash(shard_chaindb):
    if shard_chaindb.trie_class is HexaryTrie:
        root_hash = BLANK_ROOT_HASH
    else:
        root_hash = EMPTY_SHA3

    state_db = shard_chaindb.get_state_db(root_hash, read_only=False)
    state_db.set_balance(A_ADDRESS, 1)
    state_db.set_code(B_ADDRESS, b"code")
    state_db.set_storage(B_ADDRESS, big_endian_to_int(b"key1"), 100)
    state_db.set_storage(B_ADDRESS, big_endian_to_int(b"key2"), 200)
    state_db.set_storage(B_ADDRESS, big_endian_to_int(b"key"), 300)
    return shard_chaindb, state_db.root_hash
Пример #17
0
def _compute_adjusted_exponent_length(exponent_length, first_32_exponent_bytes):
    exponent = big_endian_to_int(first_32_exponent_bytes)

    if exponent_length <= 32 and exponent == 0:
        return 0
    elif exponent_length <= 32:
        return get_highest_bit_index(exponent)
    else:
        first_32_bytes_as_int = big_endian_to_int(first_32_exponent_bytes)
        return (
            8 * (exponent_length - 32) +
            get_highest_bit_index(first_32_bytes_as_int)
        )
Пример #18
0
def normalize_block_header(header):
    normalized_header = {
        'bloom': big_endian_to_int(decode_hex(header['bloom'])),
        'coinbase': to_canonical_address(header['coinbase']),
        'difficulty': to_int(header['difficulty']),
        'extraData': decode_hex(header['extraData']),
        'gasLimit': to_int(header['gasLimit']),
        'gasUsed': to_int(header['gasUsed']),
        'hash': decode_hex(header['hash']),
        'mixHash': decode_hex(header['mixHash']),
        'nonce': decode_hex(header['nonce']),
        'number': to_int(header['number']),
        'parentHash': decode_hex(header['parentHash']),
        'receiptTrie': decode_hex(header['receiptTrie']),
        'stateRoot': decode_hex(header['stateRoot']),
        'timestamp': to_int(header['timestamp']),
        'transactionsTrie': decode_hex(header['transactionsTrie']),
        'uncleHash': decode_hex(header['uncleHash']),
    }
    if 'blocknumber' in header:
        normalized_header['blocknumber'] = to_int(header['blocknumber'])
    if 'chainname' in header:
        normalized_header['chainname'] = header['chainname']
    if 'chainnetwork' in header:
        normalized_header['chainnetwork'] = header['chainnetwork']
    return normalized_header
Пример #19
0
def _ecadd(data):
    x1_bytes = pad32r(data[:32])
    y1_bytes = pad32r(data[32:64])
    x2_bytes = pad32r(data[64:96])
    y2_bytes = pad32r(data[96:128])

    x1 = big_endian_to_int(x1_bytes)
    y1 = big_endian_to_int(y1_bytes)
    x2 = big_endian_to_int(x2_bytes)
    y2 = big_endian_to_int(y2_bytes)

    p1 = validate_point(x1, y1)
    p2 = validate_point(x2, y2)

    result = bn128.normalize(bn128.add(p1, p2))
    return result
Пример #20
0
    def get_balance(self, address):
        validate_canonical_address(address, title="Storage Address")

        key = get_balance_key(address)
        self._check_accessibility(key)

        if key in self._trie:
            return big_endian_to_int(self._trie[key])
        else:
            return 0
Пример #21
0
def mine_pow_nonce(block_number: int, mining_hash: Hash32, difficulty: int) -> Tuple[bytes, bytes]:
    cache = get_cache(block_number)
    for nonce in range(MAX_TEST_MINE_ATTEMPTS):
        mining_output = hashimoto_light(block_number, cache, mining_hash, nonce)
        result = big_endian_to_int(mining_output[b'result'])
        result_cap = 2**256 // difficulty
        if result <= result_cap:
            return nonce.to_bytes(8, 'big'), mining_output[b'mix digest']

    raise Exception("Too many attempts at POW mining, giving up")
Пример #22
0
    def get_storage(self, address, slot):
        validate_canonical_address(address, title="Storage Address")
        validate_uint256(slot, title="Storage Slot")

        key = get_storage_key(address, slot)
        self._check_accessibility(key)

        if key in self._trie:
            return big_endian_to_int(self._trie[key])
        else:
            return 0
Пример #23
0
def normalize_account_state(account_state):
    return {
        to_canonical_address(address): {
            'balance': to_int(state['balance']),
            'code': decode_hex(state['code']),
            'nonce': to_int(state['nonce']),
            'storage': {
                to_int(slot): big_endian_to_int(decode_hex(value))
                for slot, value in state['storage'].items()
            },
        } for address, state in account_state.items()
    }
Пример #24
0
def ecrecover(computation):
    computation.gas_meter.consume_gas(constants.GAS_ECRECOVER,
                                      reason="ECRecover Precompile")
    raw_message_hash = computation.msg.data[:32]
    message_hash = pad32r(raw_message_hash)

    v_bytes = pad32r(computation.msg.data[32:64])
    v = big_endian_to_int(v_bytes)

    r_bytes = pad32r(computation.msg.data[64:96])
    r = big_endian_to_int(r_bytes)

    s_bytes = pad32r(computation.msg.data[96:128])
    s = big_endian_to_int(s_bytes)

    try:
        validate_lt_secpk1n(r, title="ECRecover: R")
        validate_lt_secpk1n(s, title="ECRecover: S")
        validate_lte(v, 28, title="ECRecover: V")
        validate_gte(v, 27, title="ECRecover: V")
    except ValidationError:
        return computation

    canonical_v = v - 27

    try:
        signature = keys.Signature(vrs=(canonical_v, r, s))
        public_key = signature.recover_public_key_from_msg_hash(message_hash)
    except BadSignature:
        return computation

    address = public_key.to_canonical_address()
    padded_address = pad32(address)

    computation.output = padded_address
    return computation
Пример #25
0
def test_get_witness_nodes(populated_shard_chaindb_and_root_hash):
    chaindb, root_hash = populated_shard_chaindb_and_root_hash
    header = CollationHeader(
        shard_id=1,
        expected_period_number=0,
        period_start_prevhash=ZERO_HASH32,
        parent_hash=ZERO_HASH32,
        number=0,
        state_root=root_hash
    )

    prefixes = [
        get_balance_key(A_ADDRESS),
        get_balance_key(B_ADDRESS),
        get_storage_key(A_ADDRESS, big_endian_to_int(b"key1")),
        get_storage_key(B_ADDRESS, big_endian_to_int(b"key1")),
        get_storage_key(B_ADDRESS, big_endian_to_int(b"key2")),
        get_storage_key(B_ADDRESS, big_endian_to_int(b"key")),
        get_storage_key(B_ADDRESS, big_endian_to_int(b"")),
    ]

    witness_nodes = chaindb.get_witness_nodes(header, prefixes)
    assert len(witness_nodes) == len(set(witness_nodes))  # no duplicates
    assert sorted(witness_nodes) == sorted(witness_nodes)  # sorted
Пример #26
0
def print_var(value, var_typ):

    if isinstance(value, int):
        v = int_to_big_endian(value)
    else:
        v = value

    if isinstance(v, bytes):
        if var_typ == 'uint256':
            print(big_endian_to_int(v))
        elif var_typ == 'int128':
            print('TODO!')
        elif var_typ == 'address':
            print(to_hex(v[12:]))
    else:
        print(v)
Пример #27
0
def _extract_point(data_slice):
    x1_bytes = data_slice[:32]
    y1_bytes = data_slice[32:64]
    x2_i_bytes = data_slice[64:96]
    x2_r_bytes = data_slice[96:128]
    y2_i_bytes = data_slice[128:160]
    y2_r_bytes = data_slice[160:192]

    x1 = big_endian_to_int(x1_bytes)
    y1 = big_endian_to_int(y1_bytes)
    x2_i = big_endian_to_int(x2_i_bytes)
    x2_r = big_endian_to_int(x2_r_bytes)
    y2_i = big_endian_to_int(y2_i_bytes)
    y2_r = big_endian_to_int(y2_r_bytes)

    return x1, y1, x2_i, x2_r, y2_i, y2_r
Пример #28
0
def _extract_point(data_slice):
    x1_bytes = data_slice[:32]
    y1_bytes = data_slice[32:64]
    x2_i_bytes = data_slice[64:96]
    x2_r_bytes = data_slice[96:128]
    y2_i_bytes = data_slice[128:160]
    y2_r_bytes = data_slice[160:192]

    x1 = big_endian_to_int(x1_bytes)
    y1 = big_endian_to_int(y1_bytes)
    x2_i = big_endian_to_int(x2_i_bytes)
    x2_r = big_endian_to_int(x2_r_bytes)
    y2_i = big_endian_to_int(y2_i_bytes)
    y2_r = big_endian_to_int(y2_r_bytes)

    return x1, y1, x2_i, x2_r, y2_i, y2_r
Пример #29
0
 def _pop(self, num_items, type_hint):
     for _ in range(num_items):
         if type_hint == constants.UINT256:
             value = self.values.pop()
             if isinstance(value, int):
                 yield value
             else:
                 yield big_endian_to_int(value)
         elif type_hint == constants.BYTES:
             value = self.values.pop()
             if isinstance(value, bytes):
                 yield value
             else:
                 yield int_to_big_endian(value)
         elif type_hint == constants.ANY:
             yield self.values.pop()
         else:
             raise TypeError(
                 "Unknown type_hint: {0}.  Must be one of {1}".format(
                     type_hint,
                     ", ".join((constants.UINT256, constants.BYTES)),
                 ))
Пример #30
0
 def _pop(self, num_items, type_hint):
     for _ in range(num_items):
         if type_hint == constants.UINT256:
             value = self.values.pop()
             if isinstance(value, int):
                 yield value
             else:
                 yield big_endian_to_int(value)
         elif type_hint == constants.BYTES:
             value = self.values.pop()
             if isinstance(value, bytes):
                 yield value
             else:
                 yield int_to_big_endian(value)
         elif type_hint == constants.ANY:
             yield self.values.pop()
         else:
             raise TypeError(
                 "Unknown type_hint: {0}.  Must be one of {1}".format(
                     type_hint,
                     ", ".join((constants.UINT256, constants.BYTES)),
                 )
             )
Пример #31
0
 def from_endpoint(cls, ip, udp_port, tcp_port='\x00\x00'):
     udp_port = big_endian_to_int(udp_port)
     tcp_port = big_endian_to_int(tcp_port)
     return cls(ip, udp_port, tcp_port)
Пример #32
0
from evm.utils.hexadecimal import (
    decode_hex,
)
from evm.utils.numeric import (
    big_endian_to_int,
)


# S <= N // 2
MAX_ALLOWED_S = SECPK1_N // 2
VALIDATION_CODE_GAS = 3500
GAS_RESERVE = 4500  # amount of gas reserved for returning
GAS_RESERVE_OFFSET = 200
# standard id for a method with signature `get_nonce()`
NONCE_GETTER_ID = 0x141b5b48
ENTRY_POINT_INT = big_endian_to_int(ENTRY_POINT)

ECRECOVER_ADDRESS = 1
ECRECOVER_GAS = 3000

# calldata locations
CALLDATA_FUNCTION_ID = 0
CALLDATA_SIGNATURE = 0
(
    CALLDATA_V,
    CALLDATA_R,
    CALLDATA_S,
    CALLDATA_NONCE,
    CALLDATA_GASPRICE,
    CALLDATA_VALUE,
    CALLDATA_MIN_BLOCK,
Пример #33
0
def gen_request_id():
    return big_endian_to_int(os.urandom(8))
Пример #34
0
 def recv_find_node(self, node: kademlia.Node, payload: List[Any], _: bytes) -> None:
     # The find_node payload should have 2 elements: node_id, expiration
     self.logger.debug('<<< find_node from %s', node)
     node_id, _ = payload
     self.kademlia.recv_find_node(node, big_endian_to_int(node_id))
Пример #35
0
 def recv_find_node(self, node, payload, message_hash):
     # The find_node payload should have 2 elements: node_id, expiration
     self.logger.debug('<<< find_node from {}'.format(node))
     node_id, _ = payload
     self.kademlia.recv_find_node(node, big_endian_to_int(node_id))
Пример #36
0
 def __init__(self, pubkey: datatypes.PublicKey, address: Address) -> None:
     self.pubkey = pubkey
     self.address = address
     self.id = big_endian_to_int(keccak(pubkey.to_bytes()))
Пример #37
0
 def from_endpoint(cls, ip: str, udp_port: str, tcp_port: str = '\x00\x00'):
     return cls(ip, big_endian_to_int(udp_port),
                big_endian_to_int(tcp_port))
Пример #38
0
def gen_request_id() -> int:
    return big_endian_to_int(os.urandom(8))
Пример #39
0
 def __init__(self, pubkey, address):
     self.pubkey = pubkey
     self.address = address
     self.id = big_endian_to_int(keccak(pubkey.to_bytes()))