Пример #1
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.")
Пример #2
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()
Пример #3
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.")
Пример #4
0
  def testBlockchain(
    b: int
  ) -> None:
    #Data.
    data: Data = Data.fromJSON(vectors["data"])

    #pylint: disable=no-member
    #MeritRemoval.
    removal: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(vectors["removals"][b])

    #Create and execute a Liver to send the MeritRemoval.
    def sendMeritRemoval() -> None:
      #Send the Data.
      if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
        raise TestError("Meros didn't send back the Data.")

      rpc.meros.signedElement(removal)
      try:
        if len(rpc.meros.live.recv()) != 0:
          raise Exception()
      except TestError:
        raise SuccessError("Meros rejected our MeritRemoval created from the same Element.")
      except Exception:
        raise TestError("Meros accepted our MeritRemoval created from the same Element.")

    Liver(
      rpc,
      vectors["blockchain"],
      callbacks={
        1: sendMeritRemoval
      }
    ).live()
Пример #5
0
def LowerHashTieBreakTest(rpc: RPC) -> None:
    vectors: Dict[str, Any]
    with open("e2e/Vectors/Consensus/Families/LowerHashTieBreak.json",
              "r") as file:
        vectors = json.loads(file.read())
    datas: List[Data] = [Data.fromJSON(data) for data in vectors["datas"]]

    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.")

    def verifyLowerHashWon() -> None:
        data: Data = datas[1]
        if int.from_bytes(data.hash, "little") > int.from_bytes(
                datas[2].hash, "little"):
            data = datas[2]
        if not rpc.call("consensus", "getStatus",
                        {"hash": data.hash.hex()})["verified"]:
            raise TestError(
                "Meros didn't verify the tied Transaction with a lower hash.")

    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              40: sendDatas,
              46: verifyLowerHashWon
          }).live()
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()
Пример #7
0
def PruneUnaddableTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Transactions/PruneUnaddable.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    pruned: bytes = Data.fromJSON(vectors["datas"][2]).hash
    prunedDescendant: bytes = Data.fromJSON(vectors["datas"][3]).hash

    def sendDatas() -> None:
        for data in vectors["datas"]:
            if rpc.meros.liveTransaction(
                    Data.fromJSON(data)) != rpc.meros.live.recv():
                raise TestError("Meros didn't send back the Data.")

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

    def verifyAdded() -> None:
        rpc.call("transactions", "getTransaction", [pruned.hex()])
        rpc.call("consensus", "getStatus", [pruned.hex()])

    def verifyPruned() -> None:
        try:
            rpc.call("transactions", "getTransaction", [pruned.hex()])
            rpc.call("transactions", "getTransaction",
                     [prunedDescendant.hex()])
            rpc.call("consensus", "getStatus", [pruned.hex()])
            rpc.call("consensus", "getStatus", [prunedDescendant.hex()])
            raise Exception()
        except TestError:
            pass
        except Exception:
            raise TestError("Meros didn't prune the Transaction.")

    #Create and execute a Liver.
    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              1: sendDatas,
              2: verifyAdded,
              8: verifyPruned
          }).live()
Пример #8
0
    def sendDatas() -> None:
        for data in vectors["datas"]:
            if rpc.meros.liveTransaction(
                    Data.fromJSON(data)) != rpc.meros.live.recv():
                raise TestError("Meros didn't send back the Data.")

        #Send the beaten Data's descendant's verification.
        if rpc.meros.signedElement(
                SignedVerification.fromSignedJSON(
                    vectors["verification"])) != rpc.meros.live.recv():
            raise TestError("Meros didn't send back the SignedVerification.")
