コード例 #1
0
def txid_to_block_data(txid, bitcoind_proxy, proxy=None):
    """
    Given a txid, get its block's data.

    Use SPV to verify the information we receive from the (untrusted)
    bitcoind host.

    @bitcoind_proxy must be a BitcoindConnection (from virtualchain.lib.session)

    Return the (block hash, block data, txdata) on success
    Return (None, None, None) on error
    """

    proxy = get_default_proxy() if proxy is None else proxy

    timeout = 1.0
    while True:
        try:
            untrusted_tx_data = bitcoind_proxy.getrawtransaction(txid, 1)
            untrusted_block_hash = untrusted_tx_data['blockhash']
            untrusted_block_data = bitcoind_proxy.getblock(
                untrusted_block_hash)
            break
        except (OSError, IOError) as ie:
            log.exception(ie)
            log.error('Network error; retrying...')
            timeout = timeout * 2 + random.randint(0, timeout)
            continue
        except Exception as e:
            log.exception(e)
            return None, None, None

    # first, can we trust this block? is it in the SPV headers?
    untrusted_block_header_hex = virtualchain.block_header_to_hex(
        untrusted_block_data, untrusted_block_data['previousblockhash'])

    block_id = SPVClient.block_header_index(
        proxy.spv_headers_path,
        ('{}00'.format(untrusted_block_header_hex)).decode('hex'))

    if block_id < 0:
        # bad header
        log.error('Block header "{}" is not in the SPV headers ({})'.format(
            untrusted_block_header_hex, proxy.spv_headers_path))

        return None, None, None

    # block header is trusted.  Is the transaction data consistent with it?
    verified_block_header = virtualchain.block_verify(untrusted_block_data)

    if not verified_block_header:
        msg = ('Block transaction IDs are not consistent '
               'with the Merkle root of the trusted header')

        log.error(msg)

        return None, None, None

    # verify block hash
    verified_block_hash = virtualchain.block_header_verify(
        untrusted_block_data, untrusted_block_data['previousblockhash'],
        untrusted_block_hash)

    if not verified_block_hash:
        log.error('Block hash is not consistent with block header')
        return None, None, None

    # we trust the block hash, block data, and txids
    block_hash = untrusted_block_hash
    block_data = untrusted_block_data
    tx_data = untrusted_tx_data

    return block_hash, block_data, tx_data
コード例 #2
0
            break
        except (OSError, IOError), ie:
            log.exception(ie)
            log.error("Network error; retrying...")
            timeout = timeout * 2 + random.randint(0, timeout)
            continue

        except Exception, e:
            log.exception(e)
            return (None, None, None)

    # first, can we trust this block? is it in the SPV headers?
    untrusted_block_header_hex = virtualchain.block_header_to_hex(
        untrusted_block_data, untrusted_block_data['previousblockhash'])
    block_id = SPVClient.block_header_index(proxy.spv_headers_path,
                                            (untrusted_block_header_hex +
                                             "00").decode('hex'))
    if block_id < 0:
        # bad header
        log.error("Block header '%s' is not in the SPV headers (%s)" %
                  (untrusted_block_header_hex, proxy.spv_headers_path))
        return (None, None, None)

    # block header is trusted.  Is the transaction data consistent with it?
    if not virtualchain.block_verify(untrusted_block_data):
        log.error(
            "Block transaction IDs are not consistent with the trusted header's Merkle root"
        )
        return (None, None, None)

    # verify block hash