def MissingOneSketchTest(meros: Meros) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Merit/Sketches/MissingOne.json", "r") as file: vectors = json.loads(file.read()) blockchain: Blockchain = Blockchain.fromJSON(vectors["blockchain"]) meros.liveConnect(blockchain.blocks[0].header.hash) meros.syncConnect(blockchain.blocks[0].header.hash) header: bytes = meros.liveBlockHeader(blockchain.blocks[1].header) meros.handleBlockBody(blockchain.blocks[1]) if meros.live.recv() != header: raise TestError( "Meros didn't broadcast a BlockHeader for a Block it just added.") for data in vectors["datas"]: if meros.liveTransaction(Data.fromJSON(data)) != meros.live.recv(): raise TestError("Meros didn't broadcast back a Data Transaction.") for verif in vectors["verifications"]: if meros.signedElement( SignedVerification.fromSignedJSON(verif)) != meros.live.recv(): raise TestError("Meros didn't broadcast back a Verification.") header = meros.liveBlockHeader(blockchain.blocks[2].header) meros.handleBlockBody(blockchain.blocks[2], 1) if MessageType(meros.sync.recv()[0]) != MessageType.SketchHashRequests: raise TestError("Meros didn't request the packet it's missing.") meros.packet(VerificationPacket.fromJSON(vectors["packet"])) if meros.live.recv() != header: raise TestError( "Meros didn't broadcast a BlockHeader for a Block it just added.")
def TwoHundredThirtyEightTest( rpc: RPC ) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Transactions/Prune/TwoHundredThirtyEight.json", "r") as file: vectors = json.loads(file.read()) datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]] verif: SignedVerification = SignedVerification.fromSignedJSON(vectors["verification"]) def sendDatas() -> None: for d in range(len(datas)): if rpc.meros.liveTransaction(datas[d]) != rpc.meros.live.recv(): raise TestError("Meros didn't broadcast a Data.") if rpc.meros.signedElement(verif) != rpc.meros.live.recv(): raise TestError("Meros didn't broadcast the Verification.") Liver( rpc, vectors["blockchain"], callbacks={ 42: sendDatas } ).live()
def OneHundredPercentSketchTest(meros: Meros) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Merit/Sketches/OneHundredPercent.json", "r") as file: vectors = json.loads(file.read()) blockchain: Blockchain = Blockchain.fromJSON(vectors["blockchain"]) meros.liveConnect(blockchain.blocks[0].header.hash) meros.syncConnect(blockchain.blocks[0].header.hash) header: bytes = meros.liveBlockHeader(blockchain.blocks[1].header) meros.handleBlockBody(blockchain.blocks[1]) if meros.live.recv() != header: raise TestError( "Meros didn't broadcast a BlockHeader for a Block it just added.") for data in vectors["datas"]: if meros.liveTransaction(Data.fromJSON(data)) != meros.live.recv(): raise TestError("Meros didn't broadcast back a Data Transaction.") for verif in vectors["verifications"]: if meros.signedElement( SignedVerification.fromSignedJSON(verif)) != meros.live.recv(): raise TestError("Meros didn't broadcast back a Verification.") header = meros.liveBlockHeader(blockchain.blocks[2].header) meros.handleBlockBody(blockchain.blocks[2]) if meros.live.recv() != header: raise TestError( "Meros didn't broadcast a BlockHeader for a Block it just added.")
def testBlockchain( b: int ) -> None: #Data. data: Data = Data.fromJSON(vectors["data"]) #pylint: disable=no-member #MeritRemoval. removal: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(vectors["removals"][b]) #Create and execute a Liver to send the MeritRemoval. def sendMeritRemoval() -> None: #Send the Data. if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") rpc.meros.signedElement(removal) try: if len(rpc.meros.live.recv()) != 0: raise Exception() except TestError: raise SuccessError("Meros rejected our MeritRemoval created from the same Element.") except Exception: raise TestError("Meros accepted our MeritRemoval created from the same Element.") Liver( rpc, vectors["blockchain"], callbacks={ 1: sendMeritRemoval } ).live()
def LowerHashTieBreakTest(rpc: RPC) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Consensus/Families/LowerHashTieBreak.json", "r") as file: vectors = json.loads(file.read()) datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]] def sendDatas() -> None: for d in range(len(datas)): if rpc.meros.liveTransaction(datas[d]) != rpc.meros.live.recv(): raise TestError("Meros didn't broadcast a Data.") def verifyLowerHashWon() -> None: data: Data = datas[1] if int.from_bytes(data.hash, "little") > int.from_bytes( datas[2].hash, "little"): data = datas[2] if not rpc.call("consensus", "getStatus", {"hash": data.hash.hex()})["verified"]: raise TestError( "Meros didn't verify the tied Transaction with a lower hash.") Liver(rpc, vectors["blockchain"], callbacks={ 40: sendDatas, 46: verifyLowerHashWon }).live()
def UnmentionedBeatMentionedTest( rpc: RPC ) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Consensus/Families/UnmentionedBeatMentioned.json", "r") as file: vectors = json.loads(file.read()) datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]] verif: SignedVerification = SignedVerification.fromSignedJSON(vectors["verification"]) def sendDatas() -> None: for d in range(len(datas)): if rpc.meros.liveTransaction(datas[d]) != rpc.meros.live.recv(): raise TestError("Meros didn't broadcast a Data.") #Might as well send this now. if rpc.meros.signedElement(verif) != rpc.meros.live.recv(): raise TestError("Meros didn't broadcast the Verification.") def verifyMentionedWon() -> None: if not rpc.call("consensus", "getStatus", [datas[2].hash.hex()])["verified"]: raise TestError("Meros didn't verify the only Transaction on chain which has finalized.") Liver( rpc, vectors["blockchain"], callbacks={ 41: sendDatas, 47: verifyMentionedWon } ).live()
def PruneUnaddableTest(rpc: RPC) -> None: file: IO[Any] = open("e2e/Vectors/Transactions/PruneUnaddable.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() pruned: bytes = Data.fromJSON(vectors["datas"][2]).hash prunedDescendant: bytes = Data.fromJSON(vectors["datas"][3]).hash def sendDatas() -> None: for data in vectors["datas"]: if rpc.meros.liveTransaction( Data.fromJSON(data)) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") #Send the beaten Data's descendant's verification. if rpc.meros.signedElement( SignedVerification.fromSignedJSON( vectors["verification"])) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the SignedVerification.") def verifyAdded() -> None: rpc.call("transactions", "getTransaction", [pruned.hex()]) rpc.call("consensus", "getStatus", [pruned.hex()]) def verifyPruned() -> None: try: rpc.call("transactions", "getTransaction", [pruned.hex()]) rpc.call("transactions", "getTransaction", [prunedDescendant.hex()]) rpc.call("consensus", "getStatus", [pruned.hex()]) rpc.call("consensus", "getStatus", [prunedDescendant.hex()]) raise Exception() except TestError: pass except Exception: raise TestError("Meros didn't prune the Transaction.") #Create and execute a Liver. Liver(rpc, vectors["blockchain"], callbacks={ 1: sendDatas, 2: verifyAdded, 8: verifyPruned }).live()
def sendDatas() -> None: for data in vectors["datas"]: if rpc.meros.liveTransaction( Data.fromJSON(data)) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") #Send the beaten Data's descendant's verification. if rpc.meros.signedElement( SignedVerification.fromSignedJSON( vectors["verification"])) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the SignedVerification.")
def HundredThirtyFiveTest( rpc: RPC ) -> None: file: IO[Any] = open("e2e/Vectors/Consensus/MeritRemoval/HundredThirtyFive.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Datas. datas: List[Data] = [ Data.fromJSON(vectors["datas"][0]), Data.fromJSON(vectors["datas"][1]), Data.fromJSON(vectors["datas"][2]) ] #Transactions. transactions: Transactions = Transactions() for data in datas: transactions.add(data) #First MeritRemoval. mr: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(vectors["removal"]) def sendMeritRemoval() -> None: #Send the Datas. for data in datas: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Data.") #Send and verify the original MeritRemoval. if rpc.meros.signedElement(mr) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 1, mr.holder, True) Liver( rpc, vectors["blockchain"], transactions, callbacks={ 1: sendMeritRemoval } ).live()
def fromJSON(json: Dict[str, Dict[str, Any]]) -> Any: result = Transactions() for tx in json: if json[tx]["descendant"] == "Claim": result.add(Claim.fromJSON(json[tx])) elif json[tx]["descendant"] == "Send": result.add(Send.fromJSON(json[tx])) elif json[tx]["descendant"] == "Data": result.add(Data.fromJSON(json[tx])) else: raise Exception("JSON has an unsupported Transaction type: " + json[tx]["descendant"]) return result
def MultiplePacketsTest(rpc: RPC) -> None: #Spawn a Blockchain just to set the RandomX key. _: Blockchain = Blockchain() vectors: Dict[str, Any] with open("e2e/Vectors/Merit/MultiplePackets.json", "r") as file: vectors = json.loads(file.read()) data: Data = Data.fromJSON(vectors["data"]) block: Block = Block.fromJSON(vectors["blockchain"][-1]) def sendDataAndBlock() -> None: #Send the Data. if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") rpc.meros.liveBlockHeader(block.header) rpc.meros.handleBlockBody(block) msg: bytes = rpc.meros.sync.recv() if MessageType(msg[0]) != MessageType.SketchHashRequests: raise TestError("Meros didn't request the packets for this Block.") packets: Dict[int, VerificationPacket] = {} for packet in block.body.packets: packets[Sketch.hash(block.header.sketchSalt, packet)] = packet #Look up each requested packet and respond accordingly. for h in range(int.from_bytes(msg[33:37], byteorder="little")): sketchHash: int = int.from_bytes(msg[37 + (h * 8):45 + (h * 8)], byteorder="little") if sketchHash not in packets: raise TestError("Meros asked for a non-existent Sketch Hash.") rpc.meros.packet(packets[sketchHash]) try: if MessageType( rpc.meros.live.recv()[0]) == MessageType.BlockHeader: raise TestError("Meros added the Block.") except Exception as e: if str(e) != "Meros added the Block.": raise SuccessError() with raises(SuccessError): Liver(rpc, vectors["blockchain"], callbacks={ 2: sendDataAndBlock }).live()
def PruneUnaddableTest(rpc: RPC) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Transactions/Prune/PruneUnaddable.json", "r") as file: vectors = json.loads(file.read()) datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]] def sendDatas() -> None: for data in datas: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") #Send the winning descendant Data's verification. verif: SignedVerification = SignedVerification.fromSignedJSON( vectors["verification"]) if rpc.meros.signedElement(verif) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the SignedVerification.") #The Liver thinks we sent this packet, so it shouldn't have to. #That said, that'd only be true if this was included in the Sketcher. #As its parent is unmentioned, it won't be. del rpc.meros.sentVerifs[verif.hash] def verifyAdded() -> None: for data in datas: rpc.call("transactions", "getTransaction", {"hash": data.hash.hex()}) rpc.call("consensus", "getStatus", {"hash": data.hash.hex()}) def verifyPruned() -> None: for data in datas[2:]: with raises(TestError): rpc.call("transactions", "getTransaction", {"hash": data.hash.hex()}) with raises(TestError): rpc.call("consensus", "getStatus", {"hash": data.hash.hex()}) Liver(rpc, vectors["blockchain"], callbacks={ 1: sendDatas, 2: verifyAdded, 7: verifyPruned }).live()
def PruneUnaddableTest( rpc: RPC ) -> None: file: IO[Any] = open("e2e/Vectors/Transactions/PruneUnaddable.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]] def sendDatas() -> None: for data in datas: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") #Send the beaten Data's descendant's verification. if rpc.meros.signedElement(SignedVerification.fromSignedJSON(vectors["verification"])) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the SignedVerification.") def verifyAdded() -> None: for data in datas: rpc.call("transactions", "getTransaction", [data.hash.hex()]) rpc.call("consensus", "getStatus", [data.hash.hex()]) #def verifyPruned() -> None: # for data in datas[2:]: # with raises(TestError): # rpc.call("transactions", "getTransaction", [data.hash.hex()]) # with raises(TestError): # rpc.call("consensus", "getStatus", [data.hash.hex()]) Liver( rpc, vectors["blockchain"], callbacks={ 1: sendDatas, 2: verifyAdded } ).live()
def HundredThirtyThreeTest( rpc: RPC ) -> None: file: IO[Any] = open("e2e/Vectors/Consensus/MeritRemoval/HundredThirtyThree.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Datas. datas: List[Data] = [ Data.fromJSON(vectors["datas"][0]), Data.fromJSON(vectors["datas"][1]), Data.fromJSON(vectors["datas"][2]) ] #Transactions. transactions: Transactions = Transactions() for data in datas: transactions.add(data) def testBlockchain( i: int ) -> None: def sendMeritRemoval() -> None: #Send the Datas. for data in datas: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Data.") #Send the Block containing the modified Merit Removal. block: Block = Block.fromJSON(vectors["blockchains"][i][-1]) rpc.meros.liveBlockHeader(block.header) #Flag of if the Block's Body synced. blockBodySynced: bool = False #Handle sync requests. reqHash: bytes = bytes() while True: if blockBodySynced: #Sleep for a second so Meros handles the Block. sleep(1) #Try receiving from the Live socket, where Meros sends keep-alives. try: if len(rpc.meros.live.recv()) != 0: raise Exception() except TestError: #Verify the height is 2. #The genesis Block and the Block granting Merit. try: if rpc.call("merit", "getHeight") != 2: raise Exception() except Exception: raise TestError("Node added a Block containg a repeat MeritRemoval.") #Since the node didn't add the Block, raise SuccessError. raise SuccessError("Node didn't add a Block containing a repeat MeritRemoval.") except Exception: raise TestError("Meros sent a keep-alive.") msg: bytes = rpc.meros.sync.recv() if MessageType(msg[0]) == MessageType.BlockBodyRequest: reqHash = msg[1 : 33] if reqHash != block.header.hash: raise TestError("Meros asked for a Block Body that didn't belong to the Block we just sent it.") #Send the BlockBody. blockBodySynced = True rpc.meros.blockBody(block) else: raise TestError("Unexpected message sent: " + msg.hex().upper()) Liver( rpc, vectors["blockchains"][i], transactions, callbacks={ 1: sendMeritRemoval } ).live() with raises(SuccessError): for b in range(2): testBlockchain(b)
def VParsableTest(rpc: RPC) -> None: file: IO[Any] = open("e2e/Vectors/Consensus/Verification/Parsable.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() merit: Merit = Merit.fromJSON(vectors["blockchain"]) transactions: Transactions = Transactions() transactions.add(Data.fromJSON(vectors["data"])) #Custom function to send the last Block and verify it errors at the right place. def checkFail() -> None: #This Block should cause the node to disconnect us AFTER it syncs our Transaction. syncedTX: bool = False block: Block = merit.blockchain.blocks[2] rpc.meros.liveBlockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: if syncedTX: #Try receiving from the Live socket, where Meros sends keep-alives. try: if len(rpc.meros.live.recv()) != 0: raise Exception() except TestError: raise SuccessError( "Node disconnected us after we sent a parsable, yet invalid, Transaction." ) except Exception: raise TestError("Meros sent a keep-alive.") msg: bytes = rpc.meros.sync.recv() if MessageType(msg[0]) == MessageType.BlockBodyRequest: reqHash = msg[1:33] if reqHash != block.header.hash: raise TestError( "Meros asked for a Block Body that didn't belong to the Block we just sent it." ) #Send the BlockBody. rpc.meros.blockBody(block) elif MessageType(msg[0]) == MessageType.SketchHashesRequest: if not block.body.packets: raise TestError( "Meros asked for Sketch Hashes from a Block without any." ) reqHash = msg[1:33] if reqHash != block.header.hash: raise TestError( "Meros asked for Sketch Hashes that didn't belong to the Block we just sent it." ) #Create the haashes. hashes: List[int] = [] for packet in block.body.packets: hashes.append(Sketch.hash(block.header.sketchSalt, packet)) #Send the Sketch Hashes. rpc.meros.sketchHashes(hashes) elif MessageType(msg[0]) == MessageType.SketchHashRequests: if not block.body.packets: raise TestError( "Meros asked for Verification Packets from a Block without any." ) reqHash = msg[1:33] if reqHash != block.header.hash: raise TestError( "Meros asked for Verification Packets that didn't belong to the Block we just sent it." ) #Create a lookup of hash to packets. packets: Dict[int, VerificationPacket] = {} for packet in block.body.packets: packets[Sketch.hash(block.header.sketchSalt, packet)] = packet #Look up each requested packet and respond accordingly. for h in range(int.from_bytes(msg[33:37], byteorder="little")): sketchHash: int = int.from_bytes(msg[37 + (h * 8):45 + (h * 8)], byteorder="little") if sketchHash not in packets: raise TestError( "Meros asked for a non-existent Sketch Hash.") rpc.meros.packet(packets[sketchHash]) elif MessageType(msg[0]) == MessageType.TransactionRequest: reqHash = msg[1:33] if reqHash not in transactions.txs: raise TestError( "Meros asked for a non-existent Transaction.") rpc.meros.syncTransaction(transactions.txs[reqHash]) syncedTX = True else: raise TestError("Unexpected message sent: " + msg.hex().upper()) with raises(SuccessError): Liver(rpc, vectors["blockchain"], transactions, callbacks={ 1: checkFail }).live()
def VerifyCompetingTest(rpc: RPC) -> None: file: IO[Any] = open( "e2e/Vectors/Consensus/MeritRemoval/VerifyCompeting.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Datas. datas: List[Data] = [ Data.fromJSON(vectors["datas"][0]), Data.fromJSON(vectors["datas"][1]), Data.fromJSON(vectors["datas"][2]) ] #Transactions. transactions: Transactions = Transactions() for data in datas: transactions.add(data) #Initial Data's Verification. verif: SignedVerification = SignedVerification.fromSignedJSON( vectors["verification"]) #MeritRemoval. #pylint: disable=no-member removal: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON( vectors["removal"]) #Create and execute a Liver to cause a Signed MeritRemoval. def sendElements() -> None: #Send the Datas. for data in datas: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Data.") #Send the initial Data's verification. if rpc.meros.signedElement(verif) != rpc.meros.live.recv(): raise TestError("Meros didn't us the initial Data's Verification.") #Send the first Element. if rpc.meros.signedElement(removal.se1) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Verification.") #Trigger the MeritRemoval. rpc.meros.signedElement(removal.se2) if rpc.meros.live.recv() != (MessageType.SignedMeritRemoval.toByte() + removal.signedSerialize()): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 1, removal.holder, True) Liver(rpc, vectors["blockchain"], transactions, callbacks={ 1: sendElements, 2: lambda: verifyMeritRemoval(rpc, 1, 1, removal.holder, False) }).live() #Create and execute a Liver to handle a Signed MeritRemoval. def sendMeritRemoval() -> None: #Send the Datas. for data in datas: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Data.") #Send the initial Data's verification. if rpc.meros.signedElement(verif) != rpc.meros.live.recv(): raise TestError("Meros didn't us the initial Data's Verification.") #Send and verify the MeritRemoval. if rpc.meros.signedElement(removal) != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 1, removal.holder, True) Liver(rpc, vectors["blockchain"], transactions, callbacks={ 1: sendMeritRemoval, 2: lambda: verifyMeritRemoval(rpc, 1, 1, removal.holder, False) }).live() #Create and execute a Syncer to handle a Signed MeritRemoval. Syncer(rpc, vectors["blockchain"], transactions).sync() verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
def PartialArchiveTest(rpc: RPC) -> None: vectors: Dict[str, Any] with open("e2e/Vectors/Consensus/Verification/PartialArchive.json", "r") as file: vectors = json.loads(file.read()) data: Data = Data.fromJSON(vectors["data"]) svs: List[SignedVerification] = [ SignedVerification.fromSignedJSON(vectors["verifs"][0]), SignedVerification.fromSignedJSON(vectors["verifs"][1]) ] key: PrivateKey = PrivateKey( bytes.fromhex(rpc.call("personal", "getMiner"))) def sendDataAndVerifications() -> None: if rpc.meros.liveTransaction(data) != rpc.meros.live.recv(): raise TestError( "Meros didn't rebroadcast a Transaction we sent it.") for sv in svs: if rpc.meros.signedElement(sv) != rpc.meros.live.recv(): raise TestError( "Meros didn't rebroadcast a SignedVerification we sent it." ) #As we don't have a quality RPC route for this, we need to use getTemplate. if bytes.fromhex( rpc.call("merit", "getBlockTemplate", [key.toPublicKey().serialize().hex() ])["header"])[36:68] != BlockHeader.createContents( [VerificationPacket(data.hash, [0, 1])]): raise TestError( "New Block template doesn't have a properly created packet.") def verifyRecreation() -> None: template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [key.toPublicKey().serialize().hex()]) if bytes.fromhex( template["header"])[36:68] != BlockHeader.createContents( [VerificationPacket(data.hash, [1])]): raise TestError( "New Block template doesn't have a properly recreated packet.") #Mining it further verifies the internal state. header: bytes = bytes.fromhex(template["header"]) proof: int = 0 sig: bytes while True: initial: bytes = RandomX(header + proof.to_bytes(4, byteorder="little")) sig = key.sign(initial).serialize() final: bytes = RandomX(initial + sig) if (int.from_bytes(final, "little") * template["difficulty"]) < int.from_bytes( bytes.fromhex("FF" * 32), "little"): break proof += 1 rpc.call("merit", "publishBlock", [ template["id"], (header + proof.to_bytes(4, byteorder="little") + sig).hex() ]) raise SuccessError( "Stop Liver from trying to verify the vector chain which doesn't have this Block." ) #We may not want to use Liver here. #There's a very small Block count and we can't let it terminate (hence the SE). with raises(SuccessError): Liver(rpc, vectors["blockchain"], callbacks={ 2: sendDataAndVerifications, 3: verifyRecreation }).live()
def MatchesHeaderQuantityTest(meros: Meros) -> None: #Create an instance of Merit to make sure the RandomX VM key was set. Merit() blocks: List[Block] txs: List[Data] = [] verifs: List[SignedVerification] = [] with open( "e2e/Vectors/Merit/TwoHundredSeventyFour/MatchesHeaderQuantity.json", "r") as file: vectors: Dict[str, Any] = json.loads(file.read()) blocks = [Block.fromJSON(block) for block in vectors["blocks"]] txs = [Data.fromJSON(tx) for tx in vectors["transactions"]] verifs = [ SignedVerification.fromSignedJSON(verif) for verif in vectors["verifications"] ] #Connect. meros.liveConnect(blocks[0].header.last) meros.syncConnect(blocks[0].header.last) #Send a single Block to earn Merit. meros.liveBlockHeader(blocks[0].header) meros.handleBlockBody(blocks[0]) #Send the header. meros.liveBlockHeader(blocks[1].header) #Fail Sketch Resolution, and send a different amount of sketch hashes. meros.handleBlockBody(blocks[1], 0) if MessageType(meros.sync.recv()[0]) != MessageType.SketchHashesRequest: raise TestError( "Meros didn't request the hashes after failing sketch resolution.") #Send a quantity of sketch hashes that doesn't match the header. meros.sketchHashes([ Sketch.hash(blocks[1].header.sketchSalt, VerificationPacket(tx.hash, [0])) for tx in txs ]) try: if len(meros.sync.recv()) == 0: raise TestError() raise Exception() except TestError: pass except Exception: raise TestError("Meros tried to further sync an invalid Block Body.") #Sleep so we can reconnect. sleep(65) #Repeat setup. meros.liveConnect(blocks[0].header.last) meros.syncConnect(blocks[0].header.last) #Send two Transactions. for i in range(2): meros.liveTransaction(txs[i]) meros.signedElement(verifs[i]) #Send the header and a large enough sketch to cause resolution. meros.liveBlockHeader(blocks[1].header) meros.handleBlockBody(blocks[1], 3) #Should now have been disconnected thanks to having 5 hashes. try: if len(meros.sync.recv()) == 0: raise TestError() raise Exception() except TestError: pass except Exception: raise TestError("Meros tried to further sync an invalid Block Body.")