Пример #9
0
def HundredThirtyFiveTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Consensus/MeritRemoval/HundredThirtyFive.json", "r")
  vectors: Dict[str, Any] = json.loads(file.read())
  file.close()

  #Datas.
  datas: List[Data] = [
    Data.fromJSON(vectors["datas"][0]),
    Data.fromJSON(vectors["datas"][1]),
    Data.fromJSON(vectors["datas"][2])
  ]

  #Transactions.
  transactions: Transactions = Transactions()
  for data in datas:
    transactions.add(data)

  #First MeritRemoval.
  mr: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(vectors["removal"])

  def sendMeritRemoval() -> None:
    #Send the Datas.
    for data in datas:
      if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
        raise TestError("Meros didn't send us the Data.")

    #Send and verify the original MeritRemoval.
    if rpc.meros.signedElement(mr) != rpc.meros.live.recv():
      raise TestError("Meros didn't send us the Merit Removal.")
    verifyMeritRemoval(rpc, 1, 1, mr.holder, True)

  Liver(
    rpc,
    vectors["blockchain"],
    transactions,
    callbacks={
      1: sendMeritRemoval
    }
  ).live()
Пример #10
0
 def fromJSON(json: Dict[str, Dict[str, Any]]) -> Any:
     result = Transactions()
     for tx in json:
         if json[tx]["descendant"] == "Claim":
             result.add(Claim.fromJSON(json[tx]))
         elif json[tx]["descendant"] == "Send":
             result.add(Send.fromJSON(json[tx]))
         elif json[tx]["descendant"] == "Data":
             result.add(Data.fromJSON(json[tx]))
         else:
             raise Exception("JSON has an unsupported Transaction type: " +
                             json[tx]["descendant"])
     return result
Пример #11
0
def MultiplePacketsTest(rpc: RPC) -> None:
    #Spawn a Blockchain just to set the RandomX key.
    _: Blockchain = Blockchain()

    vectors: Dict[str, Any]
    with open("e2e/Vectors/Merit/MultiplePackets.json", "r") as file:
        vectors = json.loads(file.read())

    data: Data = Data.fromJSON(vectors["data"])
    block: Block = Block.fromJSON(vectors["blockchain"][-1])

    def sendDataAndBlock() -> None:
        #Send the Data.
        if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
            raise TestError("Meros didn't send back the Data.")

        rpc.meros.liveBlockHeader(block.header)
        rpc.meros.handleBlockBody(block)
        msg: bytes = rpc.meros.sync.recv()
        if MessageType(msg[0]) != MessageType.SketchHashRequests:
            raise TestError("Meros didn't request the packets for this Block.")

        packets: Dict[int, VerificationPacket] = {}
        for packet in block.body.packets:
            packets[Sketch.hash(block.header.sketchSalt, packet)] = packet

        #Look up each requested packet and respond accordingly.
        for h in range(int.from_bytes(msg[33:37], byteorder="little")):
            sketchHash: int = int.from_bytes(msg[37 + (h * 8):45 + (h * 8)],
                                             byteorder="little")
            if sketchHash not in packets:
                raise TestError("Meros asked for a non-existent Sketch Hash.")
            rpc.meros.packet(packets[sketchHash])

        try:
            if MessageType(
                    rpc.meros.live.recv()[0]) == MessageType.BlockHeader:
                raise TestError("Meros added the Block.")
        except Exception as e:
            if str(e) != "Meros added the Block.":
                raise SuccessError()

    with raises(SuccessError):
        Liver(rpc, vectors["blockchain"], callbacks={
            2: sendDataAndBlock
        }).live()
Пример #12
0
def PruneUnaddableTest(rpc: RPC) -> None:
    vectors: Dict[str, Any]
    with open("e2e/Vectors/Transactions/Prune/PruneUnaddable.json",
              "r") as file:
        vectors = json.loads(file.read())

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

    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]

    def verifyAdded() -> None:
        for data in datas:
            rpc.call("transactions", "getTransaction",
                     {"hash": data.hash.hex()})
            rpc.call("consensus", "getStatus", {"hash": data.hash.hex()})

    def verifyPruned() -> None:
        for data in datas[2:]:
            with raises(TestError):
                rpc.call("transactions", "getTransaction",
                         {"hash": data.hash.hex()})
            with raises(TestError):
                rpc.call("consensus", "getStatus", {"hash": data.hash.hex()})

    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              1: sendDatas,
              2: verifyAdded,
              7: verifyPruned
          }).live()
