def verifyMerkleProof(*replies: Tuple[Reply]) -> bool: """ Verifies the correctness of the merkle proof provided in the reply from the node. Returns True if verified to be correct, throws an exception otherwise. :param replies: One or more replies for which Merkle Proofs have to be verified :raises ProofError: The proof is invalid :return: True """ verifier = MerkleVerifier() fields = getTxnOrderedFields() serializer = CompactSerializer(fields=fields) for r in replies: seqNo = r[f.RESULT.nm][F.seqNo.name] rootHash = base64.b64decode( r[f.RESULT.nm][F.rootHash.name].encode()) auditPath = [ base64.b64decode(a.encode()) for a in r[f.RESULT.nm][F.auditPath.name] ] filtered = ( (k, v) for (k, v) in r[f.RESULT.nm].iteritems() if k not in [F.auditPath.name, F.seqNo.name, F.rootHash.name]) result = serializer.serialize(dict(filtered)) verifier.verify_leaf_inclusion( result, seqNo - 1, auditPath, STH(tree_size=seqNo, sha256_root_hash=rootHash)) return True
class ClientTxnLog(HasFileStorage): """ An immutable log of transactions made by the client. """ def __init__(self, name, baseDir=None): self.dataDir = "data/clients" self.name = name HasFileStorage.__init__(self, name, baseDir=baseDir, dataDir=self.dataDir) self.clientDataLocation = self.dataLocation if not os.path.exists(self.clientDataLocation): os.makedirs(self.clientDataLocation) self.transactionLog = TextFileStore(self.clientDataLocation, "transactions") self.serializer = CompactSerializer(fields=self.txnFieldOrdering) @property def txnFieldOrdering(self): fields = getTxnOrderedFields() return updateFieldsWithSeqNo(fields) def append(self, identifier: str, reqId, txn): key = '{}{}'.format(identifier, reqId) self.transactionLog.put(key=key, value=self.serializer.serialize(txn, fields=self.txnFieldOrdering, toBytes=False)) def hasTxn(self, identifier, reqId) -> bool: key = '{}{}'.format(identifier, reqId) for key in self.transactionLog.iterator(includeKey=True, includeValue=False): if key == str(reqId): return True return False
class ClientTxnLog(HasFileStorage): """ An immutable log of transactions made by the client. """ def __init__(self, name, baseDir=None): self.dataDir = "data/clients" self.name = name HasFileStorage.__init__(self, name, baseDir=baseDir, dataDir=self.dataDir) self.clientDataLocation = self.dataLocation if not os.path.exists(self.clientDataLocation): os.makedirs(self.clientDataLocation) self.transactionLog = TextFileStore(self.clientDataLocation, "transactions") self.serializer = CompactSerializer(fields=self.txnFieldOrdering) @property def txnFieldOrdering(self): fields = getTxnOrderedFields() return updateFieldsWithSeqNo(fields) def append(self, reqId, txn): self.transactionLog.put(key=str(reqId), value=self.serializer.serialize(txn, fields=self.txnFieldOrdering, toBytes=False)) def hasTxnWithReqId(self, reqId) -> bool: for key in self.transactionLog.iterator(includeKey=True, includeValue=False): if key == str(reqId): return True return False
def verifyMerkleProof(*replies: Tuple[Reply]) -> bool: """ Verifies the correctness of the merkle proof provided in the reply from the node. Returns True if verified to be correct, throws an exception otherwise. :param replies: One or more replies for which Merkle Proofs have to be verified :raises ProofError: The proof is invalid :return: True """ verifier = MerkleVerifier() fields = getTxnOrderedFields() serializer = CompactSerializer(fields=fields) for r in replies: seqNo = r[f.RESULT.nm][F.seqNo.name] rootHash = base64.b64decode( r[f.RESULT.nm][F.rootHash.name].encode()) auditPath = [base64.b64decode( a.encode()) for a in r[f.RESULT.nm][F.auditPath.name]] filtered = ((k, v) for (k, v) in r[f.RESULT.nm].iteritems() if k not in [F.auditPath.name, F.seqNo.name, F.rootHash.name]) result = serializer.serialize(dict(filtered)) verifier.verify_leaf_inclusion(result, seqNo - 1, auditPath, STH(tree_size=seqNo, sha256_root_hash=rootHash)) return True
def testSerializeSubfields(): fields = OrderedDict([ ("f1.a", (str, str)), ("f1.b", (str, int)), ("f1.c", (str, float)), ("f2.d", (str, str)), ("f2.e", (str, int)), ("f2.f", (str, float)), ]) serializer = CompactSerializer(fields) json = { "f1":{"a": "v1", "b": 2, "c": 3.0}, "f2": {"d": "v1", "e": 3, "f": 4.0}, } assert b"v1|2|3.0|v1|3|4.0" == serializer.serialize(json)