Esempio n. 1
0
def make_timestamp_from_block(digest, block, blockheight, *, max_tx_size=1000):
    """Make a timestamp for a digest from a block

    Returns a timestamp for that digest on success, None on failure
    """
    # Find the smallest transaction containing the root digest

    # FIXME: note how strategy changes once we add SHA256 midstate support
    len_smallest_tx_found = max_tx_size + 1
    commitment_tx = None
    prefix = None
    suffix = None
    for tx in block.vtx:
        serialized_tx = tx.serialize()

        if len(serialized_tx) > len_smallest_tx_found:
            continue

        try:
            i = serialized_tx.index(digest)
        except ValueError:
            continue

        # Found it!
        commitment_tx = tx
        prefix = serialized_tx[0:i]
        suffix = serialized_tx[i + len(digest):]

        len_smallest_tx_found = len(serialized_tx)

    if len_smallest_tx_found > max_tx_size:
        return None

    digest_timestamp = Timestamp(digest)

    # Add the commitment ops necessary to go from the digest to the txid op
    prefix_stamp = digest_timestamp.ops.add(OpPrepend(prefix))
    txid_stamp = cat_sha256d(prefix_stamp, suffix)

    assert commitment_tx.GetHash() == txid_stamp.msg

    # Create the txid list, with our commitment txid op in the appropriate
    # place
    block_txid_stamps = []
    for tx in block.vtx:
        if tx.GetHash() != txid_stamp.msg:
            block_txid_stamps.append(Timestamp(tx.GetHash()))
        else:
            block_txid_stamps.append(txid_stamp)

    # Build the merkle tree
    merkleroot_stamp = __make_btc_block_merkle_tree(block_txid_stamps)

    attestation = BitcoinBlockHeaderAttestation(blockheight)
    merkleroot_stamp.attestations.add(attestation)

    return digest_timestamp
Esempio n. 2
0
    def submit(self, submitted_commitment):
        idx = int(time.time())

        serialized_idx = struct.pack('>L', idx)

        commitment = submitted_commitment.ops.add(OpPrepend(serialized_idx))

        per_idx_key = derive_key_for_idx(self.hmac_key, idx, bits=32)
        mac = hashlib.sha256(commitment.msg + per_idx_key).digest()[0:HMAC_SIZE]
        macced_commitment = commitment.ops.add(OpAppend(mac))

        macced_commitment.attestations.add(PendingAttestation(self.uri))
        self.journal.submit(macced_commitment.msg)
def make_timestamp_from_block_tx(confirmed_tx, block, blockheight):

    commitment_tx = confirmed_tx.tx
    serialized_tx = commitment_tx.serialize(params={'include_witness': False})
    digest = confirmed_tx.tip_timestamp.msg

    try:
        i = serialized_tx.index(digest)
    except ValueError:
        assert False, "can't build a block_timestamp from my tx, this is not supposed to happen, exiting"

    prefix = serialized_tx[0:i]
    suffix = serialized_tx[i + len(digest):]

    digest_timestamp = Timestamp(digest)

    # Add the commitment ops necessary to go from the digest to the txid op
    prefix_stamp = digest_timestamp.ops.add(OpPrepend(prefix))
    txid_stamp = cat_sha256d(prefix_stamp, suffix)

    assert commitment_tx.GetTxid() == txid_stamp.msg

    # Create the txid list, with our commitment txid op in the appropriate
    # place
    block_txid_stamps = []
    for tx in block.vtx:
        if tx.GetTxid() != txid_stamp.msg:
            block_txid_stamps.append(Timestamp(tx.GetTxid()))
        else:
            block_txid_stamps.append(txid_stamp)

    # Build the merkle tree
    merkleroot_stamp = make_btc_block_merkle_tree(block_txid_stamps)
    assert merkleroot_stamp.msg == block.hashMerkleRoot

    if bitcoin.params.NAME.lower() == "testnet":
        attestation = BitcoinTestnetBlockHeaderAttestation(blockheight)
    else:
        attestation = BitcoinBlockHeaderAttestation(blockheight)
    merkleroot_stamp.attestations.add(attestation)

    return digest_timestamp
 def upgrade_timestamps_tx(self, tx):
     for category, script, amount in tx.outputs():
         if category == 2:  # agt -> txid
             agt = script[4:]  # drop "6a20" op_return and op_pushdata(32)
             tx_raw = tx.serialize(witness=False)
             if len(x(tx_raw)) <= Op.MAX_MSG_LENGTH:
                 i = tx_raw.find(agt)
                 prepend = x(tx_raw[:i])
                 append = x(tx_raw[i + len(agt):])
                 t_agt = Timestamp(x(agt))
                 t = t_agt.ops.add(OpPrepend(prepend))
                 t = t.ops.add(OpAppend(append))
                 t = t.ops.add(OpSHA256())
                 t = t.ops.add(OpSHA256())  # txid in little endian
                 for f in self.proofs_storage_file.incomplete_proofs:
                     tf = roll_timestamp(f.detached_timestamp.timestamp)
                     if tf.msg == x(agt):
                         tf.merge(t_agt)
                         f.status = "pending"
                         f.txid = t.msg[::-1].hex()
     self.update_storage()