Пример #13
0
def PruneUnaddableTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Transactions/PruneUnaddable.json", "r")
  vectors: Dict[str, Any] = json.loads(file.read())
  file.close()

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

  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.")

  def verifyAdded() -> None:
    for data in datas:
      rpc.call("transactions", "getTransaction", [data.hash.hex()])
      rpc.call("consensus", "getStatus", [data.hash.hex()])

  #def verifyPruned() -> None:
  #  for data in datas[2:]:
  #    with raises(TestError):
  #      rpc.call("transactions", "getTransaction", [data.hash.hex()])
  #    with raises(TestError):
  #      rpc.call("consensus", "getStatus", [data.hash.hex()])

  Liver(
    rpc,
    vectors["blockchain"],
    callbacks={
      1: sendDatas,
      2: verifyAdded
    }
  ).live()
Пример #14
0
def HundredThirtyThreeTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Consensus/MeritRemoval/HundredThirtyThree.json", "r")
  vectors: Dict[str, Any] = json.loads(file.read())
  file.close()

  #Datas.
  datas: List[Data] = [
    Data.fromJSON(vectors["datas"][0]),
    Data.fromJSON(vectors["datas"][1]),
    Data.fromJSON(vectors["datas"][2])
  ]

  #Transactions.
  transactions: Transactions = Transactions()
  for data in datas:
    transactions.add(data)

  def testBlockchain(
    i: int
  ) -> None:
    def sendMeritRemoval() -> None:
      #Send the Datas.
      for data in datas:
        if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
          raise TestError("Meros didn't send us the Data.")

      #Send the Block containing the modified Merit Removal.
      block: Block = Block.fromJSON(vectors["blockchains"][i][-1])
      rpc.meros.liveBlockHeader(block.header)

      #Flag of if the Block's Body synced.
      blockBodySynced: bool = False

      #Handle sync requests.
      reqHash: bytes = bytes()
      while True:
        if blockBodySynced:
          #Sleep for a second so Meros handles the Block.
          sleep(1)

          #Try receiving from the Live socket, where Meros sends keep-alives.
          try:
            if len(rpc.meros.live.recv()) != 0:
              raise Exception()
          except TestError:
            #Verify the height is 2.
            #The genesis Block and the Block granting Merit.
            try:
              if rpc.call("merit", "getHeight") != 2:
                raise Exception()
            except Exception:
              raise TestError("Node added a Block containg a repeat MeritRemoval.")

            #Since the node didn't add the Block, raise SuccessError.
            raise SuccessError("Node didn't add a Block containing a repeat MeritRemoval.")
          except Exception:
            raise TestError("Meros sent a keep-alive.")

        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.
          blockBodySynced = True
          rpc.meros.blockBody(block)

        else:
          raise TestError("Unexpected message sent: " + msg.hex().upper())

    Liver(
      rpc,
      vectors["blockchains"][i],
      transactions,
      callbacks={
        1: sendMeritRemoval
      }
    ).live()

  with raises(SuccessError):
    for b in range(2):
      testBlockchain(b)
