Пример #1
0
 def read_utxos():
     utxos = []
     utxos_append = utxos.append
     # Key: b'u' + address_hashX + tx_idx + tx_num
     # Value: the UTXO value as a 64-bit unsigned integer
     prefix = b'u' + hashX
     for db_key, db_value in self.utxo_db.iterator(prefix=prefix):
         tx_pos, = unpack_le_uint32(db_key[-9:-5])
         tx_num, = unpack_le_uint64(db_key[-5:] + bytes(3))
         value, = unpack_le_uint64(db_value)
         tx_hash, height = self.fs_tx_hash(tx_num)
         utxos_append(UTXO(tx_num, tx_pos, tx_hash, height, value))
     return utxos
Пример #2
0
 def read_utxos():
     utxos = []
     utxos_append = utxos.append
     txnum_padding = bytes(8-TXNUM_LEN)
     # Key: b'u' + address_hashX + txout_idx + tx_num
     # Value: the UTXO value as a 64-bit unsigned integer
     prefix = b'u' + hashX
     for db_key, db_value in self.utxo_db.iterator(prefix=prefix):
         txout_idx, = unpack_le_uint32(db_key[-TXNUM_LEN-4:-TXNUM_LEN])
         tx_num, = unpack_le_uint64(db_key[-TXNUM_LEN:] + txnum_padding)
         value, = unpack_le_uint64(db_value)
         tx_hash, height = self.fs_tx_hash(tx_num)
         utxos_append(UTXO(tx_num, txout_idx, tx_hash, height, value))
     return utxos
Пример #3
0
    def spend_utxo(self, tx_hash, tx_idx, spend_tx_hash):
        '''Spend a UTXO and return the 33-byte value.

        If the UTXO is not in the cache it must be on disk.  We store
        all UTXOs so not finding one indicates a logic error or DB
        corruption.
        '''
        # Fast track is it being in the cache
        idx_packed = pack_le_uint32(tx_idx)
        cache_value = self.utxo_cache.pop(tx_hash + idx_packed, None)
        if cache_value:
            return cache_value

        # Spend it from the DB.

        # Key: b'h' + compressed_tx_hash + tx_idx + tx_num
        # Value: hashX
        prefix = b'h' + tx_hash[:4] + idx_packed
        candidates = {
            db_key: hashX
            for db_key, hashX in self.db.utxo_db.iterator(prefix=prefix)
        }

        for hdb_key, hashX in candidates.items():
            tx_num_packed = hdb_key[-4:]

            if len(candidates) > 1:
                tx_num, = unpack_le_uint32(tx_num_packed)
                hash, _height = self.db.fs_tx_hash(tx_num)
                if hash != tx_hash:
                    assert hash is not None  # Should always be found
                    continue

            # Key: b'u' + address_hashX + tx_idx + tx_num
            # Value: the UTXO value as a 64-bit unsigned integer
            udb_key = b'u' + hashX + hdb_key[-8:]
            utxo_value_packed = self.db.utxo_db.get(udb_key)
            if utxo_value_packed:
                # Remove both entries for this UTXO
                self.db_deletes.append(hdb_key)
                self.db_deletes.append(udb_key)
                return hashX + tx_num_packed + utxo_value_packed

        if spend_tx_hash in self.dup_tx_hashes:
            return None
        raise ChainError(
            'UTXO {}:{:,d} not found in "h" table at height {}, spend tx {}'.
            format(hash_to_hex_str(tx_hash), tx_idx, self.height,
                   hash_to_hex_str(spend_tx_hash)))
Пример #4
0
            def lookup_hashX(tx_hash, tx_idx):
                idx_packed = pack_le_uint32(tx_idx)

                # Key: b'h' + compressed_tx_hash + tx_idx + tx_num
                # Value: hashX
                prefix = b'h' + tx_hash[:4] + idx_packed

                # Find which entry, if any, the TX_HASH matches.
                for db_key, hashX in self.utxo_db.iterator(prefix=prefix):
                    tx_num_packed = db_key[-4:]
                    tx_num, = unpack_le_uint32(tx_num_packed)
                    hash, _height = self.fs_tx_hash(tx_num)
                    if hash == tx_hash:
                        return hashX, idx_packed + tx_num_packed
                return None, None
Пример #5
0
 def read_utxos():
     utxos = []
     utxos_append = utxos.append
     # Key: b'u' + address_hashX + tx_num + txout_idx
     # Value: the UTXO value as a 64-bit unsigned integer
     prefix = b'u' + hashX
     for db_key, db_value in self.utxo_db.iterator(prefix=prefix):
         txout_idx, = unpack_le_uint32(db_key[-TXOUTIDX_LEN:] +
                                       TXOUTIDX_PADDING)
         tx_numb = db_key[-TXOUTIDX_LEN - TXNUM_LEN:-TXOUTIDX_LEN]
         tx_num = unpack_txnum(tx_numb)
         value, = unpack_le_uint64(db_value)
         tx_hash, height = self.fs_tx_hash(tx_num)
         utxos_append(UTXO(tx_num, txout_idx, tx_hash, height, value))
     return utxos
Пример #6
0
 def date_str(self):
     timestamp, = unpack_le_uint32(self.header[68:72])
     return datetime.utcfromtimestamp(timestamp).strftime(
         '%Y-%m-%d %H:%M:%S')