Ejemplo n.º 1
0
    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: MeritRemovalElement = 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: MeritRemovalElement = 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 UnmentionedBeatMentionedTest(
  rpc: RPC
) -> None:
  vectors: Dict[str, Any]
  with open("e2e/Vectors/Consensus/Families/UnmentionedBeatMentioned.json", "r") as file:
    vectors = json.loads(file.read())
  datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]]
  verif: SignedVerification = SignedVerification.fromSignedJSON(vectors["verification"])

  def sendDatas() -> None:
    for d in range(len(datas)):
      if rpc.meros.liveTransaction(datas[d]) != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast a Data.")

    #Might as well send this now.
    if rpc.meros.signedElement(verif) != rpc.meros.live.recv():
      raise TestError("Meros didn't broadcast the Verification.")

  def verifyMentionedWon() -> None:
    if not rpc.call("consensus", "getStatus", [datas[2].hash.hex()])["verified"]:
      raise TestError("Meros didn't verify the only Transaction on chain which has finalized.")

  Liver(
    rpc,
    vectors["blockchain"],
    callbacks={
      41: sendDatas,
      47: verifyMentionedWon
    }
  ).live()
def HundredSixSignedElementsTest(rpc: RPC) -> None:
    #Solely used to get the genesis Block hash.
    blockchain: Blockchain = Blockchain()

    blsPrivKey: PrivateKey = PrivateKey(0)
    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(0, 0, 1, sig),
        SignedDataDifficulty(0, 0, 1, sig)
    ]

    for elem in elements:
        #Handshake with the node.
        rpc.meros.liveConnect(blockchain.blocks[0].header.hash)

        #Send the Element.
        rpc.meros.signedElement(elem)

        #Sleep for thirty seconds to make sure Meros realizes our connection is dead.
        sleep(30)

        #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.")
Ejemplo n.º 4
0
def OneHundredPercentSketchTest(meros: Meros) -> None:
    vectors: Dict[str, Any]
    with open("e2e/Vectors/Merit/Sketches/OneHundredPercent.json",
              "r") as file:
        vectors = json.loads(file.read())

    blockchain: Blockchain = Blockchain.fromJSON(vectors["blockchain"])

    meros.liveConnect(blockchain.blocks[0].header.hash)
    meros.syncConnect(blockchain.blocks[0].header.hash)

    header: bytes = meros.liveBlockHeader(blockchain.blocks[1].header)
    meros.handleBlockBody(blockchain.blocks[1])
    if meros.live.recv() != header:
        raise TestError(
            "Meros didn't broadcast a BlockHeader for a Block it just added.")

    for data in vectors["datas"]:
        if meros.liveTransaction(Data.fromJSON(data)) != meros.live.recv():
            raise TestError("Meros didn't broadcast back a Data Transaction.")

    for verif in vectors["verifications"]:
        if meros.signedElement(
                SignedVerification.fromSignedJSON(verif)) != meros.live.recv():
            raise TestError("Meros didn't broadcast back a Verification.")

    header = meros.liveBlockHeader(blockchain.blocks[2].header)
    meros.handleBlockBody(blockchain.blocks[2])
    if meros.live.recv() != header:
        raise TestError(
            "Meros didn't broadcast a BlockHeader for a Block it just added.")
Ejemplo n.º 5
0
def TwoHundredThirtyEightTest(
  rpc: RPC
) -> None:
  vectors: Dict[str, Any]
  with open("e2e/Vectors/Transactions/Prune/TwoHundredThirtyEight.json", "r") as file:
    vectors = json.loads(file.read())

  datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]]
  verif: SignedVerification = SignedVerification.fromSignedJSON(vectors["verification"])

  def sendDatas() -> None:
    for d in range(len(datas)):
      if rpc.meros.liveTransaction(datas[d]) != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast a Data.")

    if rpc.meros.signedElement(verif) != rpc.meros.live.recv():
      raise TestError("Meros didn't broadcast the Verification.")

  Liver(
    rpc,
    vectors["blockchain"],
    callbacks={
      42: sendDatas
    }
  ).live()
