def reorgPast( mint: bytes ) -> Merit: #Safe due to performing the shallower reorg first. while coreMerit[-1]["hash"] != mint.hex().upper(): del coreMerit[-1] del coreMerit[-1] newMerit: Merit = Merit.fromJSON(coreMerit) #pylint: disable=global-statement global heightToBeat while len(newMerit.blockchain.blocks) <= heightToBeat: newMerit.add( PrototypeBlock( #Use a slightly faster time differential. newMerit.blockchain.blocks[-1].header.time + ((newMerit.blockchain.blocks[-1].header.time - newMerit.blockchain.blocks[-2].header.time) - 1) ).finish(1, newMerit) ) heightToBeat = len(newMerit.blockchain.blocks) return newMerit
from e2e.Classes.Transactions.Transactions import Transactions from e2e.Classes.Consensus.VerificationPacket import VerificationPacket from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain merit: Merit = PrototypeChain.withMint() transactions: Transactions = Transactions() claim: Claim = Claim([(merit.mints[-1].hash, 0)], ed25519.SigningKey(b'\0' * 32).get_verifying_key().to_bytes()) claim.amount = merit.mints[-1].outputs[0][1] claim.sign(PrivateKey(0)) transactions.add(claim) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(claim.hash, [0])]).finish(0, merit)) result: Dict[str, Any] = { "blockchain": merit.toJSON(), "transactions": transactions.toJSON() } vectors: IO[Any] = open("e2e/Vectors/Transactions/ClaimedMint.json", "w") vectors.write(json.dumps(result)) vectors.close()
datas[-1].sign(ed25519.SigningKey(b'\0' * 32)) datas[-1].beat(SpamFilter(5)) transactions.add(datas[-1]) datas.append(Data(datas[-1].hash, b'\0')) del datas[-1] merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[ VerificationPacket(claim.hash, [0]), VerificationPacket(send.hash, [0, 1, 2]), VerificationPacket(datas[0].hash, [0, 2]), VerificationPacket(datas[1].hash, [0, 1, 3]), VerificationPacket(datas[2].hash, [0, 1, 2, 3, 4]), VerificationPacket(datas[3].hash, [0, 1, 2, 3]) ], elements=[ DataDifficulty(8, 0, 3), SendDifficulty(1, 0, 0), DataDifficulty(4, 0, 3), DataDifficulty(1, 2, 4), SendDifficulty(3, 1, 4), SendDifficulty(2, 1, 2), DataDifficulty(7, 0, 0), ]).finish(0, merit)) with open("e2e/Vectors/RPC/Merit/GetBlock.json", "w") as vectors: vectors.write( json.dumps({ "blockchain": merit.toJSON(), "transactions": transactions.toJSON(), "claim": claim.toJSON(),
from typing import IO, Any import json from e2e.Classes.Consensus.SendDifficulty import SendDifficulty from e2e.Classes.Consensus.DataDifficulty import DataDifficulty from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain merit: Merit = Merit.fromJSON(PrototypeChain(49).finish().toJSON()) #Add the Difficulties. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, elements=[SendDifficulty(2, 0, 0), DataDifficulty(2, 1, 0)], minerID=0).finish(0, merit)) #Close out this, and the next, Checkpoint period to lock our Merit. for _ in range(9): merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=0).finish(0, merit)) #Become Pending. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=0).finish(1, merit)) vectors: IO[Any] = open("e2e/Vectors/Consensus/Difficulties/LockedMerit.json", "w")
ed25519.SigningKey(b'\1' * 32).get_verifying_key() ] sendFilter: SpamFilter = SpamFilter(3) edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() #Create the Claim. claim: Claim = Claim([(merit.mints[-1].hash, 0)], edPubKeys[0].to_bytes()) claim.amount = merit.mints[-1].outputs[0][1] claim.sign(PrivateKey(0)) transactions.add(claim) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(claim.hash, [0])]).finish(0, merit)) #Create 12 Sends. sends: List[Send] = [] sends.append(Send([(claim.hash, 0)], [(edPubKey.to_bytes(), claim.amount)])) for _ in range(12): sends[-1].sign(edPrivKey) sends[-1].beat(sendFilter) transactions.add(sends[-1]) sends.append( Send([(sends[-1].hash, 0)], [(edPubKey.to_bytes(), sends[-1].outputs[0][1])])) #Order to verify the Transactions in.
import json from e2e.Classes.Merit.Merit import Blockchain, Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain protoRoot: PrototypeChain = PrototypeChain(1, False) protoRoot.add(1) root: Blockchain = protoRoot.finish() main: Merit = Merit.fromJSON(root.toJSON()) alt: Merit = Merit.fromJSON(root.toJSON()) main.add( PrototypeBlock(main.blockchain.blocks[-1].header.time + 1200).finish(0, main) ) #Create the competing Block to the second miner. #Since the difficulty is fixed at the start, they're guaranteed to have the same amount of work. #Because of that, we can't just mine the Block; we need to mine it until it has a lower hash than the above Block. #Calculate a custom difficulty guaranteed to beat the above Block. hashAsInt: int = int.from_bytes(main.blockchain.blocks[-1].header.hash, "little") timeOffset: int = 1201 alt.blockchain.difficulties[-1] = 0 while int.from_bytes( PrototypeBlock( alt.blockchain.blocks[-1].header.time + timeOffset, minerID=1 ).finish(0, alt).header.hash, "little" ) > hashAsInt:
transactions: Transactions = Transactions() sendFilter: SpamFilter = SpamFilter(3) proto: PrototypeChain = PrototypeChain(40, keepUnlocked=True) proto.add(1) merit: Merit = Merit.fromJSON(proto.toJSON()) #Create a Claim. claim: Claim = Claim([(merit.mints[-1], 0)], edPubKey) claim.sign(PrivateKey(0)) transactions.add(claim) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(claim.hash, list(range(2))) ]).finish(0, merit)) sends: List[Send] = [ #Transaction which will win. Send([(claim.hash, 0)], [(bytes(32), claim.amount)]), #Transaction which will be beaten. Send([(claim.hash, 0)], [(edPubKey, claim.amount // 2), (edPubKey, claim.amount // 2)]) ] #Children. One which will have a Verification, one which won't. sends += [ Send([(sends[1].hash, 0)], [(edPubKey, claim.amount // 2)]), Send([(sends[1].hash, 1)], [(edPubKey, claim.amount // 2)]) ]
from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain edPubKey: bytes = ed25519.SigningKey(b'\0' * 32).get_verifying_key().to_bytes() proto: PrototypeChain = PrototypeChain(49, keepUnlocked=True) merit: Merit = Merit.fromJSON(proto.toJSON()) transactions: Transactions = Transactions() #Create the Claims. for m in range(3): claim: Claim = Claim([(merit.mints[m], 0)], edPubKey) claim.sign(PrivateKey(0)) transactions.add(claim) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[ VerificationPacket(tx.hash, [0]) for tx in transactions.txs.values() ]).finish(0, merit)) with open("e2e/Vectors/RPC/Personal/WatchWallet.json", "w") as vectors: vectors.write( json.dumps({ "blockchain": merit.toJSON(), "transactions": transactions.toJSON() }))
#Create a Verification for this Claim. verif: SignedVerification = SignedVerification(claim.hash) verif.sign(0, PrivateKey(0)) #Create two Sends, so the missing packets exceeds the capacity. #This and the above Verification are used to actually test #175. for s in range(2): send: Send = Send([(txs[-1].hash, 0)], [(edPubKey, merit.mints[-1].outputs[0][1])]) send.sign(edPrivKey) send.beat(spamFilter) txs.append(send) transactions.add(send) #Manually add the next Block. #This wouldn't be needed if we could convert the Merit to a PrototypeChain. #That said, this is easier than writing that algorithm. #This remains true despite multiple generators needing this. merit.blockchain.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, [VerificationPacket(tx.hash, [0]) for tx in txs]).finish(0, merit)) with open("e2e/Vectors/Merit/HundredSeventyFive.json", "w") as vectors: vectors.write( json.dumps({ "blockchain": merit.toJSON(), "transactions": transactions.toJSON(), "verification": verif.toSignedJSON() }))
proto: PrototypeChain = PrototypeChain(40, keepUnlocked=True) for _ in range(2): proto.add(1) proto.add(2) proto.add(3) merit: Merit = Merit.fromJSON(proto.toJSON()) #Create a Claim. claim: Claim = Claim([(merit.mints[-1], 0)], edPubKey) claim.sign(PrivateKey(0)) transactions.add(claim) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(claim.hash, list(range(4))) ]).finish(4, merit)) sends: List[Send] = [ #Competitors. Send([(claim.hash, 0)], [(bytes(32), claim.amount)]), Send([(claim.hash, 0)], [(edPubKey, claim.amount)]) ] #Descendant, which will have more Merit than the parents. sends.append(Send([(sends[1].hash, 0)], [(edPubKey, claim.amount)])) #Finally, a transaction to force them all into the same family. sends.append( Send([(claim.hash, 0), (sends[1].hash, 0)], [(edPubKey, claim.amount * 2)])) for send in sends:
import json from e2e.Libs.BLS import PrivateKey from e2e.Classes.Merit.Merit import Blockchain, Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain secondPrivKey: PrivateKey = PrivateKey(1) root: Blockchain = PrototypeChain(5, False).finish() main: Merit = Merit.fromJSON(root.toJSON()) main.add( PrototypeBlock(main.blockchain.blocks[-1].header.time + 1200, minerID=secondPrivKey).finish(0, main)) alt: Merit = Merit.fromJSON(root.toJSON()) alt.add( PrototypeBlock(alt.blockchain.blocks[-1].header.time + 1200).finish( 0, alt)) alt.add( PrototypeBlock(alt.blockchain.blocks[-1].header.time + 1200, minerID=secondPrivKey).finish(1, alt)) with open("e2e/Vectors/Merit/Reorganizations/DelayedMeritHolder.json", "w") as vectors: vectors.write(json.dumps({"main": main.toJSON(), "alt": alt.toJSON()}))
merit: Merit = Merit.fromJSON(PrototypeChain(47).toJSON()) transactions: Transactions = Transactions() privKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32) pubKey: bytes = privKey.get_verifying_key() recipientPriv: Ristretto.SigningKey = Ristretto.SigningKey(b'\1' * 32) recipientPub: bytes = recipientPriv.get_verifying_key() olderClaim: Claim = Claim([(merit.mints[-1], 0)], pubKey) olderClaim.sign(PrivateKey(0)) transactions.add(olderClaim) merit.add( PrototypeBlock( merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(olderClaim.hash, [0])] ).finish(0, merit) ) merit.add(PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200).finish(0, merit)) newerClaim: Claim = Claim([(merit.mints[-1], 0)], pubKey) newerClaim.sign(PrivateKey(0)) transactions.add(newerClaim) merit.add( PrototypeBlock( merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(newerClaim.hash, [0])] ).finish(0, merit) )
from typing import Dict, List, Any import json from e2e.Libs.BLS import PrivateKey from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain root: List[Dict[str, Any]] = PrototypeChain(9, False).finish().toJSON() main: Merit = Merit.fromJSON(root) alt: Merit = Merit.fromJSON(root) for _ in range(2): main.add( PrototypeBlock(main.blockchain.blocks[-1].header.time + 1200).finish( 0, main)) #Create a fork Block with a lower hash. #Same principle as DepthOne. hashAsInt: int = int.from_bytes(main.blockchain.blocks[-2].header.hash, "little") k: int = 1 while int.from_bytes( PrototypeBlock(alt.blockchain.blocks[-1].header.time + 1200, minerID=PrivateKey(k)).finish(0, alt).header.hash, "little") > hashAsInt: k += 1 alt.add( PrototypeBlock(alt.blockchain.blocks[-1].header.time + 1200, minerID=PrivateKey(k)).finish(0, alt))
sendFilter: SpamFilter = SpamFilter(3) edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKeys: List[ed25519.VerifyingKey] = [ edPrivKey.get_verifying_key(), ed25519.SigningKey(b'\1' * 32).get_verifying_key() ] #Create the Claim. claim: Claim = Claim([(merit.mints[-1].hash, 0)], edPubKeys[0].to_bytes()) claim.amount = merit.mints[-1].outputs[0][1] claim.sign(PrivateKey(0)) transactions.add(claim) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(claim.hash, [0])]).finish(0, merit)) #Give the second key pair Merit. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=PrivateKey(1)).finish(0, merit)) #Create two competing Sends. packets: List[VerificationPacket] = [] for i in range(2): send: Send = Send( [(claim.hash, 0)], [(edPubKeys[i].to_bytes(), Claim.fromTransaction(transactions.txs[claim.hash]).amount)]) send.sign(edPrivKey)
def TwoHundredSixtyOneTest(rpc: RPC) -> None: merit: Merit = Merit() blsPrivKey: PrivateKey = PrivateKey( bytes.fromhex(rpc.call("personal", "getMeritHolderKey"))) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() #Get a template. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", {"miner": blsPubKey}) template["header"] = bytes.fromhex(template["header"]) #Mine it. #Ignores the template except for the ID needed to publish it. #We could publish it over the socket to an identical effect, practically. #That said, this is more accurate to flow. block: Block = PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=blsPrivKey).finish(0, merit) merit.add(block) #Connect in order to receive their Verification of the Block's Data. rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash) rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash) #Publish it. rpc.call("merit", "publishBlock", { "id": template["id"], "header": block.header.serialize().hex() }) if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader: raise TestError("Meros didn't broadcast a published Block.") #Receive their Verification. if MessageType(rpc.meros.live.recv()[0]) != MessageType.SignedVerification: raise TestError("Meros didn't verify the Block's Data.") #Reorg past the chain with them as the nick. with open("e2e/Vectors/Merit/BlankBlocks.json", "r") as file: blankBlocks: Blockchain = Blockchain.fromJSON(json.loads(file.read())) rpc.meros.liveBlockHeader(blankBlocks.blocks[2].header) if MessageType( rpc.meros.sync.recv()[0]) != MessageType.BlockListRequest: raise TestError( "Meros didn't request the Block List needed to reorg.") rpc.meros.blockList([blankBlocks.blocks[0].header.hash]) if MessageType( rpc.meros.sync.recv()[0]) != MessageType.BlockHeaderRequest: raise TestError( "Meros didn't request the next Block Header on the list.") rpc.meros.syncBlockHeader(blankBlocks.blocks[1].header) for b in range(2): rpc.meros.handleBlockBody(blankBlocks.blocks[b + 1]) #Close the connection to give us time to mine Blocks without worrying about the handshake. rpc.meros.live.connection.close() rpc.meros.sync.connection.close() sleep(65) #Mine Blocks so we can re-org back to the original chain. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=PrivateKey(1)).finish(0, merit)) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=1).finish(0, merit)) #Reconnect. rpc.meros.liveConnect(merit.blockchain.blocks[0].header.hash) rpc.meros.syncConnect(merit.blockchain.blocks[0].header.hash) #Send the header for the original chain. rpc.meros.liveBlockHeader(merit.blockchain.blocks[3].header) if MessageType(rpc.meros.sync.recv()[0]) != MessageType.BlockListRequest: raise TestError("Meros didn't request the Block List needed to reorg.") rpc.meros.blockList([ merit.blockchain.blocks[1].header.hash, merit.blockchain.blocks[0].header.hash ]) for h in range(2): if MessageType( rpc.meros.sync.recv()[0]) != MessageType.BlockHeaderRequest: raise TestError( "Meros didn't request the next Block Header on the list.") rpc.meros.syncBlockHeader(merit.blockchain.blocks[h + 1].header) for b in range(3): rpc.meros.handleBlockBody(merit.blockchain.blocks[b + 1]) if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader: raise TestError("Meros didn't broadcast a Block it just synced.") if MessageType(rpc.meros.live.recv()[0]) != MessageType.SignedVerification: raise TestError( "Meros didn't verify the Block's Data after the re-org.")
edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32) edPubKey: bytes = edPrivKey.get_verifying_key() blsPrivKey: PrivateKey = PrivateKey(0) #Generate a Data to verify for the VerificationPacket Block. data: Data = Data(bytes(32), edPubKey) data.sign(edPrivKey) data.beat(dataFilter) transactions.add(data) packet: VerificationPacket = VerificationPacket(data.hash, [1]) blocks.append( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, packets=[VerificationPacket(data.hash, [1])], minerID=blsPrivKey).finish(0, merit).toJSON()) #Generate the SendDifficulty Block. blocks.append( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, elements=[SendDifficulty(0, 0, 1)], minerID=blsPrivKey).finish(0, merit).toJSON()) #Generate the DataDifficulty Block. blocks.append( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, elements=[DataDifficulty(0, 0, 1)], minerID=blsPrivKey).finish(0, merit).toJSON()) with open("e2e/Vectors/Consensus/HundredSix/BlockElements.json",
import json from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain proto: PrototypeChain = PrototypeChain(9, False) merit: Merit = Merit.fromJSON(proto.finish().toJSON()) merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200).finish( 1, merit)) for _ in range(9): merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200).finish( 0, merit)) with open("e2e/Vectors/Merit/LockedMerit/LocksUnlocks.json", "w") as vectors: vectors.write(json.dumps(merit.toJSON()))
from typing import IO, Any import json from e2e.Classes.Merit.Merit import Blockchain, Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain protoRoot: PrototypeChain = PrototypeChain(1, False) protoRoot.add(1) root: Blockchain = protoRoot.finish() main: Merit = Merit.fromJSON(root.toJSON()) alt: Merit = Merit.fromJSON(root.toJSON()) main.add( PrototypeBlock(main.blockchain.blocks[-1].header.time + 1200).finish( 0, main)) #Create the competing Block to the second miner. #Since the difficulty is fixed at the start, they're guaranteed to have the same amount of work. #Because of that, we can't just mine the Block; we need to mine it until it has a lower hash than the above Block. #Calculate a custom difficulty guaranteed to beat the above Block. hashAsInt: int = int.from_bytes(main.blockchain.blocks[-1].header.hash, "little") alt.blockchain.difficulties[-1] = 0 while (alt.blockchain.difficulties[-1] * hashAsInt).bit_length() <= 256: alt.blockchain.difficulties[-1] += 1 alt.add( PrototypeBlock(alt.blockchain.blocks[-1].header.time + 1200, minerID=1).finish(0, alt))
#Create a Claim and a Send splitting its outputs. claim: Claim = Claim([(merit.mints[-1], 0)], edPubKey) claim.sign(PrivateKey(0)) transactions.add(claim) splitSend: Send = Send([(claim.hash, 0)], [(edPubKey, claim.amount // 2) for _ in range(2)]) splitSend.sign(edPrivKey) splitSend.beat(sendFilter) transactions.add(splitSend) merit.add( PrototypeBlock( merit.blockchain.blocks[-1].header.time + 1200, packets=[ VerificationPacket(claim.hash, list(range(5))), VerificationPacket(splitSend.hash, list(range(5))) ] ).finish(5, merit) ) #We need to define two families. Family A (send output 0) and family B (send output 1). sends: List[Send] = [ #A. Send([(splitSend.hash, 0)], [(edPubKey, claim.amount // 2)]), Send([(splitSend.hash, 0)], [(bytes(32), claim.amount // 2)]), #B. Send([(splitSend.hash, 1)], [(edPubKey, claim.amount // 2)]), Send([(splitSend.hash, 1)], [(bytes(32), claim.amount // 2)]), #Now, union them. Send([(splitSend.hash, 0), (splitSend.hash, 1)], [(edPubKey, claim.amount)]),
import json from e2e.Libs.BLS import PrivateKey from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock, PrototypeChain proto: PrototypeChain = PrototypeChain(1, False) merit: Merit = Merit.fromJSON(proto.finish().toJSON()) #Use up all of our Blocks with Merit, except the last one. for i in range(98): merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=(PrivateKey(1) if i == 0 else 1)).finish( 0, merit)) #Right before the end, move to pending. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=1).finish(1, merit)) #Have our Merit die. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200, minerID=1).finish(0, merit)) #Regain Merit. merit.add( PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200,
from e2e.Classes.Merit.Block import BlockHeader, BlockBody, Block from e2e.Classes.Merit.Merit import Merit from e2e.Vectors.Generation.PrototypeChain import PrototypeBlock blsPrivKey: PrivateKey = PrivateKey(0) edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32) edPubKey: bytes = edPrivKey.get_verifying_key() dataFilter: SpamFilter = SpamFilter(5) #Create a Block to earn Merit. blocks: List[Block] = [] blocks.append(PrototypeBlock(1200, minerID=blsPrivKey).finish(0, Merit())) #Create five Datas and matching Verifications. #The test only sends a couple of the Verifications; that said, it's easy to generate the Block signature thanks to this. txs: List[Data] = [Data(bytes(32), edPubKey)] verifs: List[SignedVerification] = [] for i in range(5): txs[-1].sign(edPrivKey) txs[-1].beat(dataFilter) verifs.append(SignedVerification(txs[-1].hash)) verifs[-1].sign(0, blsPrivKey) txs.append(Data(txs[-1].hash, b"\0")) del txs[-1] #Create the final Block.