Пример #15
0
def VParsableTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Consensus/Verification/Parsable.json",
                         "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    merit: Merit = Merit.fromJSON(vectors["blockchain"])
    transactions: Transactions = Transactions()
    transactions.add(Data.fromJSON(vectors["data"]))

    #Custom function to send the last Block and verify it errors at the right place.
    def checkFail() -> None:
        #This Block should cause the node to disconnect us AFTER it syncs our Transaction.
        syncedTX: bool = False

        block: Block = merit.blockchain.blocks[2]
        rpc.meros.liveBlockHeader(block.header)

        #Handle sync requests.
        reqHash: bytes = bytes()
        while True:
            if syncedTX:
                #Try receiving from the Live socket, where Meros sends keep-alives.
                try:
                    if len(rpc.meros.live.recv()) != 0:
                        raise Exception()
                except TestError:
                    raise SuccessError(
                        "Node disconnected us after we sent a parsable, yet invalid, Transaction."
                    )
                except Exception:
                    raise TestError("Meros sent a keep-alive.")

            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)

            elif MessageType(msg[0]) == MessageType.SketchHashesRequest:
                if not block.body.packets:
                    raise TestError(
                        "Meros asked for Sketch Hashes from a Block without any."
                    )

                reqHash = msg[1:33]
                if reqHash != block.header.hash:
                    raise TestError(
                        "Meros asked for Sketch Hashes that didn't belong to the Block we just sent it."
                    )

                #Create the haashes.
                hashes: List[int] = []
                for packet in block.body.packets:
                    hashes.append(Sketch.hash(block.header.sketchSalt, packet))

                #Send the Sketch Hashes.
                rpc.meros.sketchHashes(hashes)

            elif MessageType(msg[0]) == MessageType.SketchHashRequests:
                if not block.body.packets:
                    raise TestError(
                        "Meros asked for Verification Packets from a Block without any."
                    )

                reqHash = msg[1:33]
                if reqHash != block.header.hash:
                    raise TestError(
                        "Meros asked for Verification Packets that didn't belong to the Block we just sent it."
                    )

                #Create a lookup of hash to packets.
                packets: Dict[int, VerificationPacket] = {}
                for packet in block.body.packets:
                    packets[Sketch.hash(block.header.sketchSalt,
                                        packet)] = packet

                #Look up each requested packet and respond accordingly.
                for h in range(int.from_bytes(msg[33:37], byteorder="little")):
                    sketchHash: int = int.from_bytes(msg[37 + (h * 8):45 +
                                                         (h * 8)],
                                                     byteorder="little")
                    if sketchHash not in packets:
                        raise TestError(
                            "Meros asked for a non-existent Sketch Hash.")
                    rpc.meros.packet(packets[sketchHash])

            elif MessageType(msg[0]) == MessageType.TransactionRequest:
                reqHash = msg[1:33]

                if reqHash not in transactions.txs:
                    raise TestError(
                        "Meros asked for a non-existent Transaction.")

                rpc.meros.syncTransaction(transactions.txs[reqHash])
                syncedTX = True

            else:
                raise TestError("Unexpected message sent: " +
                                msg.hex().upper())

    with raises(SuccessError):
        Liver(rpc,
              vectors["blockchain"],
              transactions,
              callbacks={
                  1: checkFail
              }).live()
