parent
81947d796b
commit
346385680e
@ -795,19 +795,27 @@ class Controller(ServerBase):
|
|||||||
hashX = self.address_to_hashX(address)
|
hashX = self.address_to_hashX(address)
|
||||||
raise RPCError('address.get_proof is not yet implemented')
|
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):
|
async def address_listunspent(self, address):
|
||||||
'''Return the list of UTXOs of an address.'''
|
'''Return the list of UTXOs of an address.'''
|
||||||
hashX = self.address_to_hashX(address)
|
hashX = self.address_to_hashX(address)
|
||||||
return [{'tx_hash': hash_to_str(utxo.tx_hash), 'tx_pos': utxo.tx_pos,
|
return await self.hashX_listunspent(hashX)
|
||||||
'height': utxo.height, 'value': utxo.value}
|
|
||||||
for utxo in sorted(await self.get_utxos(hashX))]
|
|
||||||
|
|
||||||
async def scripthash_listunspent(self, scripthash):
|
async def scripthash_listunspent(self, scripthash):
|
||||||
'''Return the list of UTXOs of a scripthash.'''
|
'''Return the list of UTXOs of a scripthash.'''
|
||||||
hashX = self.scripthash_to_hashX(scripthash)
|
hashX = self.scripthash_to_hashX(scripthash)
|
||||||
return [{'tx_hash': hash_to_str(utxo.tx_hash), 'tx_pos': utxo.tx_pos,
|
return await self.hashX_listunspent(hashX)
|
||||||
'height': utxo.height, 'value': utxo.value}
|
|
||||||
for utxo in sorted(await self.get_utxos(hashX))]
|
|
||||||
|
|
||||||
def block_get_header(self, height):
|
def block_get_header(self, height):
|
||||||
'''The deserialized header at a given height.
|
'''The deserialized header at a given height.
|
||||||
|
|||||||
@ -260,21 +260,30 @@ class MemPool(util.LoggedClass):
|
|||||||
|
|
||||||
return result, deferred
|
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):
|
async def transactions(self, hashX):
|
||||||
'''Generate (hex_hash, tx_fee, unconfirmed) tuples for mempool
|
'''Generate (hex_hash, tx_fee, unconfirmed) tuples for mempool
|
||||||
entries for the hashX.
|
entries for the hashX.
|
||||||
|
|
||||||
unconfirmed is True if any txin is unconfirmed.
|
unconfirmed is True if any txin is unconfirmed.
|
||||||
'''
|
'''
|
||||||
# hashXs is a defaultdict
|
|
||||||
if hashX not in self.hashXs:
|
|
||||||
return []
|
|
||||||
|
|
||||||
deserializer = self.coin.DESERIALIZER
|
deserializer = self.coin.DESERIALIZER
|
||||||
hex_hashes = self.hashXs[hashX]
|
pairs = await self.raw_transactions(hashX)
|
||||||
raw_txs = await self.daemon.getrawtransactions(hex_hashes)
|
|
||||||
result = []
|
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)
|
item = self.txs.get(hex_hash)
|
||||||
if not item or not raw_tx:
|
if not item or not raw_tx:
|
||||||
continue
|
continue
|
||||||
@ -287,6 +296,23 @@ class MemPool(util.LoggedClass):
|
|||||||
result.append((hex_hash, tx_fee, unconfirmed))
|
result.append((hex_hash, tx_fee, unconfirmed))
|
||||||
return result
|
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):
|
def value(self, hashX):
|
||||||
'''Return the unconfirmed amount in the mempool for hashX.
|
'''Return the unconfirmed amount in the mempool for hashX.
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user