def get_utxoset_merkle_root(self): """Returns the merkle root of the utxoset. This implies that the utxoset is first put into a merkle tree. For now, the merkle tree and its root will be computed each time. This obviously is not efficient and a better approach that limits the repetition of the same computation when unnecesary should be sought. For instance, future optimizations could simply re-compute the branches of the tree that were affected by a change. The transaction hash (id) and output index should be sufficient to uniquely identify a utxo, and consequently only that information from a utxo record is needed to compute the merkle root. Hence, each node of the merkle tree should contain the tuple (txid, output_index). .. important:: The leaves of the tree will need to be sorted in some kind of lexicographical order. Returns: str: Merkle root in hexadecimal form. """ utxoset = backend.query.get_unspent_outputs(self.connection) # TODO Once ready, use the already pre-computed utxo_hash field. # See common/transactions.py for details. hashes = [ sha3_256('{}{}'.format(utxo['transaction_id'], utxo['output_index']).encode()).digest() for utxo in utxoset ] # TODO Notice the sorted call! return merkleroot(sorted(hashes))
def test_merkleroot(): from bigchaindb.tendermint.utils import merkleroot hashes = [sha3_256(i.encode()).digest() for i in 'abc'] assert merkleroot(hashes) == ( '78c7c394d3158c218916b7ae0ebdea502e0f4e85c08e3b371e3dfd824d389fa3')