Пример #16
0
def VerifyCompetingTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "e2e/Vectors/Consensus/MeritRemoval/VerifyCompeting.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Datas.
    datas: List[Data] = [
        Data.fromJSON(vectors["datas"][0]),
        Data.fromJSON(vectors["datas"][1]),
        Data.fromJSON(vectors["datas"][2])
    ]

    #Transactions.
    transactions: Transactions = Transactions()
    for data in datas:
        transactions.add(data)

    #Initial Data's Verification.
    verif: SignedVerification = SignedVerification.fromSignedJSON(
        vectors["verification"])

    #MeritRemoval.
    #pylint: disable=no-member
    removal: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(
        vectors["removal"])

    #Create and execute a Liver to cause a Signed MeritRemoval.
    def sendElements() -> None:
        #Send the Datas.
        for data in datas:
            if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
                raise TestError("Meros didn't send us the Data.")

        #Send the initial Data's verification.
        if rpc.meros.signedElement(verif) != rpc.meros.live.recv():
            raise TestError("Meros didn't us the initial Data's Verification.")

        #Send the first Element.
        if rpc.meros.signedElement(removal.se1) != rpc.meros.live.recv():
            raise TestError("Meros didn't send us the Verification.")

        #Trigger the MeritRemoval.
        rpc.meros.signedElement(removal.se2)
        if rpc.meros.live.recv() != (MessageType.SignedMeritRemoval.toByte() +
                                     removal.signedSerialize()):
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 1, removal.holder, True)

    Liver(rpc,
          vectors["blockchain"],
          transactions,
          callbacks={
              1: sendElements,
              2: lambda: verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
          }).live()

    #Create and execute a Liver to handle a Signed MeritRemoval.
    def sendMeritRemoval() -> None:
        #Send the Datas.
        for data in datas:
            if rpc.meros.liveTransaction(data) != rpc.meros.live.recv():
                raise TestError("Meros didn't send us the Data.")

        #Send the initial Data's verification.
        if rpc.meros.signedElement(verif) != rpc.meros.live.recv():
            raise TestError("Meros didn't us the initial Data's Verification.")

        #Send and verify the MeritRemoval.
        if rpc.meros.signedElement(removal) != rpc.meros.live.recv():
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 1, removal.holder, True)

    Liver(rpc,
          vectors["blockchain"],
          transactions,
          callbacks={
              1: sendMeritRemoval,
              2: lambda: verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
          }).live()

    #Create and execute a Syncer to handle a Signed MeritRemoval.
    Syncer(rpc, vectors["blockchain"], transactions).sync()
    verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
Пример #17
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()
Пример #18
0
def MatchesHeaderQuantityTest(meros: Meros) -> None:
    #Create an instance of Merit to make sure the RandomX VM key was set.
    Merit()

    blocks: List[Block]
    txs: List[Data] = []
    verifs: List[SignedVerification] = []
    with open(
            "e2e/Vectors/Merit/TwoHundredSeventyFour/MatchesHeaderQuantity.json",
            "r") as file:
        vectors: Dict[str, Any] = json.loads(file.read())
        blocks = [Block.fromJSON(block) for block in vectors["blocks"]]
        txs = [Data.fromJSON(tx) for tx in vectors["transactions"]]
        verifs = [
            SignedVerification.fromSignedJSON(verif)
            for verif in vectors["verifications"]
        ]

    #Connect.
    meros.liveConnect(blocks[0].header.last)
    meros.syncConnect(blocks[0].header.last)

    #Send a single Block to earn Merit.
    meros.liveBlockHeader(blocks[0].header)
    meros.handleBlockBody(blocks[0])

    #Send the header.
    meros.liveBlockHeader(blocks[1].header)

    #Fail Sketch Resolution, and send a different amount of sketch hashes.
    meros.handleBlockBody(blocks[1], 0)
    if MessageType(meros.sync.recv()[0]) != MessageType.SketchHashesRequest:
        raise TestError(
            "Meros didn't request the hashes after failing sketch resolution.")

    #Send a quantity of sketch hashes that doesn't match the header.
    meros.sketchHashes([
        Sketch.hash(blocks[1].header.sketchSalt,
                    VerificationPacket(tx.hash, [0])) for tx in txs
    ])
    try:
        if len(meros.sync.recv()) == 0:
            raise TestError()
        raise Exception()
    except TestError:
        pass
    except Exception:
        raise TestError("Meros tried to further sync an invalid Block Body.")

    #Sleep so we can reconnect.
    sleep(65)

    #Repeat setup.
    meros.liveConnect(blocks[0].header.last)
    meros.syncConnect(blocks[0].header.last)

    #Send two Transactions.
    for i in range(2):
        meros.liveTransaction(txs[i])
        meros.signedElement(verifs[i])

    #Send the header and a large enough sketch to cause resolution.
    meros.liveBlockHeader(blocks[1].header)
    meros.handleBlockBody(blocks[1], 3)

    #Should now have been disconnected thanks to having 5 hashes.
    try:
        if len(meros.sync.recv()) == 0:
            raise TestError()
        raise Exception()
    except TestError:
        pass
    except Exception:
        raise TestError("Meros tried to further sync an invalid Block Body.")