Ejemplo n.º 6
0
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.")
Ejemplo n.º 7
0
def MissingOneSketchTest(meros: Meros) -> None:
    vectors: Dict[str, Any]
    with open("e2e/Vectors/Merit/Sketches/MissingOne.json", "r") as file:
        vectors = json.loads(file.read())

    blockchain: Blockchain = Blockchain.fromJSON(vectors["blockchain"])

    meros.liveConnect(blockchain.blocks[0].header.hash)
    meros.syncConnect(blockchain.blocks[0].header.hash)

    header: bytes = meros.liveBlockHeader(blockchain.blocks[1].header)
    meros.handleBlockBody(blockchain.blocks[1])
    if meros.live.recv() != header:
        raise TestError(
            "Meros didn't broadcast a BlockHeader for a Block it just added.")

    for data in vectors["datas"]:
        if meros.liveTransaction(Data.fromJSON(data)) != meros.live.recv():
            raise TestError("Meros didn't broadcast back a Data Transaction.")

    for verif in vectors["verifications"]:
        if meros.signedElement(
                SignedVerification.fromSignedJSON(verif)) != meros.live.recv():
            raise TestError("Meros didn't broadcast back a Verification.")

    header = meros.liveBlockHeader(blockchain.blocks[2].header)
    meros.handleBlockBody(blockchain.blocks[2], 1)

    if MessageType(meros.sync.recv()[0]) != MessageType.SketchHashRequests:
        raise TestError("Meros didn't request the packet it's missing.")
    meros.packet(VerificationPacket.fromJSON(vectors["packet"]))

    if meros.live.recv() != header:
        raise TestError(
            "Meros didn't broadcast a BlockHeader for a Block it just added.")
Ejemplo n.º 8
0
def HundredSeventyFiveTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Merit/HundredSeventyFive.json", "r")
  vectors: Dict[str, Any] = json.loads(file.read())
  file.close()

  transactions: Transactions = Transactions.fromJSON(vectors["transactions"])
  verif: SignedVerification = SignedVerification.fromSignedJSON(vectors["verification"])

  def sendDatasAndVerif() -> None:
    for tx in transactions.txs:
      if rpc.meros.liveTransaction(transactions.txs[tx]) != rpc.meros.live.recv():
        raise TestError("Meros didn't send us back the Data.")

    if rpc.meros.signedElement(verif) != rpc.meros.live.recv():
      raise TestError("Meros didn't send us back the Verification.")

  Liver(
    rpc,
    vectors["blockchain"],
    transactions,
    callbacks={
      1: sendDatasAndVerif
    }
  ).live([verif.hash])
Ejemplo n.º 9
0
def createSend(rpc: RPC, last: Union[Claim, Send], toAddress: str) -> Send:
    funded: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32)
    if isinstance(last, Claim):
        send: Send = Send([(last.hash, 0)],
                          [(decodeAddress(toAddress), 1),
                           (funded.get_verifying_key(), last.amount - 1)])
    else:
        send: Send = Send(
            [(last.hash, 1)],
            [(decodeAddress(toAddress), 1),
             (funded.get_verifying_key(), last.outputs[1][1] - 1)])

    send.sign(funded)
    send.beat(SpamFilter(3))
    sleep(65)
    rpc.meros.liveConnect(Blockchain().blocks[0].header.hash)
    if rpc.meros.liveTransaction(send) != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast back a Send.")

    sv: SignedVerification = SignedVerification(send.hash)
    sv.sign(0, PrivateKey(0))
    if rpc.meros.signedElement(sv) != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast back a Verification.")

    return send
