Beispiel #1
0
def dict_to_spoof_transaction(
        chain: AsyncChainAPI, header: BlockHeaderAPI,
        transaction_dict: Dict[str, Any]) -> SignedTransactionAPI:
    """
    Convert dicts used in calls & gas estimates into a spoof transaction
    """
    txn_dict = normalize_transaction_dict(transaction_dict)
    sender = txn_dict.get('from', ZERO_ADDRESS)

    if 'nonce' in txn_dict:
        nonce = txn_dict['nonce']
    else:
        vm = chain.get_vm(header)
        nonce = vm.state.get_nonce(sender)

    gas_price = txn_dict.get('gasPrice', 0)
    gas = txn_dict.get('gas', header.gas_limit)

    unsigned = chain.get_vm_class(header).create_unsigned_transaction(
        nonce=nonce,
        gas_price=gas_price,
        gas=gas,
        to=txn_dict['to'],
        value=txn_dict['value'],
        data=txn_dict['data'],
    )
    return cast(SignedTransactionAPI, SpoofTransaction(unsigned, from_=sender))
Beispiel #2
0
async def state_at_block(
        chain: AsyncChainAPI,
        at_block: Union[str, int],
        read_only: bool = True) -> StateAPI:
    at_header = await get_header(chain, at_block)
    vm = chain.get_vm(at_header)
    return vm.state
Beispiel #3
0
async def get_header(chain: AsyncChainAPI,
                     at_block: Union[str, int]) -> BlockHeaderAPI:
    if at_block == 'pending':
        raise NotImplementedError(
            "RPC interface does not support the 'pending' block at this time")
    elif at_block == 'latest':
        at_header = chain.get_canonical_head()
    elif at_block == 'earliest':
        # TODO find if genesis block can be non-zero. Why does 'earliest' option even exist?
        block = await chain.coro_get_canonical_block_by_number(BlockNumber(0))
        at_header = block.header
    # mypy doesn't have user defined type guards yet
    # https://github.com/python/mypy/issues/5206
    elif is_integer(at_block) and at_block >= 0:  # type: ignore
        block = await chain.coro_get_canonical_block_by_number(
            BlockNumber(int(at_block)))
        at_header = block.header
    else:
        raise TypeError("Unrecognized block reference: %r" % at_block)

    return at_header
Beispiel #4
0
def block_to_dict(block: BlockAPI, chain: AsyncChainAPI,
                  include_transactions: bool) -> RpcBlockResponse:

    # There doesn't seem to be a type safe way to initialize the RpcBlockResponse from
    # a RpcHeaderResponse + the extra fields hence the cast here.
    response = cast(RpcBlockResponse, header_to_dict(block.header))

    if include_transactions:
        txs: Union[Sequence[str], Sequence[RpcBlockTransactionResponse]] = [
            block_transaction_to_dict(tx, block.header)
            for tx in block.transactions
        ]
    else:
        txs = [encode_hex(tx.hash) for tx in block.transactions]

    response['totalDifficulty'] = hex(chain.get_score(block.hash))
    response['uncles'] = [encode_hex(uncle.hash) for uncle in block.uncles]
    response['size'] = hex(len(rlp.encode(block)))
    response['transactions'] = txs

    return response
Beispiel #5
0
def block_to_dict(
        block: BlockAPI, chain: AsyncChainAPI,
        include_transactions: bool) -> Dict[str, Union[str, List[str]]]:

    header_dict = header_to_dict(block.header)

    block_dict: Dict[str, Union[str, List[str]]] = dict(
        header_dict,
        totalDifficulty=hex(chain.get_score(block.hash)),
        uncles=[encode_hex(uncle.hash) for uncle in block.uncles],
        size=hex(len(rlp.encode(block))),
    )

    if include_transactions:
        # block_dict['transactions'] = map(transaction_to_dict, block.transactions)
        raise NotImplementedError(
            "Cannot return transaction object with block, yet")
    else:
        block_dict['transactions'] = [
            encode_hex(tx.hash) for tx in block.transactions
        ]

    return block_dict
Beispiel #6
0
async def check_requested_block_age(chain: AsyncChainAPI, func: Func,
                                    params: Any) -> BlockHeaderAPI:
    """
    :return: the reference header used for the data lookup.
    """
    sig = inspect.signature(func)
    params = sig.bind(*params)

    try:
        at_block_name = getattr(func, AT_BLOCK_ATTRIBUTE_NAME)
    except AttributeError as e:
        raise Exception(
            "Function {func} was not decorated with @retryable") from e

    at_block = to_int_if_hex(params.arguments[at_block_name])

    requested_header = await get_header(chain, at_block)
    requested_block = requested_header.block_number
    current_block = chain.get_canonical_head().block_number
    if requested_block < current_block - 64:
        raise Exception(
            f'block "{at_block}" is too old to be fetched over the network')
    else:
        return requested_header