def test_get_proof_bloockchain_okay(self): sdk = getSDK() records = [ Record.fromString("Example Data 1"), Record.fromString("Example Data 2"), Record.fromString("Example Data 3") ] proof = sdk.getProof(records, network=Network.BLOOCK_CHAIN) self.assertIsNotNone(proof) self.assertIsInstance(proof, Proof)
def test_get_proof_okay(self): sdk = getSDK() records = [ Record.fromString("Example Data 1"), Record.fromString("Example Data 2"), Record.fromString("Example Data 3") ] proof = sdk.getProof(records) self.assertIsNotNone(proof) self.assertIsInstance(proof, Proof)
def test_verify_records_invalid_record_input_missing_chars(self): sdk = getSDK() records = [ Record( 'e016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994aa' ), Record( 'e016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994' ) ] with self.assertRaises(InvalidRecordException): sdk.verifyRecords(records, Network.BLOOCK_CHAIN)
def test_send_records_invalid_record_input_wrong_start(self): sdk = getSDK() records = [ Record( '0xe016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994aa' ), Record( '0xe016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994bb' ) ] with self.assertRaises(InvalidRecordException): sdk.sendRecords(records)
def test_get_proof_invalid_record_input_missing_chars(self): sdk = getSDK() records = [ Record( 'e016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994aa' ), Record( 'e016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994' ) ] with self.assertRaises(InvalidRecordException): sdk.getProof(records)
def test_verify_proof_okay(self, MockProofRepo): MockProofRepo.verifyProof.return_value = Record('root') proof = Proof( bitmap="bfdf7000", depth="000400060006000500030002000400060007000800090009", leaves=[ "02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5", ], nodes=[ "bb6986853646d083929d1d92638f3d4741a3b7149bd2b63c6bfedd32e3c684d3", "0616067c793ac533815ae2d48d785d339e0330ce5bb5345b5e6217dd9d1dbeab", "68b8f6b25cc700e64ed3e3d33f2f246e24801f93d29786589fbbab3b11f5bcee" ], anchor={ "anchor_id": 387, "root": "c6372dab6a48637173a457e3ae0c54a500bb50346e847eccf2b818ade94d8ccf", "networks": [{ "name": "bloock_chain", "tx_hash": "0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9", "state": "Confirmed", "created_at": 0 }, { "name": "ethereum_rinkeby", "tx_hash": "0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9", "state": "Confirmed", "created_at": 1 }, { "name": "ethereum_mainnet", "tx_hash": "0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9", "state": "Confirmed", "created_at": 1 }], "status": "Success" }) root = Record('root') calls = [ call(Network.BLOOCK_CHAIN, root), call(Network.ETHEREUM_RINKEBY, root), call(Network.ETHEREUM_MAINNET, root) ] MockProofRepo.validateRoot.has_calls(calls) MockProofRepo.validateRoot.side_effect = [0, 1, 2] service = ProofService(MockProofRepo) timestamp = service.verifyProof(proof) self.assertEqual(timestamp, 2, 'wrong timestamp recieved')
def test_fetch_records_okay(self): sdk = getSDK() records = [ Record.fromString("Example Data 1"), Record.fromString("Example Data 2"), Record.fromString("Example Data 3") ] send_receipt = sdk.sendRecords(records) self.assertIsNotNone(send_receipt) sdk.waitAnchor(send_receipt[0].anchor) record_receipts = sdk.getRecords(records) for mr in record_receipts: self.assertEqual(mr.status, 'Success', 'Status does not match with the expected.')
def test_from_bytes(self): b = bytes.fromhex( '10101010101010101010101010101010101010101010101010101010101010101111111111111111111111111111111111111111111111111111111111111111' ) p = 'e016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994a5' self.assertEqual( Record.fromBytes(b)._Record__hash, p, 'Hashes do not match')
def retrieveProof(self, records: List[Record], network: Network = None, date: float = None) -> Proof: if not records: return None for m in records: if not Record.isValid(m): raise InvalidRecordException(m.getHash()) return self.__proof_repository.retrieveProof(records, network, date)
def test_get_proof_none_existing_leaf(self): sdk = getSDK() with self.assertRaises(HttpRequestException): sdk.getProof([ Record( '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' ) ])
def test_verify_records_none_existing_leaf(self): sdk = getSDK() with self.assertRaises(HttpRequestException): sdk.verifyRecords([ Record( '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' ) ], Network.BLOOCK_CHAIN)
def test_wait_anchor_okay(self): sdk = getSDK() records = [ Record.fromString("Example Data 1"), Record.fromString("Example Data 2"), Record.fromString("Example Data 3") ] send_receipt = sdk.sendRecords(records) self.assertIsNotNone(send_receipt) receipt = sdk.waitAnchor(send_receipt[0].anchor) self.assertIsNotNone(receipt) self.assertGreater(receipt.id, 0) self.assertGreater(len(receipt.block_roots), 0) self.assertGreater(len(receipt.networks), 0) self.assertIsNotNone(receipt.root) self.assertIsNotNone(receipt.status)
def test_get_records_invalid_record_input_wrong_char(self): sdk = getSDK() records = [ Record( 'e016214a5c4abb88b8b614a916b1a6f075dfcf6fbc16c1e9d6e8ebcec81994aG' ) ] with self.assertRaises(InvalidRecordException): sdk.getRecords(records)
def test_send_record_okay(self): sdk = getSDK() records = [Record.fromString("Example Data")] try: sendReceipt = sdk.sendRecords(records) anchor = sdk.waitAnchor(sendReceipt[0].anchor) self.assertIsInstance(anchor, Anchor) except Exception: self.fail('Should not return exception.')
def test_basic_e2e(self): sdk = getSDK() records = [Record.fromBytes(randHex(64))] send_receipt = sdk.sendRecords(records) self.assertIsNotNone(send_receipt) sdk.waitAnchor(send_receipt[0].anchor) proof = sdk.getProof(records) timestamp = sdk.verifyProof(proof) self.assertGreater(timestamp, 0, 'Timestamp was not greater than 0.')
def test_get_proof_valid_date_filter(self): sdk = getSDK() records = [Record.fromBytes(randHex(64))] send_receipt = sdk.sendRecords(records) self.assertIsNotNone(send_receipt) sdk.waitAnchor(send_receipt[0].anchor) date = time.time() proof = sdk.getProof(records, date=date) timestamp = sdk.verifyProof(proof) self.assertGreater(date, timestamp, 'Date was not greater than blockchain timestamp.')
def test_verify_records_impossible_date_filter(self): date = time.time() - 120 sdk = getSDK() records = [Record.fromBytes(randHex(64))] send_receipt = sdk.sendRecords(records) self.assertIsNotNone(send_receipt) sdk.waitAnchor(send_receipt[0].anchor) with self.assertRaises(Exception) as context: sdk.verifyRecords(records, network=Network.BLOOCK_CHAIN, date=date) self.assertTrue( "HttpClient response was not successful: Proof not found." in str( context.exception))
def test_verify_records_valid_date_filter(self): sdk = getSDK() records = [Record.fromBytes(randHex(64))] send_receipt = sdk.sendRecords(records) self.assertIsNotNone(send_receipt) sdk.waitAnchor(send_receipt[0].anchor) date = time.time() timestamp = sdk.verifyRecords(records, network=Network.BLOOCK_CHAIN, date=date) self.assertGreater(date, timestamp, 'Date was not greater than blockchain timestamp.')
def verifyProof(self, proof: Proof) -> Record: if not Proof.isValid(proof): raise ProofVerificationException( 'Input Proof is not valid for a verification process.') leaves = proof.leaves hashes = proof.nodes depth_bytes = bytes.fromhex(proof.depth) depth = [ int.from_bytes(depth_bytes[i * 2:i * 2 + 2], 'big') for i in range(0, len(depth_bytes) // 2) ] bitmap = [b for b in bytes.fromhex(proof.bitmap)] it_leaves = 0 it_hashes = 0 stack = [] while it_hashes < len(hashes) or it_leaves < len(leaves): act_depth = depth[it_hashes + it_leaves] if (bitmap[int((it_hashes + it_leaves) / 8)] & (1 << (7 - ((it_hashes + it_leaves) % 8)))) > 0: act_hash = hashes[it_hashes] it_hashes += 1 else: act_hash = leaves[it_leaves] it_leaves += 1 while len(stack) > 0 and stack[len(stack) - 1][1] == act_depth: last_hash = stack.pop() act_hash = (Record.fromHex(last_hash[0] + act_hash).getHash()) act_depth -= 1 stack.append((act_hash, act_depth)) return Record.fromHash(stack[0][0])
def test_verify_proof_wrong_network_name(self, MockProofRepo): MockProofRepo.verifyProof.return_value = Record('root') proof = Proof( bitmap="bfdf7000", depth="000400060006000500030002000400060007000800090009", leaves=[ "02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5", ], nodes=[ "bb6986853646d083929d1d92638f3d4741a3b7149bd2b63c6bfedd32e3c684d3", "0616067c793ac533815ae2d48d785d339e0330ce5bb5345b5e6217dd9d1dbeab", "68b8f6b25cc700e64ed3e3d33f2f246e24801f93d29786589fbbab3b11f5bcee" ], anchor={ "anchor_id": 387, "root": "c6372dab6a48637173a457e3ae0c54a500bb50346e847eccf2b818ade94d8ccf", "networks": [{ "name": "bloock_chain", "tx_hash": "0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9", "state": "Confirmed", "created_at": 0 }, { "name": "ethereum_secret_master_network", "tx_hash": "0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9", "state": "Confirmed", "created_at": 1 }, { "name": "ethereum_mainnet", "tx_hash": "0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9", "state": "Confirmed", "created_at": 1 }], "status": "Success" }) service = ProofService(MockProofRepo) with self.assertRaises(Exception) as context: service.verifyProof(proof) self.assertTrue( "'ethereum_secret_master_network' is not a valid Network" in str( context.exception))
def test_send_records_some_invalid_record_error(self, MockRecordRepo, MockRecord): MockRecordRepo.sendRecords.return_value = RecordWriteResponse({ 'anchor': 80, 'client': 'ce10c769-022b-405e-8e7c-3b52eeb2a4ea', 'records': [ '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5', 'record2', '' ], 'status': 'Pending' }) MockRecord.return_value = False m_repo = RecordService(MockRecordRepo) with self.assertRaises(InvalidRecordException): m_repo.sendRecords([Record('record')])
def test_get_records_okay(self, MockRecordRepo): MockRecordRepo.fetchRecords.return_value = [ RecordReceipt( 80, 'ce10c769-022b-405e-8e7c-3b52eeb2a4ea', '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5', 'Pending') ] m_service = RecordService(MockRecordRepo) r = m_service.getRecords([ Record( '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5' ) ]) self.assertEqual(r[0].anchor, 80, 'Wrong anchor') self.assertEqual(r[0].client, 'ce10c769-022b-405e-8e7c-3b52eeb2a4ea', 'Wrong client') self.assertEqual( r[0].record, '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5', 'Wrong records') self.assertEqual(r[0].status, 'Pending', 'Wrong anchor')
def test_retrieve_proof_okay(self, MockHttpClient, MockBlockchainClient, MockConfig): MockHttpClient.post.return_value = { "bitmap": "bfdf7000", "depth": "000400060006000500030002000400060007000800090009", "leaves": [ "02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5", ], "nodes": [ "bb6986853646d083929d1d92638f3d4741a3b7149bd2b63c6bfedd32e3c684d3", "0616067c793ac533815ae2d48d785d339e0330ce5bb5345b5e6217dd9d1dbeab", "68b8f6b25cc700e64ed3e3d33f2f246e24801f93d29786589fbbab3b11f5bcee" ], "root": "c6372dab6a48637173a457e3ae0c54a500bb50346e847eccf2b818ade94d8ccf", "anchor": get_anchor_dict() } proof_repo = ProofRepository( MockHttpClient, MockBlockchainClient, MockConfig) proof = proof_repo.retrieveProof([Record( "02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5")], Network.BLOOCK_CHAIN, 0) self.assertIsInstance(proof, Proof) self.assertEqual(proof.bitmap, 'bfdf7000', 'Expecting different bitmap.') self.assertEqual( proof.depth, '000400060006000500030002000400060007000800090009', 'Expecting different depth') self.assertEqual(proof.leaves, [ '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5'], 'Expecting different leaves array') self.assertEqual(proof.nodes, [ "bb6986853646d083929d1d92638f3d4741a3b7149bd2b63c6bfedd32e3c684d3", "0616067c793ac533815ae2d48d785d339e0330ce5bb5345b5e6217dd9d1dbeab", "68b8f6b25cc700e64ed3e3d33f2f246e24801f93d29786589fbbab3b11f5bcee" ], 'Expecting different nodes array') self.assertEqual(proof.anchor.anchor_id, 387, 'Expecting different anchor id') self.assertEqual(proof.anchor.root, "c6372dab6a48637173a457e3ae0c54a500bb50346e847eccf2b818ade94d8ccf", 'Expecting different root value') self.assertEqual(proof.anchor.anchor_id, 387, 'Expecting different anchor id') self.assertEqual(proof.anchor.networks[0].name, 'ethereum_ganache', 'Expecting different network name') self.assertEqual(proof.anchor.networks[0].tx_hash, '0xc087797b9700245c8e3f678874e9c419297f2302cb822d798ca94cce8c27aea9', 'Expecting different tx_hash') self.assertEqual(proof.anchor.networks[0].state, 'Confirmed', 'Expecting different state') self.assertEqual(proof.anchor.networks[0].created_at, 1631873582, 'Expecting different created_at') self.assertEqual(proof.anchor.status, 'Success', 'Expecting different status')
def test_send_records_okay(self, MockRecordRepo, MockRecord): MockRecordRepo.sendRecords.return_value = RecordWriteResponse({ 'anchor': 80, 'client': 'ce10c769-022b-405e-8e7c-3b52eeb2a4ea', 'messages': [ '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5' ], 'status': 'Pending' }) MockRecord.return_value = True m_repo = RecordService(MockRecordRepo) r = m_repo.sendRecords([Record('record')]) self.assertIsInstance(r[0], RecordReceipt, "Wrong return type") self.assertEqual(r[0].anchor, 80, 'Wrong anchor') self.assertEqual(r[0].client, 'ce10c769-022b-405e-8e7c-3b52eeb2a4ea', 'Wrong client') self.assertEqual( r[0].record, '02aae7e86eb50f61a62083a320475d9d60cbd52749dbf08fa942b1b97f50aee5', 'Wrong records') self.assertEqual(r[0].status, 'Pending', 'Wrong anchor')
def test_from_string_not_string_error(self): with self.assertRaises(TypeError): Record.fromString(125)
def test_is_valid_wrong_char(self): self.assertFalse( Record.isValid( Record( 'G010101010101010101010101010101010101010101010101010101010101010' )), 'Record is not valid')
def test_is_valid_okay(self): self.assertTrue( Record.isValid( Record( '1010101010101010101010101010101010101010101010101010101010101010' )), 'Record is not valid')
def test_from_bytes_not_bytes_error(self): with self.assertRaises(TypeError): Record.fromBytes(125)
def test_is_valid_not_record_instance(self): self.assertFalse(Record.isValid('test Record'), 'Record is not valid')
def test_from_hash(self): self.assertEqual( Record.fromHash('test_hash')._Record__hash, Record('test_hash')._Record__hash, "Records do not match.")