Ejemplo n.º 10
0
def VUnknownSignedTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r")
    chain: Blockchain = Blockchain.fromJSON(json.loads(file.read()))
    file.close()

    #Send a single block so we have a miner.
    rpc.meros.liveConnect(chain.blocks[0].header.hash)
    rpc.meros.syncConnect(chain.blocks[0].header.hash)
    header: bytes = rpc.meros.liveBlockHeader(chain.blocks[1].header)
    if MessageType(rpc.meros.sync.recv()[0]) != MessageType.BlockBodyRequest:
        raise TestError("Meros didn't ask for the body.")
    rpc.meros.blockBody(chain.blocks[1])
    if rpc.meros.live.recv() != header:
        raise TestError("Meros didn't broadcast the header.")

    #Create a valid Data.
    #Uneccessary at this time, but good preparation for the future.
    privKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32)
    data: Data = Data(bytes(32), privKey.get_verifying_key().to_bytes())
    data.sign(privKey)
    data.beat(SpamFilter(5))

    #Sign the Data.
    verif: SignedVerification = SignedVerification(data.hash)
    verif.sign(0, PrivateKey(0))

    #Run twice. The first shouldn't send the Transaction. The second should.
    for i in range(2):
        rpc.meros.signedElement(verif)
        if MessageType(
                rpc.meros.sync.recv()[0]) != MessageType.TransactionRequest:
            raise TestError("Meros didn't request the transaction.")

        if i == 0:
            #When we send DataMissing, we should be disconnected within a few seconds.
            rpc.meros.dataMissing()
            start: int = int(time())
            try:
                rpc.meros.sync.recv()
            except Exception:
                #More than a few seconds is allowed as Meros's own SyncRequest must timeout.
                if int(time()) - start > 10:
                    raise TestError(
                        "Meros didn't disconnect us for sending a Verification of a non-existent Transaction."
                    )
            #Clear our invalid connections.
            rpc.meros.live.connection.close()
            rpc.meros.sync.connection.close()
            sleep(65)
            #Init new ones.
            rpc.meros.liveConnect(chain.blocks[0].header.hash)
            rpc.meros.syncConnect(chain.blocks[0].header.hash)

        else:
            rpc.meros.syncTransaction(data)
            sleep(2)
            if not rpc.call("consensus", "getStatus",
                            [data.hash.hex()])["verifiers"]:
                raise TestError("Meros didn't add the Verification.")
Ejemplo n.º 11
0
  def sendDatas() -> None:
    for data in datas:
      if rpc.meros.liveTransaction(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.")
Ejemplo n.º 12
0
def verify(rpc: RPC, txHash: bytes, nick: int = 0, mr: bool = False) -> None:
    sv: SignedVerification = SignedVerification(txHash)
    sv.sign(nick, PrivateKey(nick))
    temp: bytes = rpc.meros.signedElement(sv)
    if mr:
        if MessageType(
                rpc.meros.live.recv()[0]) != MessageType.SignedMeritRemoval:
            raise TestError("Meros didn't create a MeritRemoval.")
    elif temp != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast back a Verification.")
Ejemplo n.º 13
0
    def sendDatas() -> None:
        for data in datas:
            if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
                raise TestError("Meros didn't send back the Data.")

        #Send the winning descendant Data's verification.
        verif: SignedVerification = SignedVerification.fromSignedJSON(
            vectors["verification"])
        if rpc.meros.signedElement(verif) != rpc.meros.live.recv():
            raise TestError("Meros didn't send back the SignedVerification.")

        #The Liver thinks we sent this packet, so it shouldn't have to.
        #That said, that'd only be true if this was included in the Sketcher.
        #As its parent is unmentioned, it won't be.
        del rpc.meros.sentVerifs[verif.hash]
Ejemplo n.º 14
0
    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",
                                          {"hash": 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.")
Ejemplo n.º 15
0
def HundredSixSignedElementsTest(
  rpc: RPC
) -> None:
  #Solely used to get the genesis Block hash.
  blockchain: Blockchain = Blockchain()

  edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32)
  blsPrivKey: PrivateKey = PrivateKey(0)
  sig: Signature = blsPrivKey.sign(bytes())

  #Create a Data for the Verification.
  data: Data = Data(bytes(32), edPrivKey.get_verifying_key())
  data.sign(edPrivKey)
  data.beat(SpamFilter(5))

  #Create a signed Verification, SendDifficulty, and DataDifficulty.
  elements: List[SignedElement] = [
    SignedVerification(data.hash, 1, sig),
    SignedSendDifficulty(0, 0, 1, sig),
    SignedDataDifficulty(0, 0, 1, sig)
  ]

  dataSent: bool = False
  for elem in elements:
    #Handshake with the node.
    rpc.meros.liveConnect(blockchain.blocks[0].header.hash)

    #Send the Data if we have yet to.
    if not dataSent:
      if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
        raise TestError("Data wasn't rebroadcasted.")
      dataSent = True

    #Send the Element.
    rpc.meros.signedElement(elem)

    #Sleep for thirty seconds to make sure Meros realizes our connection is dead.
    sleep(30)

    #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.")
Ejemplo n.º 16
0
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, 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

    raise GenerationError(
        "Tried to sign an Element in a Block we didn't recognize the type of.")
Ejemplo n.º 17
0
def verify(rpc: RPC, tx: bytes) -> None:
    sv: SignedVerification = SignedVerification(tx)
    sv.sign(0, PrivateKey(0))
    if rpc.meros.signedElement(sv) != rpc.meros.live.recv():
        raise TestError("Meros didn't send back a Verification.")
Ejemplo n.º 18
0
#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)])
]

