示例#1
0
async def _add_diff_change(headers: List[RelayHeader]) -> None:
    print('Diff change')
    nonce = next(shared.NONCE)
    logger.info(f'\ndiff change {len(headers)} new headers,\n'
                f'first is {utils.format_header(headers[0])}\n'
                f'last is {utils.format_header(headers[-1])}\n')

    epoch_start = headers[0]['height'] - 2016
    old_start_or_none, old_end_or_none = await asyncio.gather(
        bcoin_rpc.get_header_by_height(epoch_start),
        bcoin_rpc.get_header_by_height(epoch_start + 2015),
    )

    # we know these casts won't fail
    old_start = cast(RelayHeader, old_start_or_none)
    old_end = cast(RelayHeader, old_end_or_none)
    logger.debug(f'old start is {old_start["hash_le"].hex()}')
    logger.debug(f'old end is {old_end["hash_le"].hex()}')

    headers_hex = ''.join(h['raw'].hex() for h in headers)

    tx = shared.make_call_tx(
        contract=config.get()['CONTRACT'],
        abi=relay_ABI,
        method='addHeadersWithRetarget',
        args=[old_start["raw"], old_end["raw"], headers_hex],
        nonce=nonce)

    asyncio.create_task(shared.sign_and_broadcast(tx))
示例#2
0
async def _update_best_digest(new_best: RelayHeader) -> None:
    '''Send an ethereum transaction that marks a new best known chain tip'''
    nonce = next(shared.NONCE)
    will_succeed = False

    while not will_succeed:
        current_best_digest = await contract.get_best_block()
        current_best = cast(
            RelayHeader, await
            bcoin_rpc.get_header_by_hash(current_best_digest))

        delta = new_best['height'] - current_best['height'] + 1
        # find the latest block in current's history that is an ancestor of new
        is_ancestor = False
        ancestor = current_best
        originalAncestor = ancestor
        counter = 0
        while True:
            is_ancestor = await contract.is_ancestor(ancestor['hash_le'],
                                                     new_best['hash_le'])
            if is_ancestor:
                counter = 0
                break
            ancestor = cast(
                RelayHeader, await
                bcoin_rpc.get_header_by_hash(ancestor['prevhash']))
            counter = counter + 1
            if counter > 200:
                ancestor = originalAncestor
                counter = 0

        ancestor_le = ancestor['hash_le']

        tx = shared.make_call_tx(
            contract=config.get()['CONTRACT'],
            abi=relay_ABI,
            method='markNewHeaviest',
            args=[ancestor_le, current_best["raw"], new_best["raw"], delta],
            nonce=nonce)
        try:
            result = await shared.CONNECTION.preflight_tx(
                tx, sender=config.get()['ETH_ADDRESS'])
        except RuntimeError:
            await asyncio.sleep(10)
            continue
        will_succeed = bool(int(result, 16))
        if not will_succeed:
            await asyncio.sleep(10)

    logger.info(f'\nmarking new best\n'
                f'LCA is {ancestor["hash"].hex()}\n'
                f'previous best was {utils.format_header(current_best)}\n'
                f'new best is {utils.format_header(new_best)}\n')

    asyncio.create_task(shared.sign_and_broadcast(tx))
示例#3
0
async def _add_headers(headers: List[RelayHeader]) -> None:
    logger.info(f'\nsending {len(headers)} new headers\n'
                f'first is {utils.format_header(headers[0])}\n'
                f'last is {utils.format_header(headers[-1])}\n')
    nonce = next(shared.NONCE)
    anchor_or_none = await bcoin_rpc.get_header_by_hash(
        headers[0]['prevhash'].hex())
    anchor = cast(RelayHeader, anchor_or_none)

    headers_hex = ''.join(h['raw'].hex() for h in headers)

    tx = shared.make_call_tx(contract=config.get()['CONTRACT'],
                             abi=relay_ABI,
                             method='addHeaders',
                             args=[anchor["raw"], headers_hex],
                             nonce=nonce)
    asyncio.create_task(shared.sign_and_broadcast(tx))