def fromJSON(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: Element = Verification(bytes(32), 0) if json["elements"][0]["descendant"] == "Verification": e1 = Verification.fromJSON(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 = VerificationPacket.fromJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "SendDifficulty": e1 = SendDifficulty.fromJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "DataDifficulty": e1 = DataDifficulty.fromJSON(json["elements"][0]) else: raise Exception( "Unknown Element used to construct a MeritRemoval.") e2: Element = Verification(bytes(32), 0) if json["elements"][1]["descendant"] == "Verification": e2 = Verification.fromJSON(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 = VerificationPacket.fromJSON(json["elements"][1]) elif json["elements"][1]["descendant"] == "SendDifficulty": e2 = SendDifficulty.fromJSON(json["elements"][1]) elif json["elements"][1]["descendant"] == "DataDifficulty": e2 = DataDifficulty.fromJSON(json["elements"][1]) else: raise Exception( "Unknown Element used to construct a MeritRemoval.") return MeritRemoval(e1, e2, json["partial"])
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 = Verification.fromJSON(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 = VerificationPacket.fromJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "SendDifficulty": e1 = SendDifficulty.fromJSON(json["elements"][0]) elif json["elements"][0]["descendant"] == "DataDifficulty": e1 = DataDifficulty.fromJSON(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 PartialMeritRemoval(e1, e2)
def fromJSON(keys: Dict[bytes, int], json: Dict[str, Any]) -> Any: packets: List[VerificationPacket] = [] elements: List[Element] = [] for packet in json["transactions"]: packets.append( VerificationPacket(bytes.fromhex(packet["hash"]), packet["holders"])) for element in json["elements"]: if element["descendant"] == "SendDifficulty": elements.append(SendDifficulty.fromJSON(element)) elif element["descendant"] == "DataDifficulty": elements.append(DataDifficulty.fromJSON(element)) elif element["descendant"] == "MeritRemoval": elements.append(MeritRemoval.fromJSON(keys, element)) return BlockBody(packets, elements, Signature(bytes.fromhex(json["aggregate"])))
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)) + ".") #Create the next Block. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 1,
edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() #BLS Private Key. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) #Create a Data for the VerificationPacket. data: Data = Data(bytes(32), edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) #Generate the VerificationPacket Block. block = Block( BlockHeader( 0, blockchain.last(), BlockHeader.createContents([VerificationPacket(data.hash, [1])]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [VerificationPacket(data.hash, [1])]), blsPrivKey.toPublicKey().serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody([VerificationPacket(data.hash, [1])], [], blsPrivKey.sign(b""))) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it to the vectors. blocks.append(block.toJSON()) print("Generated Hundred Six Block Elements VerificationPacket Block.") #Generate the SendDifficulty Block. elements: List[Element] = []
#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] = [] packets: List[VerificationPacket] = [] for data in datas: verifs.append(SignedVerification(data.hash, 0)) verifs[-1].sign(0, blsPrivKey) packets.append(VerificationPacket(data.hash, [0])) #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, blockchain.last(), BlockHeader.createContents([], packets, [mr]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0, blockchain.blocks[-1].header.time + 1200
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): #Mine it. block.mine(blsPrivKey, merit.blockchain.difficulty()) #Add it. merit.add(block) print("Generated Claimed Mint Block " + str(len(merit.blockchain.blocks) - 1) + ".")
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), BlockHeader.createSketchCheck(bytes(4), packets), 0, merit.blockchain.blocks[-1].header.time + 1200), BlockBody( packets, [], Signature.aggregate([firstVerif.signature, secondVerif.signature]))) for _ in range(6): #Mine it.
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) #Create a SignedVerification for the descendant Data. descendantVerif: SignedVerification = SignedVerification(datas[1].hash) descendantVerif.sign(0, blsPrivKey) #Convert the Verifications to packets. packets: List[VerificationPacket] = [ VerificationPacket(verifs[0].hash, [0]), VerificationPacket(verifs[1].hash, [0]) ] #Generate another 6 Blocks. #Next block should have the packets. block: 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([verifs[0].signature, verifs[1].signature]))) for _ in range(6): #Mine it. block.mine(blsPrivKey, blockchain.difficulty())
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): #Mine it. block.mine(blsPrivKey, merit.blockchain.difficulty()) #Add it. merit.add(block) print("Generated Invalid Competing Block " + str(len(merit.blockchain.blocks) - 1) + ".") #Create the next Block.
def hash(sketchSalt: bytes, packet: VerificationPacket) -> int: return int.from_bytes(blake2b(sketchSalt + packet.serialize(), digest_size=8).digest(), byteorder="big")
#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): #Mine it. block.mine(blsPrivKey, merit.blockchain.difficulty()) #Add it. merit.add(block) print("Generated Claimed Mint Block " + str(len(merit.blockchain.blocks) - 1) + ".") #Create the next Block.
#BLS Private Key. blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest()) #Create a Data for the VerificationPacket. data: Data = Data(bytes(32), edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) #Generate the VerificationPacket Block. block = Block( BlockHeader( 0, blockchain.last(), BlockHeader.createContents([], [VerificationPacket(data.hash, [1])]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [VerificationPacket(data.hash, [1])]), blsPrivKey.toPublicKey().serialize(), blockchain.blocks[-1].header.time + 1200), BlockBody([VerificationPacket(data.hash, [1])], [], blsPrivKey.sign(b""))) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it to the vectors. blocks.append(block.toJSON()) print("Generated Hundred Six Block Elements VerificationPacket Block.") #Generate the SendDifficulty Block. elements: List[Element] = []
def packet(self, packet: VerificationPacket) -> bytes: res: bytes = (MessageType.VerificationPacket.toByte() + packet.serialize()) self.send(res) return res
({1: [5, 6, 9, 11, 3, 0], 0: [4, 5, 8, 7, 11, 6, 10, 9]}, 1) ] #Packets. 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],
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.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), BlockHeader.createSketchCheck(bytes(4), packets), 0, merit.blockchain.blocks[-1].header.time + 1200), BlockBody( packets, [], Signature.aggregate([firstVerif.signature, secondVerif.signature]))) for _ in range(6): #Mine it.
#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) print("Generated Same Input Block " + str(len(blockchain.blocks) - 1) + ".")
print("Generated Competing Block " + str(len(blockchain.blocks)) + ".") #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())