#Send which spend the remaining descendant of the beaten Transaction.
sends.append(Send([(sends[2].hash, 0)], [(bytes(32), claim.amount // 2)]))

for s in range(len(sends)):
    sends[s].sign(edPrivKey)
    sends[s].beat(sendFilter)
    if s < 3:
        transactions.add(sends[s])

verif: SignedVerification = SignedVerification(sends[2].hash, 1)
verif.sign(1, PrivateKey(1))

merit.add(
    PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200,
                   packets=[
                       VerificationPacket(sends[0].hash, [0]),
                       VerificationPacket(sends[1].hash, [1])
                   ]).finish(0, merit))

merit.add(
    PrototypeBlock(merit.blockchain.blocks[-1].header.time + 1200,
                   packets=[VerificationPacket(sends[2].hash,
                                               [0])]).finish(0, merit))

for _ in range(4):
Ejemplo n.º 19
0
def PartialArchiveTest(rpc: RPC) -> None:
    vectors: Dict[str, Any]
    with open("e2e/Vectors/Consensus/Verification/PartialArchive.json",
              "r") as file:
        vectors = json.loads(file.read())

    data: Data = Data.fromJSON(vectors["data"])
    svs: List[SignedVerification] = [
        SignedVerification.fromSignedJSON(vectors["verifs"][0]),
        SignedVerification.fromSignedJSON(vectors["verifs"][1])
    ]

    key: PrivateKey = PrivateKey(
        bytes.fromhex(rpc.call("personal", "getMiner")))

    def sendDataAndVerifications() -> None:
        if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
            raise TestError(
                "Meros didn't rebroadcast a Transaction we sent it.")
        for sv in svs:
            if rpc.meros.signedElement(sv) != rpc.meros.live.recv():
                raise TestError(
                    "Meros didn't rebroadcast a SignedVerification we sent it."
                )

        #As we don't have a quality RPC route for this, we need to use getTemplate.
        if bytes.fromhex(
                rpc.call("merit", "getBlockTemplate",
                         [key.toPublicKey().serialize().hex()
                          ])["header"])[36:68] != BlockHeader.createContents(
                              [VerificationPacket(data.hash, [0, 1])]):
            raise TestError(
                "New Block template doesn't have a properly created packet.")

    def verifyRecreation() -> None:
        template: Dict[str,
                       Any] = rpc.call("merit", "getBlockTemplate",
                                       [key.toPublicKey().serialize().hex()])
        if bytes.fromhex(
                template["header"])[36:68] != BlockHeader.createContents(
                    [VerificationPacket(data.hash, [1])]):
            raise TestError(
                "New Block template doesn't have a properly recreated packet.")

        #Mining it further verifies the internal state.
        header: bytes = bytes.fromhex(template["header"])
        proof: int = 0
        sig: bytes
        while True:
            initial: bytes = RandomX(header +
                                     proof.to_bytes(4, byteorder="little"))
            sig = key.sign(initial).serialize()
            final: bytes = RandomX(initial + sig)
            if (int.from_bytes(final, "little") *
                    template["difficulty"]) < int.from_bytes(
                        bytes.fromhex("FF" * 32), "little"):
                break
            proof += 1

        rpc.call("merit", "publishBlock", [
            template["id"],
            (header + proof.to_bytes(4, byteorder="little") + sig).hex()
        ])

        raise SuccessError(
            "Stop Liver from trying to verify the vector chain which doesn't have this Block."
        )

    #We may not want to use Liver here.
    #There's a very small Block count and we can't let it terminate (hence the SE).
    with raises(SuccessError):
        Liver(rpc,
              vectors["blockchain"],
              callbacks={
                  2: sendDataAndVerifications,
                  3: verifyRecreation
              }).live()
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
for i in range(4):
  merit.add(Block.fromJSON(blankBlocks[i]))

#Create the Datas.
datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())]
datas.append(Data(datas[-1].hash, bytes(1)))
for data in datas:
  data.sign(edPrivKey)
  data.beat(dataFilter)
  transactions.add(data)

#Verify them in unique Blocks.
packet: List[VerificationPacket]
for data in datas:
  verif: SignedVerification = SignedVerification(data.hash)
  verif.sign(0, blsPrivKey)
  packet = [VerificationPacket(data.hash, [0])]

  block = Block(
    BlockHeader(
      0,
      merit.blockchain.last(),
      BlockHeader.createContents(packet),
      1,
      bytes(4),
      BlockHeader.createSketchCheck(bytes(4), packet),
      0,
      merit.blockchain.blocks[-1].header.time + 1200
    ),
    BlockBody(packet, [], verif.signature)
Ejemplo n.º 22
0
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)
Ejemplo n.º 23
0
def HundredFiftyFiveTest(rpc: RPC) -> None:
    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()
    ]

    blsPrivKey: PrivateKey = PrivateKey(
        bytes.fromhex(rpc.call("personal", "getMiner")))
    blsPubKey: bytes = blsPrivKey.toPublicKey().serialize()

    blockchain: Blockchain = Blockchain()
    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)

    rpc.call("merit", "publishBlock",
             [template["id"], block.serialize().hex()])

    if MessageType(rpc.meros.live.recv()[0]) != MessageType.BlockHeader:
        raise TestError("Meros didn't broadcast the Block we just published.")
    #Ignore the Verification for the Block's Data.
    if MessageType(rpc.meros.live.recv()[0]) != MessageType.SignedVerification:
        raise TestError(
            "Meros didn't send the SignedVerification for the Block's Data.")

    datas: List[Data] = [
        Data(bytes(32), edPubKeys[0].to_bytes()),
        Data(bytes(32), edPubKeys[1].to_bytes())
    ]

    for d in range(len(datas)):
        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.")