Esempio n. 5
0
def cat_then_unary_op(unary_op_cls, left, right):
    """Concatenate left and right, then perform a unary operation on them

    left and right can be either timestamps or bytes.

    Appropriate intermediary append/prepend operations will be created as
    needed for left and right.
    """
    if not isinstance(left, Timestamp):
        left = Timestamp(left)

    if not isinstance(right, Timestamp):
        right = Timestamp(right)

    left_append_stamp = left.ops.add(OpAppend(right.msg))
    right_prepend_stamp = right.ops.add(OpPrepend(left.msg))

    # Left and right should produce the same thing, so we can set the timestamp
    # of the left to the right.
    left.ops[OpAppend(right.msg)] = right_prepend_stamp

    return right_prepend_stamp.ops.add(unary_op_cls())
def make_timestamp_from_block(digest, block, blockheight, *, max_tx_size=1000):
    state = make_trie(block)
    my_root = state.root_hash
    block_root = bytes.fromhex(block['transactionsRoot'][2:])
    assert my_root == block_root

    try:
        j, prepend_tx, append_tx = found_tx(digest, block, max_tx_size)
    except ValueError:
        return None
    tx_raw = prepend_tx + digest + append_tx
    # print("tx_raw: " + tx_raw)
    # print("tx_hash: " + sha3.keccak_256(bytes.fromhex(tx_raw)).hexdigest())

    rlp_encode = rlp.encode(j)
    # print("rlp_encode: " + bytes.hex(rlp_encode))
    nibbles = trie.bin_to_nibbles(rlp_encode)
    current_node = state.root_node
    ops_list = []
    nibble_iter = nibbles.__iter__()

    while True:
        node_type = state._get_node_type(current_node)
        # print("node type: " + str(node_type))
        # print([bytes.hex(cur_el) for cur_el in current_node])
        current_node_rlp = rlp.encode(current_node)
        current_node_encoded = bytes.hex(current_node_rlp)
        # print(current_node_encoded)
        try:
            index = next(nibble_iter)
        except:
            pass

        current_el = current_node[index if node_type == trie.NODE_TYPE_BRANCH else 1]
        current_el_hex = bytes.hex(current_el)
        # print(str(index) + ":" + current_el_hex)
        [prepend, append] = get_append_and_prepend(current_el_hex, current_node_encoded)

        ops_list.append(OpKECCAK256())
        if len(append) > 0:
            ops_list.append(OpAppend(bytes.fromhex(append)))
        if len(prepend) > 0:
            ops_list.append(OpPrepend(bytes.fromhex(prepend)))

        if node_type == trie.NODE_TYPE_LEAF:
            break
        else:
            current_node = state._decode_to_node(current_el)

    assert tx_raw == prepend_tx + digest + append_tx
    orig = Timestamp(bytes.fromhex(digest))
    current = orig
    if len(prepend_tx) > 0:
        current = current.ops.add(OpPrepend(bytes.fromhex(prepend_tx)))
    if len(append_tx) > 0:
        current = current.ops.add(OpAppend(bytes.fromhex(append_tx)))
    while len(ops_list) > 0:
        current = current.ops.add(ops_list.pop())
    attestation = EthereumBlockHeaderAttestation(blockheight)
    current.attestations.add(attestation)

    return orig
def make_timestamp_from_block(digest, block, blockheight, *, max_tx_size=1000):
    """Make a timestamp for a message in a block

    Every transaction within the block is serialized and checked to see if the
    raw serialized bytes contain the message. If one or more transactions do,
    the smallest transaction is used to create a timestamp proof for that
    specific message to the block header.

    To limit the maximum size of proof, transactions larger than `max_tx_size`
    are ignored.

    Returns a timestamp for that message on success, None on failure.
    """

    # Note how strategy changes if we add SHA256 midstate support
    len_smallest_tx_found = max_tx_size + 1
    commitment_tx = None
    prefix = None
    suffix = None
    for tx in block.vtx:
        serialized_tx = tx.serialize(params={'include_witness': False})

        if len(serialized_tx) > len_smallest_tx_found:
            continue

        try:
            i = serialized_tx.index(digest)
        except ValueError:
            continue

        # Found it!
        commitment_tx = tx
        prefix = serialized_tx[0:i]
        suffix = serialized_tx[i + len(digest):]

        len_smallest_tx_found = len(serialized_tx)

    if len_smallest_tx_found > max_tx_size:
        return None

    digest_timestamp = Timestamp(digest)

    # Add the commitment ops necessary to go from the digest to the txid op
    prefix_stamp = digest_timestamp.ops.add(OpPrepend(prefix))
    txid_stamp = cat_sha256d(prefix_stamp, suffix)

    assert commitment_tx.GetTxid() == txid_stamp.msg

    # Create the txid list, with our commitment txid op in the appropriate
    # place
    block_txid_stamps = []
    for tx in block.vtx:
        if tx.GetTxid() != txid_stamp.msg:
            block_txid_stamps.append(Timestamp(tx.GetTxid()))
        else:
            block_txid_stamps.append(txid_stamp)

    # Build the merkle tree
    merkleroot_stamp = __make_btc_block_merkle_tree(block_txid_stamps)
    assert merkleroot_stamp.msg == block.hashMerkleRoot

    attestation = BitcoinBlockHeaderAttestation(blockheight)
    merkleroot_stamp.attestations.add(attestation)

    return digest_timestamp