def add(self, verif: SignedVerification) -> None: self.holders.append(verif.holder) if self.signature.isInf(): self.signature = verif.signature else: self.signature = Signature.aggregate( [self.signature, verif.signature])
def signElement(elem: Element) -> Signature: if isinstance(elem, Verification): verif: SignedVerification = SignedVerification(elem.hash, elem.holder) verif.sign(elem.holder, PrivateKey(elem.holder)) return verif.signature if isinstance(elem, SignedMeritRemovalVerificationPacket): return elem.signature if isinstance(elem, SendDifficulty): sendDiff: SignedSendDifficulty = SignedSendDifficulty( elem.difficulty, elem.nonce) sendDiff.sign(elem.holder, PrivateKey(elem.holder)) return sendDiff.signature if isinstance(elem, DataDifficulty): dataDiff: SignedDataDifficulty = SignedDataDifficulty( elem.difficulty, elem.nonce) dataDiff.sign(elem.holder, PrivateKey(elem.holder)) return dataDiff.signature if isinstance(elem, MeritRemoval): result: Signature = signElement(elem.e2) if not elem.partial: result = Signature.aggregate([result, signElement(elem.e1)]) return result raise GenerationError( "Tried to sign an Element in a Block we didn't recognize the type of.")
def __init__(self, e1: MeritRemovalElement, e2: MeritRemovalElement, holder: int = -1) -> None: PartialMeritRemoval.__init__(self, e1, e2, holder) self.partial = False self.se1: SignedElement = e1 self.signature = Signature.aggregate([e1.signature, e2.signature])
def sign(self, privKeys: List[PrivateKey]) -> None: signatures: List[Signature] = [ privKeys[0].sign(b'\1' + self.inputs[0][0] + self.inputs[0][1].to_bytes(1, "big") + self.output) ] for i in range(1, len(self.inputs)): signatures.append( privKeys[i].sign(b'\1' + self.inputs[i][0] + self.inputs[i][1].to_bytes(1, "big") + self.output)) self.signature = Signature.aggregate(signatures).serialize() self.hash = blake2b(b'\1' + self.signature, digest_size=32).digest()
def __init__( self, e1: Union[ SignedVerification, SignedMeritRemovalVerificationPacket, SignedSendDifficulty, SignedDataDifficulty ], e2: Union[ SignedVerification, SignedMeritRemovalVerificationPacket, SignedSendDifficulty, SignedDataDifficulty ], holder: int = -1 ) -> None: PartialMeritRemoval.__init__(self, e1, e2, holder) self.partial = False self.se1: SignedElement = e1 self.signature = Signature.aggregate([e1.signature, e2.signature])
#Create a MeritRemoval out of the conflicting Verifications. mr: SignedMeritRemoval = SignedMeritRemoval(verifs[1], verifs[2]) #Create a MeritRemoval with random keys. packeted: SignedMeritRemoval = SignedMeritRemoval( SignedMeritRemovalVerificationPacket( SignedVerificationPacket(verifs[1].hash), [ blsPubKey.serialize(), PrivateKey(1).toPublicKey().serialize(), PrivateKey(2).toPublicKey().serialize() ], Signature.aggregate([ blsPrivKey.sign(verifs[1].signatureSerialize()), PrivateKey(1).sign(verifs[1].signatureSerialize()), PrivateKey(2).sign(verifs[1].signatureSerialize()) ]) ), SignedMeritRemovalVerificationPacket( SignedVerificationPacket(verifs[2].hash), [ blsPubKey.serialize(), PrivateKey(3).toPublicKey().serialize(), PrivateKey(4).toPublicKey().serialize() ], Signature.aggregate( [ blsPrivKey.sign(verifs[2].signatureSerialize()), PrivateKey(3).sign(verifs[2].signatureSerialize()), PrivateKey(4).sign(verifs[2].signatureSerialize())
def TElementTest( rpc: RPC ) -> None: file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() merit: Merit = Merit() blsPrivKey: PrivateKey = PrivateKey(0) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() #Handshake with the node. rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash) rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash) #Send the first Block. block: Block = Block.fromJSON(blocks[0]) merit.blockchain.add(block) rpc.meros.liveBlockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: 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.") rpc.meros.blockBody(block) break else: raise TestError("Unexpected message sent: " + msg.hex().upper()) if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader: raise TestError("Meros didn't broadcast the Block Header it just added.") #Create and transmit a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty(0, 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([], [dataDiff]): raise TestError("Block template doesn't have the Data Difficulty.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents([], [dataDiff]), 1, template["header"][-43 : -39], BlockHeader.createSketchCheck(template["header"][-43 : -39], []), 0, int.from_bytes(template["header"][-4:], byteorder="little"), ), BlockBody([], [dataDiff], dataDiff.signature) ) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(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="little") + block.header.signature + block.body.serialize(block.header.sketchSalt) ).hex() ] ) #Create and transmit a new DataDifficulty. dataDiff = SignedDataDifficulty(3, 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([], [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(4, 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(3, 1, 0), SignedDataDifficulty(4, 1, 0), False ) template = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36 : 68] != BlockHeader.createContents([], [mr]): raise TestError("Block template doesn't have the Merit Removal.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents([], [mr]), 1, template["header"][-43 : -39], BlockHeader.createSketchCheck(template["header"][-43 : -39], []), 0, int.from_bytes(template["header"][-4:], byteorder="little") ), BlockBody([], [mr], Signature.aggregate(signatures)) ) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(block.header.sketchSalt) != bytes.fromhex(template["body"]): raise TestError("Failed to recreate the body.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) rpc.call( "merit", "publishBlock", [ template["id"], ( template["header"] + block.header.proof.to_bytes(4, byteorder="little") + block.header.signature + block.body.serialize(block.header.sketchSalt) ).hex() ] ) verifyBlockchain(rpc, merit.blockchain)
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) print("Generated Competing Block " + str(len(blockchain.blocks)) + ".") #Create the next Block. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody()) #Save the appended data (3 Blocks and 12 Sends). result: Dict[str, Any] = {
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))) miner: Union[bytes, int] = order[1] if isinstance(miner, bytes): for k in range(len(blsPubKeys)): if miner == blsPubKeys[k].serialize(): block.mine(blsPrivKeys[k], blockchain.difficulty()) break else: block.mine(blsPrivKeys[miner], blockchain.difficulty()) blockchain.add(block) print("Generated Fifty Block " + str(len(blockchain.blocks) - 1) + ".") #Generate another 5 Blocks. for _ in range(5):
#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( BlockHeader(0, merit.blockchain.last(), BlockHeader.createContents([packet]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [packet]), 1, merit.blockchain.blocks[-1].header.time + 1200), BlockBody([packet], [], packet.signature)) block.mine(blsPrivKeys[1], merit.blockchain.difficulty()) merit.add(block) print("Generated Aggregated Claim Block " + str(len(merit.blockchain.blocks) - 1) + ".") #Generate another 5 Blocks to close the Epochs.
data = Data(bytes(32), edPubKey.to_bytes()) else: data = Data(data.hash, edPubKey.to_bytes()) data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) svs.append(SignedVerification(data.hash)) svs[-1].sign(0, blsPrivKey) packets.append(VerificationPacket(data.hash, [0])) 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( [svs[0].signature, svs[1].signature, svs[2].signature]))) block.mine(blsPrivKey, blockchain.difficulty()) blockchain.add(block) vectors: IO[Any] = open("e2e/Vectors/Merit/HundredSeventyFive.json", "w") vectors.write( json.dumps({ "blockchain": blockchain.toJSON(), "transactions": transactions.toJSON(), "verification": svs[0].toSignedJSON() })) vectors.close()
def EightyEightTest(rpc: RPC) -> None: edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32) edPubKey: bytes = edPrivKey.get_verifying_key() blsPrivKey: PrivateKey = PrivateKey(0) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() merit: Merit = Merit() dataFilter: SpamFilter = SpamFilter(5) #Handshake with the node. rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash) rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash) #Send the first Block. block: Block with open("e2e/Vectors/Merit/BlankBlocks.json", "r") as file: block = Block.fromJSON(json.loads(file.read())[0]) merit.blockchain.add(block) rpc.meros.liveBlockHeader(block.header) rpc.meros.handleBlockBody(block) if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader: raise TestError( "Meros didn't broadcast the Block Header it just added.") #Create two Datas. datas: List[Data] = [Data(bytes(32), edPubKey)] 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.liveTransaction(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(1.5) #Verify the block template has no verifications. if bytes.fromhex( rpc.call("merit", "getBlockTemplate", {"miner": blsPubKey})["header"])[36:68] != bytes(32): raise TestError("Block template has Verification Packets.") #Transmit the first signed verification. rpc.meros.signedElement(verifs[0]) sleep(1.5) #Verify the block template has both verifications. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", {"miner": 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(packets): raise TestError( "Block template doesn't have both Verification Packets.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(packets), len(packets), template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], packets), 0, int.from_bytes(template["header"][-4:], byteorder="little")), BlockBody( packets, [], Signature.aggregate([verifs[0].signature, verifs[1].signature]))) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) rpc.call( "merit", "publishBlock", { "id": template["id"], "header": (template["header"] + block.header.proof.to_bytes(4, byteorder="little") + block.header.signature).hex() }) verifyBlockchain(rpc, merit.blockchain)
mr: SignedMeritRemoval = SignedMeritRemoval(verifs[1], verifs[2]) #Create a MeritRemoval with random keys. packeted: SignedMeritRemoval = SignedMeritRemoval( SignedMeritRemovalVerificationPacket( SignedVerificationPacket(verifs[1].hash), [ blsPubKey.serialize(), PrivateKey(blake2b( b'\1', digest_size=32).digest()).toPublicKey().serialize(), PrivateKey(blake2b( b'\2', digest_size=32).digest()).toPublicKey().serialize() ], Signature.aggregate([ blsPrivKey.sign(verifs[1].signatureSerialize()), PrivateKey(blake2b(b'\1', digest_size=32).digest()).sign( verifs[1].signatureSerialize()), PrivateKey(blake2b(b'\2', digest_size=32).digest()).sign( verifs[1].signatureSerialize()) ])), SignedMeritRemovalVerificationPacket( SignedVerificationPacket(verifs[2].hash), [ blsPubKey.serialize(), PrivateKey(blake2b( b'\3', digest_size=32).digest()).toPublicKey().serialize(), PrivateKey(blake2b( b'\4', digest_size=32).digest()).toPublicKey().serialize() ], Signature.aggregate([ blsPrivKey.sign(verifs[2].signatureSerialize()), PrivateKey(blake2b(b'\3', digest_size=32).digest()).sign( verifs[2].signatureSerialize()),
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()) #Add it. blockchain.add(block) print("Generated Prune Unaddable Block " + str(len(blockchain.blocks)) + ".") #Create the next Block. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody()) result: Dict[str, Any] = {
def EightyEightTest( rpc: RPC ) -> None: edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() blsPrivKey: PrivateKey = PrivateKey(0) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() merit: Merit = Merit() dataFilter: SpamFilter = SpamFilter(5) #Handshake with the node. rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash) rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash) #Send the first Block. block: Block = Block.fromJSON(blocks[0]) merit.blockchain.add(block) rpc.meros.liveBlockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: 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) break else: raise TestError("Unexpected message sent: " + msg.hex().upper()) if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader: raise TestError("Meros didn't broadcast the Block Header it just added.") #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.liveTransaction(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(packets): raise TestError("Block template doesn't have both Verification Packets.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(packets), 1, template["header"][-43 : -39], BlockHeader.createSketchCheck(template["header"][-43 : -39], packets), 0, int.from_bytes(template["header"][-4:], byteorder="little") ), 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( 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) rpc.call( "merit", "publishBlock", [ template["id"], ( template["header"] + block.header.proof.to_bytes(4, byteorder="little") + block.header.signature + block.body.serialize(block.header.sketchSalt, len(packets)) ).hex() ] ) verifyBlockchain(rpc, merit.blockchain)
def finish(self, keepUnlocked: int, existing: Merit) -> Block: genesis: bytes = existing.blockchain.genesis prev: BlockHeader = existing.blockchain.blocks[-1].header diff: int = existing.blockchain.difficulty() #Create the signatures for every packet/element. signatures: List[Signature] = [] for packet in self.packets: for holder in packet.holders: verif: SignedVerification = SignedVerification( packet.hash, holder) verif.sign(holder, PrivateKey(holder)) signatures.append(verif.signature) for element in self.elements: signatures.append(signElement(element)) #Only add the Data Verification if: #1) We're supposed to make sure Merit Holders are always Unlocked #2) The last Block created a Data #3) The Merit Holder has Merit. if (keepUnlocked != 0) and (prev.last != genesis): #Create the Data from the last Block. blockData: Data = Data(genesis, prev.hash) #Create Verifications for said Data with every Private Key. #Ensures no one has their Merit locked. #pylint: disable=unnecessary-comprehension self.packets.append(VerificationPacket(blockData.hash, [])) for i in range(keepUnlocked): if ( #Miners who are just being created don't have Merit. ((i == (keepUnlocked - 1)) and (isinstance(self.minerID, PrivateKey))) or (existing.state.balances[i] == 0)): continue self.packets[-1].holders.append(i) verif: SignedVerification = SignedVerification( blockData.hash, i) verif.sign(i, PrivateKey(i)) signatures.append(verif.signature) #Remove this packet if there's no holders. if not self.packets[-1].holders: del self.packets[-1] #Set the aggregate. aggregate = Signature.aggregate(signatures) #Create the actual Block. minerID: Union[bytes, int] = 0 if isinstance(self.minerID, int): minerID = self.minerID else: minerID = self.minerID.toPublicKey().serialize() result: Block = Block( BlockHeader( 0, prev.hash, BlockHeader.createContents(self.packets, self.elements), len(self.packets), bytes(4), BlockHeader.createSketchCheck(bytes(4), self.packets), minerID, self.time), BlockBody(self.packets, self.elements, aggregate)) if isinstance(self.minerID, int): result.mine(PrivateKey(self.minerID), diff) else: result.mine(self.minerID, diff) return result
SignedDataDifficulty(2, 0) ] for dataDiff in dataDiffs: dataDiff.sign(0, blsPrivKey) for _ in range(2): block = Block( BlockHeader( 0, blockchain.last(), #Used so the type checkers realize List[SignedDataDifficulty] is a viable List[Element]. #pylint: disable=unnecessary-comprehension BlockHeader.createContents([], [e for e in dataDiffs]), 0, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), #pylint: disable=unnecessary-comprehension BlockBody([], [e for e in dataDiffs], Signature.aggregate([d.signature for d in dataDiffs]))) block.mine(blsPrivKey, blockchain.difficulty()) blockchain.add(block) #To verify the nonce isn't improperly set, add one more Data Difficulty with a nonce of 2. dataDiffs = [SignedDataDifficulty(4, 2)] dataDiffs[0].sign(0, blsPrivKey) with open("e2e/Vectors/Merit/OutOfOrder/Elements.json", "w") as vectors: vectors.write(json.dumps(blockchain.toJSON()))
] #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. block.mine(blsPrivKey, merit.blockchain.difficulty()) #Add it. merit.add(block) print("Generated Competing Finalized Block " + str(len(merit.blockchain.blocks) - 1) + ".") #Create the next Block. block = Block( BlockHeader( 0, merit.blockchain.last(), bytes(32),
verifs[-1].sign(0, blsPrivKey) txs.append(Data(txs[-1].hash, b"\0")) del txs[-1] #Create the final Block. #Done manually as it has invalid data. packets: List[VerificationPacket] = [ VerificationPacket(tx.hash, [0]) for tx in txs ] blocks.append( Block( BlockHeader(0, blocks[0].header.hash, BlockHeader.createContents(packets), 4, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0, 2400), BlockBody(packets, [], Signature.aggregate([verif.signature for verif in verifs])))) #The difficulty either shouldn't change or should lower, hence why this works. blocks[-1].header.mine(blsPrivKey, Merit().blockchain.difficulty()) #Only save the Verifications the test will use. #Not a micro-opt on disk space; rather ensures this data isn't floating around to cause invalid testing methodology. #This would optimally be inlined below with the vector write, yet pylint errors on the complex statement. verifs = verifs[:2] with open("e2e/Vectors/Merit/TwoHundredSeventyFour/MatchesHeaderQuantity.json", "w") as vectors: vectors.write( json.dumps({ "blocks": [block.toJSON() for block in blocks], "transactions": [tx.toJSON() for tx in txs], "verifications": [verif.toSignedJSON() for verif in verifs]