Ejemplo n.º 24
0
blsPubKey: PublicKey = blsPrivKey.toPublicKey()

spamFilter: SpamFilter = SpamFilter(5)

#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])

#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([
Ejemplo n.º 25
0
#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(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):
    #Mine it.
Ejemplo n.º 26
0
dataFilter: SpamFilter = SpamFilter(5)

edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32)
edPubKey: bytes = edPrivKey.get_verifying_key()

proto: PrototypeChain = PrototypeChain(40, keepUnlocked=True)
proto.add(1)

datas: List[Data] = [Data(bytes(32), edPubKey)]
for d in range(2):
  datas.append(Data(datas[0].hash, d.to_bytes(1, "little")))
for data in datas:
  data.sign(edPrivKey)
  data.beat(dataFilter)

verif: SignedVerification = SignedVerification(datas[1].hash)
verif.sign(0, PrivateKey(0))
proto.add(
  packets=[
    VerificationPacket(datas[0].hash, [0]),
    VerificationPacket(datas[2].hash, [1])
  ]
)

for _ in range(5):
  proto.add()

with open("e2e/Vectors/Consensus/Families/UnmentionedBeatMentioned.json", "w") as vectors:
  vectors.write(json.dumps({
    "blockchain": proto.toJSON(),
    "datas": [data.toJSON() for data in datas],
Ejemplo n.º 27
0
#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(
Ejemplo n.º 28
0
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)) +
Ejemplo n.º 29
0
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,
Ejemplo n.º 30
0
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.