new protocol method: blockchain.transaction.id_from_pos (#524)
This commit is contained in:
parent
60435c0c06
commit
c7f3f7ac6d
@ -133,6 +133,11 @@ Changes
|
||||
* Optional *cp_height* argument added to
|
||||
:func:`blockchain.block.header` and :func:`blockchain.block.headers`
|
||||
|
||||
New methods
|
||||
-----------
|
||||
|
||||
* :func:`blockchain.transaction.id_from_pos`
|
||||
|
||||
Removed methods
|
||||
---------------
|
||||
|
||||
|
||||
@ -671,6 +671,70 @@ and height.
|
||||
"pos": 710
|
||||
}
|
||||
|
||||
blockchain.transaction.id_from_pos
|
||||
==================================
|
||||
|
||||
Return a transaction hash and optionally a merkle proof,
|
||||
given a block height and a position in the block.
|
||||
|
||||
**Signature**
|
||||
|
||||
.. function:: blockchain.transaction.id_from_pos(height, tx_pos, merkle=False)
|
||||
.. versionadded:: 1.4
|
||||
|
||||
*height*
|
||||
|
||||
A block height in the main chain, an integer.
|
||||
|
||||
*tx_pos*
|
||||
|
||||
A zero-based index of the transaction in the given block, an integer.
|
||||
|
||||
*merkle*
|
||||
|
||||
Whether a merkle proof should also be returned, a boolean.
|
||||
|
||||
**Result**
|
||||
|
||||
If *merkle* is :const:`False`, the transaction hash as a hexadecimal string.
|
||||
If :const:`True`, a dictionary with the following keys:
|
||||
|
||||
* *tx_hash*
|
||||
|
||||
The transaction hash as a hexadecimal string.
|
||||
|
||||
* *merkle*
|
||||
|
||||
A list of transaction hashes the current hash is paired with,
|
||||
recursively, in order to trace up to obtain merkle root of the
|
||||
block, deepest pairing first.
|
||||
|
||||
**Example Results**
|
||||
|
||||
When *merkle* is :const:`False`::
|
||||
|
||||
"fc12dfcb4723715a456c6984e298e00c479706067da81be969e8085544b0ba08"
|
||||
|
||||
When *merkle* is :const:`True`::
|
||||
|
||||
{
|
||||
"tx_hash": "fc12dfcb4723715a456c6984e298e00c479706067da81be969e8085544b0ba08",
|
||||
"merkle":
|
||||
[
|
||||
"928c4275dfd6270349e76aa5a49b355eefeb9e31ffbe95dd75fed81d219a23f8",
|
||||
"5f35bfb3d5ef2ba19e105dcd976928e675945b9b82d98a93d71cbad0e714d04e",
|
||||
"f136bcffeeed8844d54f90fc3ce79ce827cd8f019cf1d18470f72e4680f99207",
|
||||
"6539b8ab33cedf98c31d4e5addfe40995ff96c4ea5257620dfbf86b34ce005ab",
|
||||
"7ecc598708186b0b5bd10404f5aeb8a1a35fd91d1febbb2aac2d018954885b1e",
|
||||
"a263aae6c470b9cde03b90675998ff6116f3132163911fafbeeb7843095d3b41",
|
||||
"c203983baffe527edb4da836bc46e3607b9a36fa2c6cb60c1027f0964d971b29",
|
||||
"306d89790df94c4632d652d142207f53746729a7809caa1c294b895a76ce34a9",
|
||||
"c0b4eff21eea5e7974fe93c62b5aab51ed8f8d3adad4583c7a84a98f9e428f04",
|
||||
"f0bd9d2d4c4cf00a1dd7ab3b48bbbb4218477313591284dcc2d7ca0aaa444e8d",
|
||||
"503d3349648b985c1b571f59059e4da55a57b0163b08cc50379d73be80c4c8f3"
|
||||
]
|
||||
}
|
||||
|
||||
mempool.get_fee_histogram
|
||||
=========================
|
||||
|
||||
|
||||
@ -1068,6 +1068,17 @@ class ElectrumX(SessionBase):
|
||||
block = await self.daemon_request('deserialised_block', block_hash)
|
||||
return block_hash, block['tx']
|
||||
|
||||
def _get_merkle_branch(self, tx_hashes, tx_pos):
|
||||
'''Return a merkle branch to a transaction.
|
||||
|
||||
tx_hashes: ordered list of hex strings of tx hashes in a block
|
||||
tx_pos: index of transaction in tx_hashes to create branch for
|
||||
'''
|
||||
hashes = [hex_str_to_hash(hash) for hash in tx_hashes]
|
||||
branch, root = self.bp.merkle.branch_and_root(hashes, tx_pos)
|
||||
branch = [hash_to_hex_str(hash) for hash in branch]
|
||||
return branch
|
||||
|
||||
async def transaction_merkle(self, tx_hash, height):
|
||||
'''Return the markle tree to a confirmed transaction given its hash
|
||||
and height.
|
||||
@ -1082,13 +1093,30 @@ class ElectrumX(SessionBase):
|
||||
except ValueError:
|
||||
raise RPCError(BAD_REQUEST, f'tx hash {tx_hash} not in '
|
||||
f'block {block_hash} at height {height:,d}')
|
||||
|
||||
hashes = [hex_str_to_hash(hash) for hash in tx_hashes]
|
||||
branch, root = self.bp.merkle.branch_and_root(hashes, pos)
|
||||
branch = [hash_to_hex_str(hash) for hash in branch]
|
||||
|
||||
branch = self._get_merkle_branch(tx_hashes, pos)
|
||||
return {"block_height": height, "merkle": branch, "pos": pos}
|
||||
|
||||
async def transaction_id_from_pos(self, height, tx_pos, merkle=False):
|
||||
'''Return the txid and optionally a merkle proof, given
|
||||
a block height and position in the block.
|
||||
'''
|
||||
tx_pos = non_negative_integer(tx_pos)
|
||||
if merkle not in (True, False):
|
||||
raise RPCError(BAD_REQUEST, f'"merkle" must be a boolean')
|
||||
|
||||
block_hash, tx_hashes = await self.block_hash_and_tx_hashes(height)
|
||||
try:
|
||||
tx_hash = tx_hashes[tx_pos]
|
||||
except IndexError:
|
||||
raise RPCError(BAD_REQUEST, f'no tx at position {tx_pos:,d} in '
|
||||
f'block {block_hash} at height {height:,d}')
|
||||
branch = self._get_merkle_branch(tx_hashes, tx_pos)
|
||||
|
||||
if merkle:
|
||||
return {"tx_hash": tx_hash, "merkle": branch}
|
||||
else:
|
||||
return tx_hash
|
||||
|
||||
def set_protocol_handlers(self, ptuple):
|
||||
self.protocol_tuple = ptuple
|
||||
|
||||
@ -1126,6 +1154,8 @@ class ElectrumX(SessionBase):
|
||||
'blockchain.block.header': self.block_header,
|
||||
'blockchain.block.headers': self.block_headers,
|
||||
'blockchain.headers.subscribe': self.headers_subscribe,
|
||||
'blockchain.transaction.id_from_pos':
|
||||
self.transaction_id_from_pos,
|
||||
})
|
||||
elif ptuple >= (1, 3):
|
||||
handlers.update({
|
||||
|
||||
Loading…
Reference in New Issue
Block a user