def fromJSON( sendDiff: bytes, dataDiff: bytes, json: Dict[str, List[Dict[str, Any]]] ) -> Any: result = Consensus(sendDiff, dataDiff) for mh in json: for elem in json[mh]: if "signed" in elem: if elem["descendant"] == "Verification": result.add(SignedVerification.fromJSON(elem)) elif elem["descendant"] == "MeritRemoval": if elem["partial"]: result.add(PartiallySignedMeritRemoval.fromJSON(elem)) else: result.add(SignedMeritRemoval.fromJSON(elem)) else: raise Exception("JSON has an unsupported Element type: " + elem["descendant"]) else: if elem["descendant"] == "Verification": result.add(Verification.fromJSON(elem)) elif elem["descendant"] == "MeritRemoval": result.add(MeritRemoval.fromJSON(elem)) else: raise Exception("JSON has an unsupported Element type: " + elem["descendant"]) return result
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 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 fromJSON(json: Dict[str, Any]) -> Any: se1: SignedElement = SignedElement() if json["elements"][0]["descendant"] == "Verification": se1 = SignedVerification.fromJSON(json["elements"][0]) else: raise Exception( "MeritRemoval constructed from an unsupported type of Element: " + json["elements"][0]["descendant"]) se2: SignedElement = SignedElement() if json["elements"][1]["descendant"] == "Verification": se2 = SignedVerification.fromJSON(json["elements"][1]) else: raise Exception( "MeritRemoval constructed from an unsupported type of Element: " + json["elements"][1]["descendant"]) result: SignedMeritRemoval = SignedMeritRemoval(se1, se2) result.nonce = json["nonce"] return result
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 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.")
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.")
block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Invalid Competing Block " + str(len(blockchain.blocks)) + ".") #Create a Data using a bogus input. data: Data = Data(bytes.fromhex("11" * 32), bytes(1)) transactions.add(data) #Create a competing Data using the same input. competingData: Data = Data(bytes.fromhex("11" * 32), bytes(2)) transactions.add(competingData) #Verify the Datas. verif: SignedVerification = SignedVerification(data.hash) verif.sign(0, blsPrivKey) competingVerif: SignedVerification = SignedVerification(competingData.hash) competingVerif.sign(0, blsPrivKey) #Create a MeritRemoval out of the conflicting Verifications. mr: SignedMeritRemoval = SignedMeritRemoval(verif, competingVerif) #Generate a Block containing the MeritRemoval. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([], [mr]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), []), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([], [mr], mr.signature)) #Mine it.
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()
for i in range(1): merit.add(Block.fromJSON(blankBlocks[i])) #Create the Data and a successor. first: Data = Data(bytes(32), edPubKey.to_bytes()) first.sign(edPrivKey) first.beat(dataFilter) transactions.add(first) second: Data = Data(first.hash, bytes(1)) second.sign(edPrivKey) second.beat(dataFilter) transactions.add(second) #Verify them. firstVerif: SignedVerification = SignedVerification(first.hash) firstVerif.sign(0, blsPrivKey) secondVerif: SignedVerification = SignedVerification(second.hash) secondVerif.sign(0, blsPrivKey) packets: List[VerificationPacket] = [ VerificationPacket(first.hash, [0]), VerificationPacket(second.hash, [0]), ] #Generate another 6 Blocks. #Next block should have the packets. block: Block = Block( BlockHeader(0, merit.blockchain.last(), BlockHeader.createContents(packets), 1, bytes(4),
#BLS keys. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Add 5 Blank Blocks. for i in range(5): merit.add(Block.fromJSON(merit.blockchain.keys, blankBlocks[i])) #Create the Data. data: Data = Data(bytes(32), edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) #Verify it. verif: SignedVerification = SignedVerification(data.hash) verif.sign(0, blsPrivKey) #Generate another 6 Blocks. #Next block should have a packet. block: Block = Block( BlockHeader( 0, merit.blockchain.last(), BlockHeader.createContents([], [VerificationPacket(verif.hash, [0])]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [VerificationPacket(verif.hash, [0])]), 0, merit.blockchain.blocks[-1].header.time + 1200 ),
#Create two competing Sends. packets: List[VerificationPacket] = [] toAggregate: List[Signature] = [] verif: SignedVerification for i in range(2): send: Send = Send( [(claim, 0)], [(edPubKeys[i].to_bytes(), Claim.fromTransaction(transactions.txs[claim]).amount)]) send.sign(edPrivKey) send.beat(sendFilter) transactions.add(send) packets.append(VerificationPacket(send.hash, [i])) verif = SignedVerification(send.hash) verif.sign(i, blsPrivKeys[i]) toAggregate.append(verif.signature) #Archive the Packets and close the Epoch. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents(packets), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0, blockchain.blocks[-1].header.time + 1200), BlockBody(packets, [], Signature.aggregate(toAggregate))) for _ in range(6): #Mine it. block.mine(blsPrivKeys[0], blockchain.difficulty()) #Add it. blockchain.add(block)
pubKey: blspy.PublicKey = privKey.get_public_key() #Load a Multiple Block and load their MeritRemoval. snFile: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/SameNonce.json", "r") snVectors: Dict[str, Any] = json.loads(snFile.read()) blockchain.add(Block.fromJSON(snVectors["blockchain"][0])) removal1: SignedMeritRemoval = SignedMeritRemoval.fromJSON( snVectors["removal"]) snFile.close() #Create a second MeritRemoval. sv: SignedVerification = SignedVerification(b'\1' * 48) sv.sign(privKey, 0) removal2: SignedMeritRemoval = SignedMeritRemoval( removal1.se1, SignedElement.fromElement(sv)) #Add the second MeritRemoval to Consensus. consensus.add(removal2) #Generate a Block with the second MeritRemoval. block: Block = Block( BlockHeader(2, blockchain.last(), int(time()), consensus.getAggregate([(pubKey, 0, -1)])), BlockBody([(pubKey, 0, consensus.getMerkle(pubKey, 0))])) #Mine it. block.mine(blockchain.difficulty())
#BLS keys. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Add 5 Blank Blocks. for i in range(5): merit.add(Block.fromJSON(merit.blockchain.keys, blankBlocks[i])) #Create the Data. data: Data = Data(bytes(32), edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) #Verify it. verif: SignedVerification = SignedVerification(data.hash) verif.sign(0, blsPrivKey) #Generate another 6 Blocks. #Next block should have a packet. block: Block = Block( BlockHeader( 0, merit.blockchain.last(), BlockHeader.createContents([], [VerificationPacket(verif.hash, [0])]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [VerificationPacket(verif.hash, [0])]), 0, merit.blockchain.blocks[-1].header.time + 1200), BlockBody([VerificationPacket(verif.hash, [0])], [], verif.signature)) for _ in range(6):
#Create the Datas. datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())] datas.append(Data(datas[-1].hash, bytes(1))) datas.append(Data(datas[-1].hash, bytes(1))) datas.append(Data(datas[-1].hash, bytes(1))) for data in datas: data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) #Verify them. verifs: List[List[SignedVerification]] = [] for data in datas: verifs.append( [SignedVerification(data.hash), SignedVerification(data.hash)]) for v in range(2): verifs[-1][v].sign(v, blsPrivKeys[v]) #Create the packets. packets: List[SignedVerificationPacket] = [] for packet in verifs: packets.append( SignedVerificationPacket( packet[0].hash, [0, 1], Signature.aggregate([packet[0].signature, packet[1].signature]))) #Create Blocks containing these packets. for packet in packets: block = Block(
privKey: blspy.PrivateKey = blspy.PrivateKey.from_seed(b'\0') pubKey: blspy.PublicKey = privKey.get_public_key() #Add a single Block to create Merit. bbFile: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(bbFile.read()) blockchain.add(Block.fromJSON(blocks[0])) bbFile.close() #Create a Data with an invalid signature. data: Data = Data(edPubKey.to_bytes().rjust(48, b'\0'), bytes()) data.signature = edPrivKey.sign(b"INVALID") data.beat(consensus.dataFilter) #Create a Verification. sv: SignedVerification = SignedVerification(data.hash) sv.sign(privKey, 0) consensus.add(sv) #Generate another Block. block: Block = Block( BlockHeader( 2, blockchain.last(), int(time()), consensus.getAggregate([(pubKey, 0, -1)]) ), BlockBody([(pubKey, 0, consensus.getMerkle(pubKey, 0))]) ) #Mine it. block.mine(blockchain.difficulty())
packets: Dict[int, VerificationPacket] toAggregate: List[Signature] #Add each Block. for order in orders: #Clear old data. packets = {} toAggregate = [] for h in order[0]: for s in order[0][h]: if s not in packets: packets[s] = VerificationPacket(sends[s].hash, []) packets[s].holders.append(h) verif: SignedVerification = SignedVerification(sends[s].hash) verif.sign(h, blsPrivKeys[h]) toAggregate.append(verif.signature) block: Block = Block( BlockHeader( 0, blockchain.last(), BlockHeader.createContents([], list(packets.values())), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), list(packets.values())), order[1], blockchain.blocks[-1].header.time + 1200 ), BlockBody(list(packets.values()), [], Signature.aggregate(toAggregate))
blockchain.add(Block.fromJSON(blocks[0])) bbFile.close() #Create a Data per key. datas: List[Data] = [] for edPrivKey in edKeys: datas.append( Data(edPrivKey.get_verifying_key().to_bytes().rjust(48, b'\0'), bytes())) datas[-1].sign(edPrivKey) datas[-1].beat(consensus.dataFilter) #Create 1 Verification per Data. verifs: List[SignedVerification] = [] for d in range(len(datas)): verifs.append(SignedVerification(datas[d].hash)) verifs[-1].sign(privKey, d) consensus.add(verifs[-1]) #Create a MeritRemoval off the last one. sv: SignedVerification = SignedVerification(b'\0' * 48) sv.sign(privKey, 5) removal: SignedMeritRemoval = SignedMeritRemoval( SignedElement.fromElement(verifs[5]), SignedElement.fromElement(sv)) consensus.add(removal) #Generate a Block with the Verifications. block: Block = Block( BlockHeader(2, blockchain.last(), int(time()), consensus.getAggregate([(pubKey, 0, 5)])), BlockBody([(pubKey, 5, consensus.getMerkle(pubKey, 0, 5))]))
edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() #Add a single Block to create Merit. bbFile: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(bbFile.read()) blockchain.add(Block.fromJSON(blocks[0])) bbFile.close() #Create a Data to verify. data: Data = Data(edPubKey.to_bytes().rjust(48, b'\0'), bytes()) data.sign(edPrivKey) data.beat(consensus.dataFilter) #Create two Verifications with the same nonce, yet for the different Datas. sv1: SignedVerification = SignedVerification(data.hash) sv1.sign(privKey, 0) sv2: SignedVerification = SignedVerification(b'\0' * 48) sv2.sign(privKey, 0) removal: SignedMeritRemoval = SignedMeritRemoval( SignedElement.fromElement(sv1), SignedElement.fromElement(sv2)) consensus.add(removal) #Generate another Block. block: Block = Block( BlockHeader(2, blockchain.last(), int(time()), consensus.getAggregate([(pubKey, 0, -1)])), BlockBody([(pubKey, 0, consensus.getMerkle(pubKey, 0))])) #Mine it.
blsPubKey.serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody()) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Prune Unaddable Block " + str(len(blockchain.blocks)) + ".") #Create the original Data. datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())] datas[0].sign(edPrivKey) datas[0].beat(dataFilter) #Verify it. verifs: List[SignedVerification] = [SignedVerification(datas[0].hash)] verifs[0].sign(0, blsPrivKey) #Create two competing Datas yet only verify the first. for d in range(2): datas.append(Data(datas[0].hash, d.to_bytes(1, "big"))) datas[1 + d].sign(edPrivKey) datas[1 + d].beat(dataFilter) verifs.append(SignedVerification(datas[1].hash)) verifs[1].sign(0, blsPrivKey) #Create a Data that's a descendant of the Data which will be beaten. datas.append(Data(datas[2].hash, (2).to_bytes(1, "big"))) datas[3].sign(edPrivKey) datas[3].beat(dataFilter)
block: Block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), blsPubKeys[1].serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody()) block.mine(blsPrivKeys[1], blockchain.difficulty()) blockchain.add(block) print("Generated Hundred Forty Two Block " + str(len(blockchain.blocks)) + ".") #Create a Data and verify it by both parties. data: Data = Data(bytes(32), edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(spamFilter) transactions.add(data) verifs: List[SignedVerification] = [ SignedVerification(data.hash), SignedVerification(data.hash) ] verifs[0].sign(0, blsPrivKeys[0]) verifs[1].sign(1, blsPrivKeys[1]) packets: List[VerificationPacket] = [VerificationPacket(data.hash, [0])] block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents(packets), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 1, blockchain.blocks[-1].header.time + 1200), BlockBody(packets, [], verifs[0].signature)) for _ in range(6): block.mine(blsPrivKeys[1], blockchain.difficulty()) blockchain.add(block) print("Generated Hundred Forty Two Block " + str(len(blockchain.blocks)) +
def VParsableTest(rpc: RPC) -> None: file: IO[Any] = open( "PythonTests/Vectors/Consensus/Verification/Parsable.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( bytes.fromhex( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), bytes.fromhex( "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" ), ) consensus.add(SignedVerification.fromJSON(vectors["verification"])) #Transactions. transactions: Transactions = Transactions() transactions.add(Data.fromJSON(vectors["data"])) #Handshake with the node. rpc.meros.connect(254, 254, 3) sentLast: bool = False reqHash: bytes = bytes() msg: bytes = bytes() height: int = 0 while True: try: msg = rpc.meros.recv() except TestError as e: if (not sentLast) or (str(e) != "Node disconnected us as a peer."): raise e break if MessageType(msg[0]) == MessageType.Syncing: rpc.meros.acknowledgeSyncing() elif MessageType(msg[0]) == MessageType.GetBlockHash: height = int.from_bytes(msg[1:5], "big") if height == 0: rpc.meros.blockHash(blockchain.last()) else: if height >= len(blockchain.blocks): raise TestError( "Meros asked for a Block Hash we do not have.") rpc.meros.blockHash(blockchain.blocks[height].header.hash) elif MessageType(msg[0]) == MessageType.BlockHeaderRequest: reqHash = msg[1:49] for block in blockchain.blocks: if block.header.hash == reqHash: rpc.meros.blockHeader(block.header) break if block.header.hash == blockchain.last(): raise TestError( "Meros asked for a Block Header we do not have.") elif MessageType(msg[0]) == MessageType.BlockBodyRequest: reqHash = msg[1:49] for block in blockchain.blocks: if block.header.hash == reqHash: rpc.meros.blockBody(block.body) break if block.header.hash == blockchain.last(): raise TestError( "Meros asked for a Block Body we do not have.") elif MessageType(msg[0]) == MessageType.ElementRequest: holder: bytes = msg[1:49] rpc.meros.element(consensus.holders[holder][int.from_bytes( msg[49:53], "big")]) elif MessageType(msg[0]) == MessageType.TransactionRequest: sentLast = True rpc.meros.transaction(transactions.txs[msg[1:49]]) elif MessageType(msg[0]) == MessageType.SyncingOver: pass else: raise TestError("Unexpected message sent: " + msg.hex().upper())
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)
b"MEROS_DEVELOPER_NETWORK", 60, int( "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16)) #BLS Public Key. pubKey: blspy.PublicKey = blspy.PrivateKey.from_seed(b'\0').get_public_key() #Add a single Block to create Merit and load a MeritRemoval. snFile: IO[Any] = open( "PythonTests/Vectors/Consensus/MeritRemoval/SameNonce.json", "r") vectors: Dict[str, Any] = json.loads(snFile.read()) blockchain.add(Block.fromJSON(vectors["blockchain"][0])) consensus.add(SignedVerification.fromJSON(vectors["removal"]["elements"][0])) removal: PartiallySignedMeritRemoval = PartiallySignedMeritRemoval.fromJSON( vectors["removal"]) removal.nonce = 1 consensus.add(removal) snFile.close() #Generate a Block with a verif and a Block with the removal. for i in range(2): block: Block = Block( BlockHeader(i + 2, blockchain.last(), int(time()), consensus.getAggregate([(pubKey, i, i)])), BlockBody([(pubKey, i, consensus.getMerkle(pubKey, i, i))])) #Mine it.
def EightyEightTest(rpc: RPC) -> None: #Ed25519 key. edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() #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() #Spam Filter. dataFilter: SpamFilter = SpamFilter(bytes.fromhex("CC" * 32)) #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 two Datas. datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())] datas.append(Data(datas[0].hash, b"Hello there! General Kenobi.")) for data in datas: #Sign them and have them beat the spam filter. data.sign(edPrivKey) data.beat(dataFilter) #Transmit them. rpc.meros.transaction(data) #Verify both. verifs: List[SignedVerification] = [ SignedVerification(datas[0].hash), SignedVerification(datas[1].hash) ] for verif in verifs: verif.sign(0, blsPrivKey) #Only transmit the second. rpc.meros.signedElement(verifs[1]) sleep(0.5) #Verify the block template has no verifications. if bytes.fromhex( rpc.call("merit", "getBlockTemplate", [blsPubKey])["header"])[36:68] != bytes(32): raise TestError("Block template has Verification Packets.") #Transmit the first signed verification. rpc.meros.signedElement(verifs[0]) sleep(0.5) #Verify the block template has both verifications. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) packets: List[VerificationPacket] = [ VerificationPacket(datas[0].hash, [0]), VerificationPacket(datas[1].hash, [0]) ] if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, packets): raise TestError( "Block template doesn't have both Verification Packets.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(merit.state.nicks, packets), 1, template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], packets), 0, int.from_bytes(template["header"][-4:], byteorder="big"), ), BlockBody( packets, [], Signature.aggregate([verifs[0].signature, verifs[1].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, len(packets)) != 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, len(packets))).hex() ]) #Verify the Blockchain. verifyBlockchain(rpc, merit.blockchain)
transactions.txs[claim]).amount)])) for _ in range(12): sends[-1].sign(edPrivKey) sends[-1].beat(consensus.sendFilter) sends[-1].verified = True transactions.add(sends[-1]) sends.append( Send([(sends[-1].hash, 0)], [(edPubKey.to_bytes(), sends[-1].outputs[0][1])])) #Verify 0 and 1 in order. order: List[int] = [0, 1] verif: SignedVerification for s in order: verif = SignedVerification(sends[s].hash) verif.sign(blsPrivKey1, len(consensus.holders[blsPubKey1.serialize()])) consensus.add(verif) block: Block = Block( BlockHeader(13, blockchain.last(), int(time()), consensus.getAggregate([(blsPubKey1, 2, -1)])), BlockBody([(blsPubKey1, 3, consensus.getMerkle(blsPubKey1, 2))])) block.mine(blockchain.difficulty()) blockchain.add(block) print("Generated Fifty Block " + str(block.header.nonce) + ".") #Verify 3, and then 2, while giving Merit to a second Merit Holder. order = [3, 2] for s in order: verif = SignedVerification(sends[s].hash)
reorderedChain.add(block) print("Generated Hundred Twenty Three Packet Block 1/2 " + str(len(packetedChain.blocks)) + ".") #Create the initial Data and two competing Datas. datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())] datas.append(Data(datas[0].hash, b"Initial Data.")) datas.append(Data(datas[0].hash, b"Second Data.")) for data in datas: data.sign(edPrivKey) data.beat(spamFilter) #Create Verifications for all 3. verifs: List[SignedVerification] = [] for data in datas: verifs.append(SignedVerification(data.hash, 0)) verifs[-1].sign(0, blsPrivKey) #Create a MeritRemoval out of the conflicting Verifications. mr: SignedMeritRemoval = SignedMeritRemoval(verifs[1], verifs[2]) #Generate a Block containing the MeritRemoval. block = Block( BlockHeader(0, packetedChain.last(), BlockHeader.createContents([], [mr]), 1, bytes(4), bytes(32), 0, packetedChain.blocks[-1].header.time + 1200), BlockBody([], [mr], mr.signature)) #Mine it. block.mine(blsPrivKey, packetedChain.difficulty())
send1.verified = True transactions.add(send1) send2: Send = Send( [(claim, 0)], [( edPubKey2.to_bytes(), Claim.fromTransaction(transactions.txs[claim]).amount )] ) send2.sign(edPrivKey1) send2.beat(consensus.sendFilter) transactions.add(send2) #Verify the 1st Send with the 1st key. verif = SignedVerification(send1.hash) verif.sign(blsPrivKey1, len(consensus.holders[blsPubKey1.serialize()])) consensus.add(verif) #Verify the 2nd Send with the 2nd key. verif = SignedVerification(send2.hash) verif.sign(blsPrivKey2, 0) consensus.add(verif) #Archive the Elements and close the Epoch. block = Block( BlockHeader( 14, blockchain.last(), int(time()), consensus.getAggregate([(blsPubKey1, 2, -1), (blsPubKey2, 0, -1)])
blsPubKey: PublicKey = blsPrivKey.toPublicKey() #Grab the Claim hash. claim: bytes = blockchain.blocks[-1].body.packets[0].hash #Create a Send spending it twice. send: Send = Send( [(claim, 0), (claim, 0)], [(edPubKey.to_bytes(), Claim.fromTransaction(transactions.txs[claim]).amount * 2)]) send.sign(edPrivKey) send.beat(sendFilter) transactions.add(send) #Create a Verification/VerificationPacket for the Send. sv: SignedVerification = SignedVerification(send.hash) sv.sign(0, blsPrivKey) packet: VerificationPacket = VerificationPacket(send.hash, [0]) #Add a Block verifying it. block: Block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents([packet]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [packet]), 0, blockchain.blocks[-1].header.time + 1200), BlockBody([packet], [], sv.signature)) #Mine the Block. block.mine(blsPrivKey, blockchain.difficulty()) #Add the Block. blockchain.add(block)
def HundredFiftyFiveTest(rpc: RPC) -> None: #Ed25519 keys. edPrivKeys: List[ed25519.SigningKey] = [ ed25519.SigningKey(b'\0' * 32), ed25519.SigningKey(b'\1' * 32) ] edPubKeys: List[ed25519.VerifyingKey] = [ edPrivKeys[0].get_verifying_key(), edPrivKeys[1].get_verifying_key() ] #BLS keys. blsPrivKey: PrivateKey = PrivateKey( bytes.fromhex(rpc.call("personal", "getMiner"))) blsPubKey: bytes = blsPrivKey.toPublicKey().serialize() #Blockchain. blockchain: Blockchain = Blockchain() #Spam Filter. dataFilter: SpamFilter = SpamFilter(5) #Handshake with the node. rpc.meros.liveConnect(blockchain.blocks[0].header.hash) rpc.meros.syncConnect(blockchain.blocks[0].header.hash) #Call getBlockTemplate just to get an ID. #Skips the need to write a sync loop for the BlockBody. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey.hex()]) #Mine a Block. block = Block( BlockHeader(0, blockchain.blocks[0].header.hash, bytes(32), 1, bytes(4), bytes(32), blsPubKey, blockchain.blocks[0].header.time + 1200, 0), BlockBody()) block.mine(blsPrivKey, blockchain.difficulty()) blockchain.add(block) #Publish it. rpc.call("merit", "publishBlock", [template["id"], block.serialize().hex()]) #Handle the fact Meros will now broadcast it to us. if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader: raise TestError("Meros didn't broadcast the Block it just published.") #Create the Datas. datas: List[Data] = [ Data(bytes(32), edPubKeys[0].to_bytes()), Data(bytes(32), edPubKeys[1].to_bytes()) ] for d in range(len(datas)): #Sign, and mine the Data. datas[d].sign(edPrivKeys[d]) datas[d].beat(dataFilter) #Send the Data and verify Meros sends it back. if rpc.meros.liveTransaction(datas[d]) != rpc.meros.live.recv(): raise TestError("Meros didn't send back the Data.") #Verify Meros sends back a Verification. res: bytes = rpc.meros.live.recv() if MessageType(res[0]) != MessageType.SignedVerification: raise TestError("Meros didn't send a SignedVerification.") verif: SignedVerification = SignedVerification(datas[d].hash) verif.sign(0, blsPrivKey) if res[1:] != verif.signedSerialize(): raise TestError( "Meros didn't send the correct SignedVerification.")