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()
#Ed25519 lib. import ed25519 #Blake2b standard function. from hashlib import blake2b #JSON standard lib. import json #Blank Blocks. bbFile: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r") blankBlocks: List[Dict[str, Any]] = json.loads(bbFile.read()) bbFile.close() #Transactions. transactions: Transactions = Transactions() #Merit. merit: Merit = Merit() #SpamFilter. dataFilter: SpamFilter = SpamFilter(5) #Ed25519 keys. edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() #BLS keys. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Add 1 Blank Block.
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 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 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()