def fromSignedJSON(keys: Dict[bytes, int], jsonArg: Dict[str, Any]) -> Any: json: Dict[str, Any] = dict(jsonArg) json["elements"] = list(json["elements"]) json["elements"][0] = dict(json["elements"][0]) json["elements"][1] = dict(json["elements"][1]) json["elements"][0]["holder"] = json["holder"] json["elements"][1]["holder"] = json["holder"] e1: Union[SignedVerification, SignedVerificationPacket, SignedSendDifficulty, SignedDataDifficulty] = SignedVerification(bytes(32), 0) if json["elements"][0]["descendant"] == "Verification": e1 = SignedVerification.fromSignedJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "VerificationPacket": json["elements"][0]["holders"] = list( json["elements"][0]["holders"]) for h in range(len(json["elements"][0]["holders"])): json["elements"][0]["holders"][h] = keys[bytes.fromhex( json["elements"][0]["holders"][h])] e1 = SignedVerificationPacket.fromSignedJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "SendDifficulty": e1 = SignedSendDifficulty.fromSignedJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "DataDifficulty": e1 = SignedDataDifficulty.fromSignedJSON(json["elements"][0]) e2: Union[SignedVerification, SignedVerificationPacket, SignedSendDifficulty, SignedDataDifficulty] = SignedVerification(bytes(32), 0) if json["elements"][1]["descendant"] == "Verification": e2 = SignedVerification.fromSignedJSON(json["elements"][1]) elif json["elements"][1]["descendant"] == "VerificationPacket": json["elements"][1]["holders"] = list( json["elements"][1]["holders"]) for h in range(len(json["elements"][1]["holders"])): json["elements"][1]["holders"][h] = keys[bytes.fromhex( json["elements"][1]["holders"][h])] e2 = SignedVerificationPacket.fromSignedJSON(json["elements"][1]) elif json["elements"][1]["descendant"] == "SendDifficulty": e2 = SignedSendDifficulty.fromSignedJSON(json["h"][1]) elif json["elements"][1]["descendant"] == "DataDifficulty": e2 = SignedDataDifficulty.fromSignedJSON(json["elements"][1]) return SignedMeritRemoval(e1, e2)
def fromSignedJSON(jsonArg: Dict[str, Any]) -> Any: json: Dict[str, Any] = dict(jsonArg) json["elements"] = list(json["elements"]) json["elements"][0] = dict(json["elements"][0]) json["elements"][1] = dict(json["elements"][1]) json["elements"][0]["holder"] = json["holder"] json["elements"][1]["holder"] = json["holder"] e1: Union[SignedVerification, SignedMeritRemovalVerificationPacket, SignedSendDifficulty, SignedDataDifficulty] = SignedVerification(bytes(32), 0) if json["elements"][0]["descendant"] == "Verification": e1 = SignedVerification.fromSignedJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "VerificationPacket": e1 = SignedMeritRemovalVerificationPacket.fromSignedJSON( json["elements"][0]) elif json["elements"][0]["descendant"] == "SendDifficulty": e1 = SignedSendDifficulty.fromSignedJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "DataDifficulty": e1 = SignedDataDifficulty.fromSignedJSON(json["elements"][0]) e2: Union[SignedVerification, SignedMeritRemovalVerificationPacket, SignedSendDifficulty, SignedDataDifficulty] = SignedVerification(bytes(32), 0) if json["elements"][1]["descendant"] == "Verification": e2 = SignedVerification.fromSignedJSON(json["elements"][1]) elif json["elements"][1]["descendant"] == "VerificationPacket": e2 = SignedMeritRemovalVerificationPacket.fromSignedJSON( json["elements"][1]) elif json["elements"][1]["descendant"] == "SendDifficulty": e2 = SignedSendDifficulty.fromSignedJSON(json["elements"][1]) elif json["elements"][1]["descendant"] == "DataDifficulty": e2 = SignedDataDifficulty.fromSignedJSON(json["elements"][1]) return SignedMeritRemoval(e1, e2, json["holder"])
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 HundredSixSignedElementsTest(rpc: RPC) -> None: #Blockchain. Solely used to get the genesis Block hash. blockchain: Blockchain = Blockchain() #BLS Key. blsPrivKey: PrivateKey = PrivateKey( blake2b(b'\0', digest_size=32).digest()) sig: Signature = blsPrivKey.sign(bytes()) #Create a Data. #This is required so the Verification isn't terminated early for having an unknown hash. data: bytes = bytes.fromhex(rpc.call("personal", "data", ["AA"])) #Create a signed Verification, SendDifficulty, and DataDifficulty. elements: List[SignedElement] = [ SignedVerification(data, 1, sig), SignedSendDifficulty(bytes.fromhex("00" * 32), 0, 1, sig), SignedDataDifficulty(bytes.fromhex("00" * 32), 0, 1, sig) ] for elem in elements: #Handshake with the node. rpc.meros.connect(254, 254, blockchain.blocks[0].header.hash) #Send the Element. rpc.meros.signedElement(elem) #Sleep for a bit. sleep(0.2) #Verify the node didn't crash. try: if rpc.call("merit", "getHeight") != 1: raise Exception() except Exception: raise TestError( "Node crashed after being sent a malformed Element.")
blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Generate a Block granting the holder Merit. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), blsPubKey.serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody()) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Same Nonce Block " + str(len(blockchain.blocks)) + ".") #Create a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty(3, 0) dataDiff.sign(0, blsPrivKey) #Create a conflicting DataDifficulty with the same nonce. dataDiffConflicting = SignedDataDifficulty(1, 0) dataDiffConflicting.sign(0, blsPrivKey) #Create a MeritRemoval out of the two of them. mr: SignedMeritRemoval = SignedMeritRemoval(dataDiff, dataDiffConflicting) #Generate a Block containing the MeritRemoval. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([], [mr]), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([], [mr], mr.signature))
blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Generate a Block granting the holder Merit. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), blsPubKey.serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody()) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Partial Block " + str(len(blockchain.blocks)) + ".") #Create a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty(bytes.fromhex("AA" * 32), 0) dataDiff.sign(0, blsPrivKey) #Generate a Block containing the DataDifficulty. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([], [], [dataDiff]), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([], [dataDiff], dataDiff.signature)) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Partial Block " + str(len(blockchain.blocks)) + ".")
#Generate a Block granting the holder Merit. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), blsPubKey.serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody()) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Hundred Twenty Three Swap Block " + str(len(blockchain.blocks)) + ".") #Create conflicting Data Difficulties. dataDiffs: List[SignedDataDifficulty] = [ SignedDataDifficulty(3, 0), SignedDataDifficulty(4, 0) ] dataDiffs[0].sign(0, blsPrivKey) dataDiffs[1].sign(0, blsPrivKey) #Create a MeritRemoval out of the conflicting Data Difficulties. mr: SignedMeritRemoval = SignedMeritRemoval(dataDiffs[0], dataDiffs[1]) #Generate a Block containing the MeritRemoval. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([], [mr]), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([], [mr], mr.signature)) #Mine it.
def TElementTest(rpc: RPC) -> None: #BLS key. blsPrivKey: PrivateKey = PrivateKey( blake2b(b'\0', digest_size=32).digest()) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() #Blocks. file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() #Merit. merit: Merit = Merit() #Handshake with the node. rpc.meros.connect(254, 254, merit.blockchain.blocks[0].header.hash) #Send the first Block. block: Block = Block.fromJSON(merit.blockchain.keys, blocks[0]) merit.blockchain.add(block) rpc.meros.blockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: msg: bytes = rpc.meros.recv() 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.SyncingOver: pass elif MessageType(msg[0]) == MessageType.BlockHeader: break else: raise TestError("Unexpected message sent: " + msg.hex().upper()) #Create and transmit a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty( bytes.fromhex("00" * 32), 0, 0) dataDiff.sign(0, blsPrivKey) rpc.meros.signedElement(dataDiff) sleep(0.5) #Verify the block template has the DataDifficulty. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, [], [dataDiff]): raise TestError("Block template doesn't have the Data Difficulty.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(merit.state.nicks, [], [dataDiff]), 1, template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], []), 0, int.from_bytes(template["header"][-4:], byteorder="big"), ), BlockBody([], [dataDiff], dataDiff.signature)) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(merit.state.nicks, block.header.sketchSalt) != bytes.fromhex( template["body"]): raise TestError("Failed to recreate the body.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) #Publish it. rpc.call("merit", "publishBlock", [ template["id"], (template["header"] + block.header.proof.to_bytes(4, byteorder="big") + block.header.signature + block.body.serialize( merit.state.nicks, block.header.sketchSalt)).hex() ]) #Create and transmit a new DataDifficulty. dataDiff = SignedDataDifficulty(bytes.fromhex("AA" * 32), 1, 0) dataDiff.sign(0, blsPrivKey) rpc.meros.signedElement(dataDiff) sleep(0.5) #Verify the block template has the DataDifficulty. template = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, [], [dataDiff]): raise TestError("Block template doesn't have the new Data Difficulty.") #Create and transmit a new DataDifficulty reusing an existing nonce. signatures: List[Signature] = [dataDiff.signature] dataDiff = SignedDataDifficulty(bytes.fromhex("BB" * 32), 1, 0) dataDiff.sign(0, blsPrivKey) signatures.append(dataDiff.signature) rpc.meros.signedElement(dataDiff) sleep(0.5) #Verify the block template has a MeritRemoval. mr: MeritRemoval = MeritRemoval( SignedDataDifficulty(bytes.fromhex("AA" * 32), 1, 0), SignedDataDifficulty(bytes.fromhex("BB" * 32), 1, 0), False) template = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, [], [mr]): raise TestError("Block template doesn't have the Merit Removal.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(merit.state.nicks, [], [mr]), 1, template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], []), 0, int.from_bytes(template["header"][-4:], byteorder="big"), ), BlockBody([], [mr], Signature.aggregate(signatures))) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(merit.state.nicks, block.header.sketchSalt) != bytes.fromhex( template["body"]): raise TestError("Failed to recreate the body.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) #Publish it. rpc.call("merit", "publishBlock", [ template["id"], (template["header"] + block.header.proof.to_bytes(4, byteorder="big") + block.header.signature + block.body.serialize( merit.state.nicks, block.header.sketchSalt)).hex() ]) #Verify the Blockchain. verifyBlockchain(rpc, merit.blockchain)
#JSON standard lib. import json #Blockchain. bbFile: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(bbFile.read()) blockchain: Blockchain = Blockchain.fromJSON(blocks) bbFile.close() #BLS Keys. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Create a DataDifficulty. dataDiffs: List[SignedDataDifficulty] = [ SignedDataDifficulty(3, 0), SignedDataDifficulty(1, 1) ] for dataDiff in dataDiffs: dataDiff.sign(0, blsPrivKey) #Generate a Block containing the DataDifficulty. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([], [dataDiffs[0]]), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([], [dataDiffs[0]], dataDiffs[0].signature)) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it.
blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Generate a Block granting the holder Merit. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), blsPubKey.serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody()) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Hundred Twenty Block " + str(len(blockchain.blocks)) + ".") #Create a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty(3, 0) dataDiff.sign(0, blsPrivKey) #Create a conflicting DataDifficulty with the same nonce. dataDiffConflicting = SignedDataDifficulty(1, 0) dataDiffConflicting.sign(0, blsPrivKey) #Generate a Block containing the competing Data difficulty. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([], [dataDiffConflicting]), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([], [dataDiffConflicting], dataDiffConflicting.signature)) #Mine it. block.mine(blsPrivKey, blockchain.difficulty())
#JSON standard lib. import json #Blockchain. bbFile: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(bbFile.read()) blockchain: Blockchain = Blockchain.fromJSON(blocks) bbFile.close() #BLS Keys. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Create a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty(bytes.fromhex("AA" * 32), 0) dataDiff.sign(0, blsPrivKey) #Generate a Block containing the DataDifficulty. block = Block( BlockHeader( 0, blockchain.last(), BlockHeader.createContents([], [], [dataDiff]), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200 ), BlockBody([], [dataDiff], dataDiff.signature)
), BlockBody() ) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Same Element Block " + str(len(blockchain.blocks)) + ".") #Create a SendDifficulty. sendDiff: SignedSendDifficulty = SignedSendDifficulty(4, 0) sendDiff.sign(0, blsPrivKey) #Create a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty(4, 0) dataDiff.sign(0, blsPrivKey) #Create a Data. data: Data = Data(bytes(32), edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(SpamFilter(5)) #Create a Verification. verif: SignedVerification = SignedVerification(data.hash) verif.sign(0, blsPrivKey) #Create a MeritRemovalVerificationPacket verifying the same Transaction as the Verification. packet: SignedMeritRemovalVerificationPacket = SignedMeritRemovalVerificationPacket( SignedVerificationPacket(data.hash), [blsPubKey.serialize()],