def mempool_add(self, tx): # Do not add if not fully synced if self.initial_sync: return # TODO: Transaction can get stuck in mempool if double-spent or RBF # TODO: Add expiry from mempool? e.g. x blocks, either indicates not accepted by the network or stuck in mempool due to another issue self.mempool.add(tx) timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') tx_parsed = self.parse_tx(timestamp, None, None, tx) Transaction.insert_many([tx_parsed]).execute(None) for vin in tx.vin: Utxo.update(spent=True).where((Utxo.txid == b2lx(vin.prevout.hash)) & (Utxo.vout == vin.prevout.n)).execute() external_sio.emit('tx', tx_parsed, room='inv')
def checkutxos(self, force=False): if force or self.utxo_changes > 10000: self.log.debug('Commit utxo changes') utxos = [] #wb.put(('pg_utxo_put:%s:%s' % (txid, vout)).encode(), ('%s:%s:%s:%s' % (address, value, scriptPubKey, blockHeight)).encode()) with self.db.write_batch(transaction=True) as deleteBatch: for key, value in self.db.iterator(prefix=b'pg_utxo_put:'): key_parts = key.decode().split(':') txid = key_parts[1] vout = key_parts[2] try: (address, value, scriptPubKey, blockHeight) = value.decode().split(':') except: raise utxos.append({ 'txid': txid, 'vout': vout, 'address': address, 'scriptPubKey': scriptPubKey, 'block_height': blockHeight, 'amount': value }) deleteBatch.delete(key) if utxos: Utxo.insert_many(utxos).execute(None) utxos = [] with self.db.write_batch(transaction=True) as deleteBatch: for key, value in self.db.iterator(prefix=b'pg_utxo_del:'): key_parts = key.decode().split(':') txid = key_parts[1] vout = key_parts[2] utxos.append('(\'%s\', %s)' % (txid, vout)) if utxos: # print('Deleting utxos') # print(utxos) # select * from utxo join (VALUES('TE8evzF3gZoRQozJgfNzekrv7uiBgKKFiE', '001239f17dde519a4fbadb71dda3725ef7474ab2995b6466e8c079dc5c2a7865:0')) AS t(addr, t) ON addr = address and txid_vout = t; q = 'DELETE FROM utxo WHERE id in (SELECT id FROM utxo JOIN (VALUES %s) AS t (t, v) ON t = txid AND v = vout)' % ','.join(utxos) #Utxo.delete().where(Utxo.txid_vout.in_(utxos)).execute() res = Utxo.raw(q).execute() self.utxo_changes = 0
async def read_address(address : str): try: record = Address.get(address=address) except: return HTMLResponse(status_code=404) res = record.to_dict() unconfirmed = 0 utxos = Utxo.select().where((Utxo.address == address) & (Utxo.spent == True)).execute() for utxo in utxos: unconfirmed += utxo.amount res['balance'] -= unconfirmed res['unconfirmed'] = unconfirmed return res
async def read_addrs_utxo(addresses : str): utxos = Utxo.select().where(Utxo.address.in_(addresses.split(','))) block = get_latest_block() return list(map(_utxo_map(block), utxos))
async def read_addr_utxos(address : str): utxos = Utxo.select().where((Utxo.address == address) & (Utxo.spent == False)) block = get_latest_block() return list(map(_utxo_map(block), utxos))