def PartialTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/Partial.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() keys: Dict[bytes, int] = { bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]): 0 } nicks: List[bytes] = [ bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]) ] #MeritRemoval. #pylint: disable=no-member removal: PartialMeritRemoval = PartialMeritRemoval.fromSignedJSON( keys, vectors["removal"]) #Create and execute a Liver to cause a Partial MeritRemoval. def sendElement() -> None: #Send the second Element. rpc.meros.signedElement(removal.se2) #Verify the MeritRemoval. if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() + removal.signedSerialize(nicks)): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 2, 2, removal.holder, True) Liver(rpc, vectors["blockchain"], callbacks={ 2: sendElement, 3: lambda: verifyMeritRemoval(rpc, 2, 2, removal.holder, False) }).live() #Create and execute a Liver to handle a Partial MeritRemoval. def sendMeritRemoval() -> None: #Send and verify the MeritRemoval. if rpc.meros.signedElement(removal) != rpc.meros.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 2, 2, removal.holder, True) Liver(rpc, vectors["blockchain"], callbacks={ 2: sendMeritRemoval, 3: lambda: verifyMeritRemoval(rpc, 2, 2, removal.holder, False) }).live() #Create and execute a Syncer to handle a Partial MeritRemoval. Syncer(rpc, vectors["blockchain"]).sync() verifyMeritRemoval(rpc, 2, 2, removal.holder, False)
def SameNonceTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/SameNonce.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #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 Elements. rpc.meros.signedElement(removal.se1) rpc.meros.signedElement(removal.se2) #Verify the first Element. if rpc.meros.live.recv() != (MessageType.SignedDataDifficulty.toByte() + removal.se1.signedSerialize()): raise TestError("Meros didn't send us the first Data Difficulty.") #Verify the MeritRemoval. 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"], 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 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"], 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"]).sync() verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
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 DepthOneTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Merit/Reorganizations/DepthOne.json", "r") chains: Dict[str, List[Dict[str, Any]]] = json.loads(file.read()) file.close() #Load the alternate blockchain. alt: Blockchain = Blockchain.fromJSON(chains["alt"]) #Send the alternate tip. def sendAlternateTip() -> None: header: bytes = rpc.meros.liveBlockHeader(alt.blocks[-1].header) req: bytes = rpc.meros.sync.recv() if req != (MessageType.BlockBodyRequest.toByte() + alt.blocks[-1].header.hash): raise TestError("Meros didn't request the BlockBody.") rpc.meros.blockBody(alt.blocks[-1]) if rpc.meros.live.recv() != header: raise TestError("Meros didn't send back the BlockHeader.") #Verify the alternate Blockchain. verifyBlockchain(rpc, alt) #Raise SuccessError so the Liver doesn't fail when verifying the original chain. raise SuccessError("Meros re-organized to the alternate chain.") #Create and execute a Liver. Liver( rpc, chains["main"], callbacks={ 3: sendAlternateTip } ).live()
def DelayedMeritHolderTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Merit/Reorganizations/DelayedMeritHolder.json", "r") chains: Dict[str, List[Dict[str, Any]]] = json.loads(file.read()) file.close() #Load the alternate blockchain. alt: Blockchain = Blockchain.fromJSON(chains["alt"]) #Send the alternate tip. def sendAlternateTip() -> None: header: bytes = rpc.meros.liveBlockHeader(alt.blocks[-1].header) req: bytes = rpc.meros.sync.recv() if MessageType(req[0]) != MessageType.BlockListRequest: raise TestError("Meros didn't request the list of previous BlockHeaders.") if req[3 : 35] != alt.blocks[-1].header.hash: raise TestError("Meros didn't request the list of previous BlockHeaders for THIS header.") blockList: List[bytes] = [] b: int = len(alt.blocks) - 2 while b != -1: blockList.append(alt.blocks[b].header.hash) b -= 1 rpc.meros.blockList(blockList) diff = -2 while diff != -1: req = rpc.meros.sync.recv() if req != (MessageType.BlockHeaderRequest.toByte() + alt.blocks[diff].header.hash): raise TestError("Meros didn't request a previous BlockHeader.") rpc.meros.syncBlockHeader(alt.blocks[diff].header) diff += 1 diff = -2 while diff != 0: req = rpc.meros.sync.recv() if req != (MessageType.BlockBodyRequest.toByte() + alt.blocks[diff].header.hash): raise TestError("Meros didn't request a previous BlockBody.") rpc.meros.blockBody(alt.blocks[diff]) diff += 1 if rpc.meros.live.recv() != header: raise TestError("Meros didn't send back the BlockHeader.") #Verify the alternate Blockchain. verifyBlockchain(rpc, alt) #Raise SuccessError so the Liver doesn't fail when verifying the original chain. raise SuccessError("Meros re-organized to the alternate chain.") #Create and execute a Liver. Liver( rpc, chains["main"], callbacks={ 6: sendAlternateTip } ).live()
def SendDifficultyTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/Difficulties/SendDifficulty.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Verify functions. vddStarting: Callable[[], None] = lambda: verifySendDifficulty(rpc, 3) vddEarnedVote: Callable[[], None] = lambda: verifySendDifficulty(rpc, 5) vddVoted: Callable[[], None] = lambda: verifySendDifficulty(rpc, 1) def vmr() -> None: verifyMeritRemoval(rpc, 52, 52, 0, False) vddStarting() def vEarnedBack() -> None: vddEarnedVote() #Create and execute a Liver/Syncer. Liver(rpc, vectors["blockchain"], callbacks={ 26: vddStarting, 50: vddEarnedVote, 51: vddVoted, 52: vmr, 102: vEarnedBack }).live() Syncer(rpc, vectors["blockchain"]).sync()
def HundredTwoTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Consensus/Verification/HundredTwo.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #Verifies the Transaction is added, it has the right holders, the holders Merit surpasses the threshold, yet it isn't verified. def verify() -> None: for tx in transactions.txs: status: Dict[str, Any] = rpc.call("consensus", "getStatus", [tx.hex()]) if set(status["verifiers"]) != set([0, 1]): raise TestError("Meros doesn't have the right list of verifiers for this Transaction.") if status["merit"] != 80: raise TestError("Meros doesn't have the right amount of Merit for this Transaction.") if rpc.call("merit", "getMerit", [0])["merit"] + rpc.call("merit", "getMerit", [1])["merit"] < status["threshold"]: raise TestError("Merit sum of holders is less than the threshold.") if status["verified"]: raise TestError("Meros verified the Transaction which won't have enough Merit by the time the Transaction finalizes.") #Create and execute a Liver. Liver(rpc, vectors["blockchain"], transactions, callbacks={100: verify}).live()
def VCompetingTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/Verification/Competing.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Blockchain. blockchain: Blockchain = Blockchain.fromJSON( b"MEROS_DEVELOPER_NETWORK", 60, int( "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16), vectors["blockchain"]) #Consensus. consensus: Consensus = Consensus.fromJSON( bytes.fromhex( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), bytes.fromhex( "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" ), vectors["consensus"]) #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #Create and execute a Liver/Syncer. Liver(rpc, blockchain, consensus, transactions).live() Syncer(rpc, blockchain, consensus, transactions).sync()
def ChainAdvancementTest(rpc: RPC) -> None: file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() #Create and execute a Liver/Syncer. Liver(rpc, blocks).live() Syncer(rpc, blocks).sync()
def InvalidCompetingTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Consensus/MeritRemoval/InvalidCompeting.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() keys: Dict[bytes, int] = { bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]): 0 } #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #MeritRemoval. #pylint: disable=no-member removal: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(keys, vectors["removal"]) #Create and execute a Liver to handle the MeritRemoval. def sendMeritRemoval() -> None: #Send and verify the MeritRemoval. removalBytes: bytes = rpc.meros.signedElement(removal) done: bool = False while True: try: msg: bytes = rpc.meros.recv() except TestError: raise TestError("Node disconnected us.") if MessageType(msg[0]) == MessageType.Syncing: rpc.meros.syncingAcknowledged() elif MessageType(msg[0]) == MessageType.TransactionRequest: rpc.meros.transaction(transactions.txs[msg[1 : 33]]) elif MessageType(msg[0]) == MessageType.SyncingOver: if done: break done = True if removalBytes != rpc.meros.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 11, 11, removal.holder, True) Liver( rpc, vectors["blockchain"], transactions, callbacks={ 11: sendMeritRemoval, 12: lambda: verifyMeritRemoval(rpc, 11, 11, removal.holder, False) } ).live() #Create and execute a Syncer to handle the MeritRemoval. Syncer(rpc, vectors["blockchain"], transactions).sync() verifyMeritRemoval(rpc, 11, 11, removal.holder, False)
def FiftyTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Transactions/Fifty.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Create and execute a Liver/Syncer. Liver(rpc, vectors["blockchain"], Transactions.fromJSON(vectors["transactions"])).live() Syncer(rpc, vectors["blockchain"], Transactions.fromJSON(vectors["transactions"])).sync()
def RepeatTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/Repeat.json", "r") vectors: List[Dict[str, Any]] = json.loads(file.read()) file.close() keys: Dict[bytes, int] = {bytes.fromhex(vectors[0]["header"]["miner"]): 0} def sendBlock() -> None: #Send the Block with the MeritRemoval archived again. block: Block = Block.fromJSON(keys, vectors[-1]) rpc.meros.blockHeader(block.header) #Flag of if the Block's Body synced. blockBodySynced: bool = False #Handle sync requests. reqHash: bytes = bytes() while True: try: msg: bytes = rpc.meros.recv() except TestError: if not blockBodySynced: raise TestError( "Node disconnected us before syncing the body.") raise SuccessError( "Meros didn't add the same MeritRemoval twice.") if MessageType(msg[0]) == MessageType.Syncing: rpc.meros.syncingAcknowledged() elif 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) elif MessageType(msg[0]) == MessageType.SyncingOver: pass elif MessageType(msg[0]) == MessageType.BlockHeader: #Raise a TestError if the Block was added. raise TestError( "Meros synced a Block with a repeat MeritRemoval.") else: raise TestError("Unexpected message sent: " + msg.hex().upper()) Liver(rpc, vectors, callbacks={3: sendBlock}).live()
def InvalidCompetingTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/InvalidCompeting.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #MeritRemoval. #pylint: disable=no-member removal: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON( vectors["removal"]) #Create and execute a Liver to handle the MeritRemoval. def sendMeritRemoval() -> None: #Send and verify the MeritRemoval. removalBytes: bytes = rpc.meros.signedElement(removal) sent: int = 0 while True: if sent == 2: break msg: bytes = rpc.meros.sync.recv() if MessageType(msg[0]) == MessageType.TransactionRequest: rpc.meros.syncTransaction(transactions.txs[msg[1:33]]) sent += 1 else: raise TestError("Unexpected message sent: " + msg.hex().upper()) if removalBytes != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 1, removal.holder, True) #Verify the MeritRemoval and the Blockchain. def verify() -> None: verifyMeritRemoval(rpc, 1, 1, removal.holder, False) verifyBlockchain(rpc, Blockchain.fromJSON(vectors["blockchain"])) raise SuccessError( "MeritRemoval and Blockchain were properly handled.") Liver(rpc, vectors["blockchain"], transactions, callbacks={ 1: sendMeritRemoval, 2: verify }).live()
def DifficultyTest(rpc: RPC) -> None: #Blocks. file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() #Blockchain. blockchain: Blockchain = Blockchain.fromJSON(blocks) def checkDifficulty(block: int) -> None: if int(rpc.call("merit", "getDifficulty"), 16) != blockchain.difficulties[block][0]: raise TestError("Difficulty doesn't match.") Liver(rpc, blocks, everyBlock=checkDifficulty).live()
def HundredFortySevenTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Transactions/ClaimedMint.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Merit. merit: Merit = Merit.fromJSON(vectors["blockchain"]) #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #Ed25519 keys. privKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) pubKey: ed25519.VerifyingKey = privKey.get_verifying_key() #Grab the Claim hash, claim: bytes = merit.blockchain.blocks[-1].body.packets[0].hash #Create a Send which underflows. send: Send = Send( [(claim, 0)], [ (pubKey.to_bytes(), 18446744073709551231), (pubKey.to_bytes(), 385 + Claim.fromTransaction(transactions.txs[claim]).amount) ] ) send.sign(privKey) send.beat(SpamFilter(3)) #Custom function to send the last Block and verify it errors at the right place. def checkFail() -> None: #Send the Send. rpc.meros.liveTransaction(send) #Handle sync requests. while True: #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 an invalid Transaction.") except Exception: raise TestError("Meros sent a keep-alive.") #Create and execute a Liver. Liver(rpc, vectors["blockchain"], transactions, callbacks={12: checkFail}).live()
def ChainAdvancementTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() blockchain: Blockchain = Blockchain.fromJSON( b"MEROS_DEVELOPER_NETWORK", 60, int("FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16), blocks ) #Create and execute a Liver/Syncer. Liver(rpc, blockchain).live() Syncer(rpc, blockchain).sync()
def PruneUnaddableTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/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 HundredFortyTwoTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/Verification/HundredFortyTwo.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #Function to verify the Transaction includes unarchived Merit before finalization. def verifyUnarchivedMerit() -> None: #Send the verification which won't be archived. if rpc.meros.signedElement( SignedVerification.fromSignedJSON( vectors["verification"])) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the SignedVerification.") status: Dict[str, Any] = rpc.call("consensus", "getStatus", [vectors["transaction"]]) if sorted(status["verifiers"]) != [0, 1]: raise TestError( "Status didn't include verifiers which have yet to be archived." ) if status["merit"] != 7: raise TestError( "Status didn't include Merit which has yet to be archived.") #Function to verify the Transaction doesn't include unarchived Merit after finalization. def verifyArchivedMerit() -> None: status: Dict[str, Any] = rpc.call("consensus", "getStatus", [vectors["transaction"]]) if status["verifiers"] != [0]: raise TestError( "Status included verifiers which were never archived.") if status["merit"] != 1: raise TestError("Status included Merit which was never archived.") #Create and execute a Liver. Liver(rpc, vectors["blockchain"], transactions, callbacks={ 7: verifyUnarchivedMerit, 8: verifyArchivedMerit }).live()
def RepeatTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/Repeat.json", "r") vectors: List[Dict[str, Any]] = json.loads(file.read()) file.close() def sendBlock() -> None: #Send the Block with the MeritRemoval archived again. block: Block = Block.fromJSON(vectors[-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: #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( "Meros didn't add the same MeritRemoval twice.") 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, callbacks={3: sendBlock}).live()
def MultipleTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Consensus/MeritRemoval/Multiple.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #MeritRemovals. removals: List[SignedMeritRemoval] = [ SignedMeritRemoval.fromSignedJSON(vectors["removals"][0]), SignedMeritRemoval.fromSignedJSON(vectors["removals"][1]) ] #Send and verify the MeritRemoval. def sendMeritRemovals() -> None: removalBuf: bytes = rpc.meros.signedElement(removals[0]) if removalBuf != rpc.meros.live.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 1, removals[0].holder, True) rpc.meros.signedElement(removals[1]) if removalBuf != rpc.meros.live.recv(): raise TestError("Meros didn't send us the first Merit Removal.") verifyMeritRemoval(rpc, 1, 1, removals[0].holder, True) #Verify the holder has 0 Merit and is marked as malicious. def verifyFirstMeritRemoval() -> None: verifyMeritRemoval(rpc, 0, 0, removals[0].holder, True) #Create and execute a Liver to handle the Signed MeritRemovals. Liver( rpc, vectors["blockchain"], callbacks={ 1: sendMeritRemovals, 2: verifyFirstMeritRemoval, 3: lambda: verifyMeritRemoval(rpc, 0, 0, removals[0].holder, False) } ).live() #Create and execute a Syncer to handle a Signed MeritRemoval. Syncer(rpc, vectors["blockchain"]).sync() verifyMeritRemoval(rpc, 0, 0, removals[0].holder, False)
def HundredTwentyTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/HundredTwenty.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #DataDifficulty for the mempool. #pylint: disable=no-member mempoolDataDiff: SignedDataDifficulty = SignedDataDifficulty.fromSignedJSON( vectors["mempoolDataDiff"]) #DataDifficulty for the Blockchain. #pylint: disable=no-member blockchainDataDiff: DataDifficulty = DataDifficulty.fromJSON( vectors["blockchainDataDiff"]) def sendDataDifficulty() -> None: #Send the Data Difficulty for the mempool. rpc.meros.signedElement(mempoolDataDiff) #Verify its sent back. if rpc.meros.live.recv() != (MessageType.SignedDataDifficulty.toByte() + mempoolDataDiff.signedSerialize()): raise TestError( "Meros didn't send us the mempool Data Difficulty.") def receiveMeritRemoval() -> None: #We should receive a MeritRemoval, which is partial. #The unsigned Element should be the Block's DataDifficulty. #The signed Element should be the mempool's DataDifficulty. if rpc.meros.live.recv() != ( MessageType.SignedMeritRemoval.toByte() + PartialMeritRemoval( blockchainDataDiff, mempoolDataDiff, 0).signedSerialize()): raise TestError("Meros didn't create the partial Merit Removal.") #Verify Meros didn't just broadcast it, yet also added it. verifyMeritRemoval(rpc, 1, 1, 0, False) Liver(rpc, vectors["blockchain"], callbacks={ 1: sendDataDifficulty, 2: receiveMeritRemoval }).live()
def HundredThirtyFiveTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/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 StateTest(rpc: RPC) -> None: #Blocks. file: IO[Any] = open("PythonTests/Vectors/Merit/StateBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() #Blockchain. blockchain: Blockchain = Blockchain.fromJSON(blocks) #State. state: State = State() def checkState(block: int) -> None: state.add(blockchain, block) for miner in state.unlocked: if rpc.call("merit", "getMerit", [miner]) != { "unlocked": True, "malicious": False, "merit": state.unlocked[miner] }: raise TestError("Merit doesn't match.") Liver(rpc, blocks, everyBlock=checkState).live()
def VUnknownTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/Verification/Parsable.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Merit. merit: Merit = Merit.fromJSON(vectors["blockchain"]) #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 attempts to sync our Transaction. syncedTX: bool = False #Grab the Block. block: Block = merit.blockchain.blocks[2] #Send the Block. 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, Verification." ) 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="big")): sketchHash: int = int.from_bytes(msg[37 + (h * 8):45 + (h * 8)], byteorder="big") 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: rpc.meros.dataMissing() syncedTX = True else: raise TestError("Unexpected message sent: " + msg.hex().upper()) #Create and execute a Liver. Liver(rpc, vectors["blockchain"], callbacks={1: checkFail}).live()
def MultipleTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/Multiple.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Blockchain blockchain: Blockchain = Blockchain.fromJSON( b"MEROS_DEVELOPER_NETWORK", 60, int( "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16), vectors["blockchain"]) #MeritRemovals. removal1: SignedMeritRemoval = SignedMeritRemoval.fromJSON( vectors["removal1"]) removal2: SignedMeritRemoval = SignedMeritRemoval.fromJSON( vectors["removal2"]) #Data. data: Data = Data.fromJSON(vectors["data"]) #Create and execute a Liver to cause multiple MeritRemovals. def sendElements() -> None: #Send the Data. if rpc.meros.transaction(data) != rpc.meros.recv(): raise TestError("Unexpected message sent.") #Send the first SignedElement. if rpc.meros.signedElement(removal1.se1) != rpc.meros.recv(): raise TestError("Unexpected message sent.") #Send the second. rpc.meros.signedElement(removal1.se2) #Verify the first MeritRemoval. if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() + removal1.signedSerialize()): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal1, True) #Send the third SignedElement. rpc.meros.signedElement(removal2.se2) #Meros should treat the first created MeritRemoval as the default MeritRemoval. if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() + removal1.signedSerialize()): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal1, True) Liver(rpc, blockchain, callbacks={ 1: sendElements, 2: lambda: verifyMeritRemoval(rpc, 1, 100, removal2, False) }).live() #Create and execute a Liver to handle multiple MeritRemovals. def sendMeritRemovals() -> None: #Send and verify the first MeritRemoval. msg = rpc.meros.signedElement(removal1) if msg != rpc.meros.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal1, True) #Send the second MeritRemoval. rpc.meros.signedElement(removal2) #Meros should treat the first created MeritRemoval as the default. if msg != rpc.meros.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal1, True) Liver(rpc, blockchain, callbacks={ 1: sendMeritRemovals, 2: lambda: verifyMeritRemoval(rpc, 1, 100, removal2, False) }).live()
def SameNonceTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/SameNonce.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Blockchain blockchain: Blockchain = Blockchain.fromJSON( b"MEROS_DEVELOPER_NETWORK", 60, int( "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16), vectors["blockchain"]) #MeritRemoval. removal: SignedMeritRemoval = SignedMeritRemoval.fromJSON( vectors["removal"]) #Consensus. consensus: Consensus = Consensus( bytes.fromhex( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), bytes.fromhex( "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" )) consensus.add(removal) #Data. data: Data = Data.fromJSON(vectors["data"]) #Create and execute a Liver to cause a SameNonce MeritRemoval. def sendElements() -> None: #Send the Data/SignedVerifications. if rpc.meros.transaction(data) != rpc.meros.recv(): raise TestError("Unexpected message sent.") if rpc.meros.signedElement(removal.se1) != rpc.meros.recv(): raise TestError("Unexpected message sent.") rpc.meros.signedElement(removal.se2) #Verify the MeritRemoval. if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() + removal.signedSerialize()): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal, True) Liver(rpc, blockchain, consensus, callbacks={ 1: sendElements, 2: lambda: verifyMeritRemoval(rpc, 1, 100, removal, False) }).live() #Create and execute a Liver to handle a SameNonce MeritRemoval. def sendMeritRemoval() -> None: #Send and verify the MeritRemoval. if rpc.meros.signedElement(removal) != rpc.meros.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal, True) Liver(rpc, blockchain, consensus, callbacks={ 1: sendMeritRemoval, 2: lambda: verifyMeritRemoval(rpc, 1, 100, removal, False) }).live() #Create and execute a Syncer to handle a SameNonce MeritRemoval. Syncer(rpc, blockchain, consensus).sync() verifyMeritRemoval(rpc, 1, 100, removal, False)
def VerifyCompetingTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/VerifyCompeting.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() keys: Dict[bytes, int] = { bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]): 0 } nicks: List[bytes] = [ bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]) ] #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( keys, 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.transaction(data) != rpc.meros.recv(): raise TestError("Meros didn't send us the Data.") #Send the initial Data's verification. if rpc.meros.signedElement(verif) != rpc.meros.recv(): raise TestError("Meros didn't us the initial Data's Verification.") #Send the first Element. if rpc.meros.signedElement(removal.se1) != rpc.meros.recv(): raise TestError("Meros didn't send us the Verification.") #Trigger the MeritRemoval. rpc.meros.signedElement(removal.se2) if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() + removal.signedSerialize(nicks)): 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.transaction(data) != rpc.meros.recv(): raise TestError("Meros didn't send us the Data.") #Send the initial Data's verification. if rpc.meros.signedElement(verif) != rpc.meros.recv(): raise TestError("Meros didn't us the initial Data's Verification.") #Send and verify the MeritRemoval. if rpc.meros.signedElement(removal) != rpc.meros.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 testBlockchain(i: int) -> None: #First MeritRemoval. mr: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON( vectors["removals"][i]) 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 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) def sendRepeatMeritRemoval() -> None: #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 3. #The genesis Block, the Block granting Merit, and the Block containing the MeritRemoval originally. try: if rpc.call("merit", "getHeight") != 3: 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, 2: sendRepeatMeritRemoval }).live()
def PendingActionsTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/PendingActions.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Blockchain. blockchain: Blockchain = Blockchain.fromJSON( b"MEROS_DEVELOPER_NETWORK", 60, int( "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16), vectors["blockchain"]) #SignedVerifications. verifs: List[SignedVerification] = [] for verif in vectors["verifications"]: verifs.append(SignedVerification.fromJSON(verif)) #Removal. removal: SignedMeritRemoval = SignedMeritRemoval.fromJSON( vectors["removal"]) #Datas. datas: List[Data] = [] for data in vectors["datas"]: datas.append(Data.fromJSON(data)) #Send every Data/Verification. def sendDatasAndVerifications() -> None: #Send the Datas. for data in datas: if rpc.meros.transaction(data) != rpc.meros.recv(): raise TestError("Unexpected message sent.") #Send the Verifications. for verif in verifs: if rpc.meros.signedElement(verif) != rpc.meros.recv(): raise TestError("Unexpected message sent.") #Verify every Data has 100 Merit. for data in datas: if rpc.call("consensus", "getStatus", [data.hash.hex()])["merit"] != 100: raise TestError( "Meros didn't verify Transactions with received Verifications." ) #Cause a MeritRemoval. def causeMeritRemoval() -> None: #Send every Data/;Verification. sendDatasAndVerifications() #Send the problem Verification and verify the MeritRemoval. rpc.meros.signedElement(removal.se2) if rpc.meros.recv() != MessageType.SignedMeritRemoval.toByte( ) + removal.signedSerialize(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal, True) #Verify every Data has 0 Merit. for data in datas: if rpc.call("consensus", "getStatus", [data.hash.hex()])["merit"] != 0: raise TestError( "Meros didn't revert pending actions of a malicious MeritHolder." ) #Send a MeritRemoval. def sendMeritRemoval() -> None: #Send every Data/;Verification. sendDatasAndVerifications() #Send and verify the MeritRemoval. if rpc.meros.signedElement(removal) != rpc.meros.recv(): raise TestError("Meros didn't send us the Merit Removal.") verifyMeritRemoval(rpc, 1, 100, removal, True) #Verify every Data has 0 Merit. for data in datas: if rpc.call("consensus", "getStatus", [data.hash.hex()])["merit"] != 0: raise TestError( "Meros didn't revert pending actions of a malicious MeritHolder." ) #Check the Data's finalized with the proper amount of Merit and update the MeritRemoval. def check() -> None: #Verify the Datas have the Merit they should. for data in datas: if rpc.call("consensus", "getStatus", [data.hash.hex()])["merit"] != 0: raise TestError( "Meros didn't finalize with the reverted pending actions of a malicious MeritHolder." ) #Update the MeritRemoval's nonce. removal.nonce = 6 #Verify the MeritRemoval is now accessible with a nonce of 6. verifyMeritRemoval(rpc, 7, 0, removal, False) #Create and execute a Liver to cause a MeritRemoval. Liver(rpc, blockchain, callbacks={1: causeMeritRemoval, 7: check}).live() #Reset the MeritRemoval nonce. removal.nonce = 0 #Create and execute a Liver to handle a MeritRemoval. Liver(rpc, blockchain, callbacks={1: sendMeritRemoval, 7: check}).live()
def CompetingFinalizedTest( rpc: RPC ) -> None: file: IO[Any] = open("PythonTests/Vectors/Transactions/CompetingFinalized.json", "r") vectors: Dict[str, Any] = json.loads(file.read()) file.close() #Merit. merit: Merit = Merit.fromJSON(vectors["blockchain"]) #Transactions. transactions: Transactions = Transactions.fromJSON(vectors["transactions"]) #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 #Grab the Block. block: Block = merit.blockchain.blocks[-1] #Send the Block. rpc.meros.blockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: try: msg: bytes = rpc.meros.recv() except TestError: if syncedTX: raise SuccessError("Node disconnected us after we sent an invalid Transaction.") raise TestError("Node errored before syncing our Transaction.") if MessageType(msg[0]) == MessageType.Syncing: rpc.meros.syncingAcknowledged() elif 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(merit.state.nicks, 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="big")): sketchHash: int = int.from_bytes(msg[37 + (h * 8) : 45 + (h * 8)], byteorder="big") 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.transaction(transactions.txs[reqHash]) syncedTX = True elif MessageType(msg[0]) == MessageType.SyncingOver: pass elif MessageType(msg[0]) == MessageType.BlockHeader: #Raise a TestError if the Block was added. raise TestError("Meros synced a Transaction which competed with a finalized Transaction.") else: raise TestError("Unexpected message sent: " + msg.hex().upper()) #Create and execute a Liver. Liver(rpc, vectors["blockchain"], transactions, callbacks={7: checkFail}).live()