parent
81947d796b
commit
346385680e
@ -795,19 +795,27 @@ class Controller(ServerBase):
|
||||
hashX = self.address_to_hashX(address)
|
||||
raise RPCError('address.get_proof is not yet implemented')
|
||||
|
||||
async def hashX_listunspent(self, hashX):
|
||||
'''Return the list of UTXOs of a script hash.
|
||||
|
||||
We should remove mempool spends from the in-DB UTXOs.'''
|
||||
utxos = await self.get_utxos(hashX)
|
||||
spends = await self.mempool.spends(hashX)
|
||||
|
||||
return [{'tx_hash': hash_to_str(utxo.tx_hash), 'tx_pos': utxo.tx_pos,
|
||||
'height': utxo.height, 'value': utxo.value}
|
||||
for utxo in sorted(utxos)
|
||||
if (utxo.tx_hash, utxo.tx_pos) not in spends]
|
||||
|
||||
async def address_listunspent(self, address):
|
||||
'''Return the list of UTXOs of an address.'''
|
||||
hashX = self.address_to_hashX(address)
|
||||
return [{'tx_hash': hash_to_str(utxo.tx_hash), 'tx_pos': utxo.tx_pos,
|
||||
'height': utxo.height, 'value': utxo.value}
|
||||
for utxo in sorted(await self.get_utxos(hashX))]
|
||||
return await self.hashX_listunspent(hashX)
|
||||
|
||||
async def scripthash_listunspent(self, scripthash):
|
||||
'''Return the list of UTXOs of a scripthash.'''
|
||||
hashX = self.scripthash_to_hashX(scripthash)
|
||||
return [{'tx_hash': hash_to_str(utxo.tx_hash), 'tx_pos': utxo.tx_pos,
|
||||
'height': utxo.height, 'value': utxo.value}
|
||||
for utxo in sorted(await self.get_utxos(hashX))]
|
||||
return await self.hashX_listunspent(hashX)
|
||||
|
||||
def block_get_header(self, height):
|
||||
'''The deserialized header at a given height.
|
||||
|
||||
@ -260,21 +260,30 @@ class MemPool(util.LoggedClass):
|
||||
|
||||
return result, deferred
|
||||
|
||||
async def raw_transactions(self, hashX):
|
||||
'''Returns an iterable of (hex_hash, raw_tx) pairs for all
|
||||
transactions in the mempool that touch hashX.
|
||||
|
||||
raw_tx can be None if the transaction has left the mempool.
|
||||
'''
|
||||
# hashXs is a defaultdict
|
||||
if hashX not in self.hashXs:
|
||||
return []
|
||||
|
||||
hex_hashes = self.hashXs[hashX]
|
||||
raw_txs = await self.daemon.getrawtransactions(hex_hashes)
|
||||
return zip(hex_hashes, raw_txs)
|
||||
|
||||
async def transactions(self, hashX):
|
||||
'''Generate (hex_hash, tx_fee, unconfirmed) tuples for mempool
|
||||
entries for the hashX.
|
||||
|
||||
unconfirmed is True if any txin is unconfirmed.
|
||||
'''
|
||||
# hashXs is a defaultdict
|
||||
if hashX not in self.hashXs:
|
||||
return []
|
||||
|
||||
deserializer = self.coin.DESERIALIZER
|
||||
hex_hashes = self.hashXs[hashX]
|
||||
raw_txs = await self.daemon.getrawtransactions(hex_hashes)
|
||||
pairs = await self.raw_transactions(hashX)
|
||||
result = []
|
||||
for hex_hash, raw_tx in zip(hex_hashes, raw_txs):
|
||||
for hex_hash, raw_tx in pairs:
|
||||
item = self.txs.get(hex_hash)
|
||||
if not item or not raw_tx:
|
||||
continue
|
||||
@ -287,6 +296,23 @@ class MemPool(util.LoggedClass):
|
||||
result.append((hex_hash, tx_fee, unconfirmed))
|
||||
return result
|
||||
|
||||
async def spends(self, hashX):
|
||||
'''Return a set of (prev_hash, prev_idx) pairs from mempool
|
||||
transactions that touch hashX.
|
||||
|
||||
None, some or all of these may be spends of the hashX.
|
||||
'''
|
||||
deserializer = self.coin.DESERIALIZER
|
||||
pairs = await self.raw_transactions(hashX)
|
||||
spends = set()
|
||||
for hex_hash, raw_tx in pairs:
|
||||
if not raw_tx:
|
||||
continue
|
||||
tx, tx_hash = deserializer(raw_tx).read_tx()
|
||||
for txin in tx.inputs:
|
||||
spends.add((txin.prev_hash, txin.prev_idx))
|
||||
return spends
|
||||
|
||||
def value(self, hashX):
|
||||
'''Return the unconfirmed amount in the mempool for hashX.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user