Пример #1
0
def SameNonceTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Consensus/MeritRemoval/SameNonce.json",
                         "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #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 Elements.
        rpc.meros.signedElement(removal.se1)
        rpc.meros.signedElement(removal.se2)

        #Verify the first Element.
        if rpc.meros.live.recv() != (MessageType.SignedDataDifficulty.toByte()
                                     + removal.se1.signedSerialize()):
            raise TestError("Meros didn't send us the first Data Difficulty.")

        #Verify the MeritRemoval.
        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"],
          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 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"],
          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"]).sync()
    verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
Пример #2
0
def PartialTest(
  rpc: RPC
) -> None:
  vectors: Dict[str, Any]
  with open("e2e/Vectors/Consensus/MeritRemoval/Partial.json", "r") as file:
    vectors = json.loads(file.read())

  removal: PartialMeritRemoval = PartialMeritRemoval.fromSignedJSON(vectors["removal"])

  #Create and execute a Liver to cause a Partial MeritRemoval.
  def sendElement() -> None:
    #Send the second Element.
    rpc.meros.signedElement(removal.se2)

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

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

  #Create and execute a Liver to handle a Partial MeritRemoval.
  def sendMeritRemoval() -> None:
    #Send and verify the MeritRemoval.
    if rpc.meros.meritRemoval(removal) != rpc.meros.live.recv():
      raise TestError("Meros didn't send us the Merit Removal.")
    verifyMeritRemoval(rpc, 2, 2, removal.holder, True)

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

  #Create and execute a Syncer to handle a Partial MeritRemoval.
  Syncer(rpc, vectors["blockchain"]).sync()
  verifyMeritRemoval(rpc, 2, 2, removal.holder, False)
Пример #3
0
def VCompetingTest(rpc: RPC) -> None:
    vectors: Dict[str, Any]
    with open("e2e/Vectors/Consensus/Verification/Competing.json",
              "r") as file:
        vectors = json.loads(file.read())

    transactions: Transactions = Transactions.fromJSON(vectors["transactions"])

    #Function to verify the right Transaction was confirmed.
    def verifyConfirmation() -> None:
        if not rpc.call("consensus", "getStatus",
                        {"hash": vectors["verified"]})["verified"]:
            raise TestError(
                "Didn't verify the Send which should have been verified.")

        if rpc.call("consensus", "getStatus",
                    {"hash": vectors["beaten"]})["verified"]:
            raise TestError(
                "Did verify the Send which should have been beaten.")

    Liver(rpc,
          vectors["blockchain"],
          transactions,
          callbacks={
              19: verifyConfirmation
          }).live()
    Syncer(rpc, vectors["blockchain"], transactions).sync()
Пример #4
0
def UnionedFamiliesMultipleWinnersTest(rpc: RPC) -> None:
    vectors: Dict[str, Any]
    with open(
            "e2e/Vectors/Consensus/Families/UnionedFamiliesMultipleWinners.json",
            "r") as file:
        vectors = json.loads(file.read())
    sends: List[Send] = [Send.fromJSON(send) for send in vectors["sends"]]

    def sendSends() -> None:
        for s in range(len(sends)):
            if rpc.meros.liveTransaction(sends[s]) != rpc.meros.live.recv():
                raise TestError("Meros didn't broadcast a Send.")

    def verifyMultipleWon() -> None:
        for send in [sends[1], *sends[3:]]:
            if rpc.call("consensus", "getStatus",
                        [send.hash.hex()])["verified"]:
                raise TestError(
                    "Meros verified a transaction which was beaten by another transaction."
                )
        for send in [sends[0], sends[2]]:
            if not rpc.call("consensus", "getStatus",
                            [send.hash.hex()])["verified"]:
                raise TestError(
                    "Meros didn't verify the verified transaction for each original family."
                )

    Liver(rpc,
          vectors["blockchain"],
          Transactions.fromJSON(vectors["transactions"]),
          callbacks={
              44: sendSends,
              50: verifyMultipleWon
          }).live()
def RespondsWithRequestedCapacityTest(
  rpc: RPC
) -> None:
  vectors: Dict[str, Any]
  with open("e2e/Vectors/Merit/TwoHundredSeventyFour/RespondsWithRequestedCapacity.json", "r") as file:
    vectors = json.loads(file.read())

  def requestWithCapacity() -> None:
    block: Block = Block.fromJSON(vectors["blockchain"][-1])

    #Request 3/6 Transactions.
    rpc.meros.sync.send(MessageType.BlockBodyRequest.toByte() + block.header.hash + (3).to_bytes(4, "little"))
    if rpc.meros.sync.recv() != (MessageType.BlockBody.toByte() + block.body.serialize(block.header.sketchSalt, 3)):
      raise TestError("Meros didn't respond with the requested capacity.")

    #Request 8/6 Transactions.
    rpc.meros.sync.send(MessageType.BlockBodyRequest.toByte() + block.header.hash + (8).to_bytes(4, "little"))
    if rpc.meros.sync.recv() != (MessageType.BlockBody.toByte() + block.body.serialize(block.header.sketchSalt, 6)):
      raise TestError("Meros didn't respond with the requested capacity (normalized).")

  Liver(
    rpc,
    vectors["blockchain"],
    Transactions.fromJSON(vectors["transactions"]),
    callbacks={
      2: requestWithCapacity
    }
  ).live()
Пример #6
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()
Пример #7
0
def NodeThresholdTest(rpc: RPC) -> None:
    edPrivKey: Ristretto.SigningKey = Ristretto.SigningKey(b'\0' * 32)

    dataFilter: SpamFilter = SpamFilter(5)

    datas: List[Data] = [Data(bytes(32), edPrivKey.get_verifying_key())]
    datas[-1].sign(edPrivKey)
    datas[-1].beat(dataFilter)

    def verifyThreshold(b: int) -> None:
        rpc.meros.liveTransaction(datas[-1])
        datas.append(Data(datas[-1].hash, b"a"))
        datas[-1].sign(edPrivKey)
        datas[-1].beat(dataFilter)

        #Swallow the new Data(s).
        if b == 1:
            rpc.meros.live.recv()
        rpc.meros.live.recv()

        #Check the threshold.
        threshold: int = rpc.call("consensus", "getStatus",
                                  {"hash": datas[-2].hash.hex()})["threshold"]
        if b < 9:
            if threshold != ((max(b + 6, 5) // 5 * 4) + 1):
                raise TestError(
                    "Meros didn't calculate the right node threshold. That said, this isn't defined by the protocol."
                )
        elif threshold != 5:
            raise TestError("Meros didn't lower the node threshold.")

    with open("e2e/Vectors/Merit/BlankBlocks.json", "r") as file:
        Liver(rpc, json.loads(file.read())[:9],
              everyBlock=verifyThreshold).live()
Пример #8
0
def DataDifficultyTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "e2e/Vectors/Consensus/Difficulties/DataDifficulty.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Verify functions.
    vddStarting: Callable[[], None] = lambda: verifyDataDifficulty(rpc, 5)
    vddEarnedVote: Callable[[], None] = lambda: verifyDataDifficulty(rpc, 2)
    vddVoted: Callable[[], None] = lambda: verifyDataDifficulty(rpc, 1)

    def vmr() -> None:
        verifyMeritRemoval(rpc, 52, 52, 0, False)
        vddStarting()

    def vEarnedBack() -> None:
        vddStarting()

    #Create and execute a Liver/Syncer.
    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              26: vddStarting,
              50: vddEarnedVote,
              51: vddVoted,
              52: vmr,
              103: vEarnedBack
          }).live()
    Syncer(rpc, vectors["blockchain"]).sync()
Пример #9
0
def FiftyTest(rpc: RPC) -> None:
    with open("e2e/Vectors/Transactions/Fifty.json", "r") as file:
        vectors: Dict[str, Any] = json.loads(file.read())
        Liver(rpc, vectors["blockchain"],
              Transactions.fromJSON(vectors["transactions"])).live()
        Syncer(rpc, vectors["blockchain"],
               Transactions.fromJSON(vectors["transactions"])).sync()
Пример #10
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 UnionedFamiliesSingleWinnerTest(
  rpc: RPC
) -> None:
  vectors: Dict[str, Any]
  with open("e2e/Vectors/Consensus/Families/UnionedFamiliesSingleWinner.json", "r") as file:
    vectors = json.loads(file.read())
  sends: List[Send] = [Send.fromJSON(send) for send in vectors["sends"]]

  def sendSends() -> None:
    for s in range(len(sends)):
      if rpc.meros.liveTransaction(sends[s]) != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast a Send.")

  def verifyUnionizingWon() -> None:
    for send in sends[:-1]:
      if rpc.call("consensus", "getStatus", {"hash": send.hash.hex()})["verified"]:
        raise TestError("Meros verified a transaction which was beaten by a unionizing transaction.")
    if not rpc.call("consensus", "getStatus", {"hash": sends[-1].hash.hex()})["verified"]:
      raise TestError("Meros didn't verify the verified unionizing transaction.")

  Liver(
    rpc,
    vectors["blockchain"],
    Transactions.fromJSON(vectors["transactions"]),
    callbacks={
      45: sendSends,
      51: verifyUnionizingWon
    }
  ).live()
Пример #12
0
def ChainAdvancementTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r")
    chain: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    Liver(rpc, chain).live()
    Syncer(rpc, chain).sync()
Пример #13
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])
Пример #14
0
def StateTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Merit/State.json", "r")
    blocks: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    blockchain: Blockchain = Blockchain.fromJSON(blocks)
    state: State = State()

    def checkState(block: int) -> None:
        state.add(blockchain, block)

        meritSum: int = 0
        for miner in range(len(state.balances)):
            meritSum += state.balances[miner]
            if rpc.call("merit", "getMerit", [miner]) != {
                    "status": "Unlocked",
                    "malicious": False,
                    "merit": state.balances[miner]
            }:
                raise TestError("Merit doesn't match.")

        if meritSum != min(block, state.lifetime):
            raise TestError("Merit sum is invalid.")

    Liver(rpc, blocks, everyBlock=checkState).live()
Пример #15
0
def PendingDieRegainTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Merit/LockedMerit/PendingDieRegain.json",
                         "r")
    chain: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    def verifyCorrectlyLocked(height: int) -> None:
        merit: Dict[str, Any] = rpc.call("merit", "getMerit", [0])
        merit = {"merit": merit["merit"], "status": merit["status"]}

        if height < 9:
            if merit != {"merit": 1, "status": "Unlocked"}:
                raise TestError("Merit was locked early.")
        elif height < 100:
            if merit != {"merit": 1, "status": "Locked"}:
                raise TestError("Merit wasn't locked.")
        elif height == 100:
            if merit != {"merit": 1, "status": "Pending"}:
                raise TestError("Merit wasn't pending.")
        elif height == 101:
            if merit != {"merit": 0, "status": "Unlocked"}:
                raise TestError("Merit didn't die and become unlocked.")
        elif height == 102:
            #pylint: disable=global-statement
            global correctVectorsHeight
            correctVectorsHeight = True
            if merit != {"merit": 1, "status": "Unlocked"}:
                raise TestError("Didn't regain Merit which was unlocked.")

    Liver(rpc, chain, everyBlock=verifyCorrectlyLocked).live()

    if not correctVectorsHeight:
        raise Exception("PendingDieRegain vectors have an invalid length.")
def LockedMeritDifficultyTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Consensus/Difficulties/LockedMerit.json",
                         "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    def verifyVotedAndUnlocked() -> None:
        if rpc.call("merit", "getMerit", [0])["status"] != "Unlocked":
            raise Exception(INVALID_TEST)
        verifySendDifficulty(rpc, 2)
        verifyDataDifficulty(rpc, 2)

    def verifyDiscountedAndLocked() -> None:
        if rpc.call("merit", "getMerit", [0])["status"] != "Locked":
            raise Exception(INVALID_TEST)
        verifySendDifficulty(rpc, 3)
        verifyDataDifficulty(rpc, 5)

    def verifyCountedAndPending() -> None:
        if rpc.call("merit", "getMerit", [0])["status"] != "Pending":
            raise Exception(INVALID_TEST)
        verifySendDifficulty(rpc, 2)
        verifyDataDifficulty(rpc, 2)

    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              50: verifyVotedAndUnlocked,
              59: verifyDiscountedAndLocked,
              60: verifyCountedAndPending
          }).live()
Пример #17
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()
Пример #18
0
def DescendantHighestUnverifiedParentTest(rpc: RPC) -> None:
    vectors: Dict[str, Any]
    with open(
            "e2e/Vectors/Consensus/Families/DescendantHighestUnverifiedParent.json",
            "r") as file:
        vectors = json.loads(file.read())
    sends: List[Send] = [Send.fromJSON(send) for send in vectors["sends"]]

    def sendSends() -> None:
        for s in range(len(sends)):
            if rpc.meros.liveTransaction(sends[s]) != rpc.meros.live.recv():
                raise TestError("Meros didn't broadcast a Send.")

    def verifyDescendantLost() -> None:
        for send in sends[1:]:
            if rpc.call("consensus", "getStatus",
                        {"hash": send.hash.hex()})["verified"]:
                raise TestError(
                    "Meros verified a beaten transaction or one of its children (one of which is impossible)."
                )
        if not rpc.call("consensus", "getStatus",
                        {"hash": sends[0].hash.hex()})["verified"]:
            raise TestError(
                "Meros either didn't verify the descendant or its parent.")

    Liver(rpc,
          vectors["blockchain"],
          Transactions.fromJSON(vectors["transactions"]),
          callbacks={
              45: sendSends,
              51: verifyDescendantLost
          }).live()
Пример #19
0
def HTTSwapTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Consensus/MeritRemoval/HundredTwentyThree/Swap.json", "r")
  vectors: Dict[str, Any] = json.loads(file.read())
  file.close()

  def sendRepeatMeritRemoval() -> None:
    #Send the Block containing the modified Merit Removal.
    block: Block = Block.fromJSON(vectors["blockchain"][-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 3.
          #The genesis Block, the Block granting Merit, and the Block containing the MeritRemoval originally.
          try:
            if rpc.call("merit", "getHeight") != 3:
              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["blockchain"],
    callbacks={
      2: sendRepeatMeritRemoval
    }
  ).live()
Пример #20
0
def LockedMeritDifficultyTest(rpc: RPC) -> None:
    def verifyVotedAndUnlocked() -> None:
        if rpc.call("merit", "getMerit", {"nick": 0})["status"] != "Unlocked":
            raise Exception(INVALID_TEST)
        verifySendDifficulty(rpc, 2)
        verifyDataDifficulty(rpc, 2)

    def verifyDiscountedAndLocked() -> None:
        if rpc.call("merit", "getMerit", {"nick": 0})["status"] != "Locked":
            raise Exception(INVALID_TEST)
        verifySendDifficulty(rpc, 3)
        verifyDataDifficulty(rpc, 5)

    def verifyCountedAndPending() -> None:
        if rpc.call("merit", "getMerit", {"nick": 0})["status"] != "Pending":
            raise Exception(INVALID_TEST)
        verifySendDifficulty(rpc, 2)
        verifyDataDifficulty(rpc, 2)

    with open("e2e/Vectors/Consensus/Difficulties/LockedMerit.json",
              "r") as vectors:
        Liver(rpc,
              json.loads(vectors.read()),
              callbacks={
                  50: verifyVotedAndUnlocked,
                  59: verifyDiscountedAndLocked,
                  60: verifyCountedAndPending
              }).live()
Пример #21
0
def DepthOneTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Merit/Reorganizations/DepthOne.json",
                         "r")
    chains: Dict[str, List[Dict[str, Any]]] = json.loads(file.read())
    file.close()

    #Load the alternate blockchain.
    alt: Blockchain = Blockchain.fromJSON(chains["alt"])

    #Send the alternate tip.
    def sendAlternateTip() -> None:
        header: bytes = rpc.meros.liveBlockHeader(alt.blocks[-1].header)
        req: bytes = rpc.meros.sync.recv()
        if req != (MessageType.BlockBodyRequest.toByte() +
                   alt.blocks[-1].header.hash):
            raise TestError("Meros didn't request the BlockBody.")
        rpc.meros.blockBody(alt.blocks[-1])

        if rpc.meros.live.recv() != header:
            raise TestError("Meros didn't send back the BlockHeader.")

        #Verify the alternate Blockchain.
        verifyBlockchain(rpc, alt)

        #Raise SuccessError so the Liver doesn't fail when verifying the original chain.
        raise SuccessError("Meros re-organized to the alternate chain.")

    with raises(SuccessError):
        Liver(rpc, chains["main"], callbacks={3: sendAlternateTip}).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()
Пример #23
0
def GetDifficultyTest(
  rpc: RPC
) -> None:
  #Check the global difficulty.
  if rpc.call("consensus", "getSendDifficulty", auth=False) != 3:
    raise TestError("getSendDifficulty didn't reply properly.")
  if rpc.call("consensus", "getDataDifficulty", auth=False) != 5:
    raise TestError("getDataDifficulty didn't reply properly.")

  #Check the difficulties for a holder who doesn't exist.
  try:
    rpc.call("consensus", "getSendDifficulty", {"holder": 0}, False)
    raise TestError("")
  except TestError as e:
    if str(e) != "-2 Holder doesn't have a SendDifficulty.":
      raise TestError("getSendDifficulty didn't raise when asked about a non-existent holder.")

  try:
    rpc.call("consensus", "getDataDifficulty", {"holder": 0}, False)
    raise TestError("")
  except TestError as e:
    if str(e) != "-2 Holder doesn't have a DataDifficulty.":
      raise TestError("getDataDifficulty didn't raise when asked about a non-existent holder.")

  def voteAndVerify() ->  None:
    #Check the difficulties for a holder who has yet to vote.
    try:
      rpc.call("consensus", "getSendDifficulty", {"holder": 0}, False)
      raise TestError("")
    except TestError as e:
      if str(e) != "-2 Holder doesn't have a SendDifficulty.":
        raise TestError("getSendDifficulty didn't raise when asked about a holder who has yet to vote.")
    try:
      rpc.call("consensus", "getDataDifficulty", {"holder": 0}, False)
      raise TestError("")
    except TestError as e:
      if str(e) != "-2 Holder doesn't have a DataDifficulty.":
        raise TestError("getDataDifficulty didn't raise when asked about a holder who has yet to vote.")

    #Create the votes.
    sendDiff: SignedSendDifficulty = SignedSendDifficulty(6, 0)
    sendDiff.sign(0, PrivateKey(0))

    dataDiff: SignedDataDifficulty = SignedDataDifficulty(10, 1)
    dataDiff.sign(0, PrivateKey(0))

    #Send them.
    rpc.meros.signedElement(sendDiff)
    rpc.meros.signedElement(dataDiff)
    rpc.meros.live.recv()
    rpc.meros.live.recv()

    #Check them.
    if rpc.call("consensus", "getSendDifficulty", {"holder": 0}, False) != 6:
      raise TestError("getSendDifficulty didn't reply with the holder's current difficulty.")
    if rpc.call("consensus", "getDataDifficulty", {"holder": 0}, False) != 10:
      raise TestError("getDataDifficulty didn't reply with the holder's current difficulty.")

  with open("e2e/Vectors/Merit/BlankBlocks.json", "r") as file:
    Liver(rpc, json.loads(file.read())[:1], callbacks={1: voteAndVerify}).live()
Пример #24
0
def HundredTwoTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Consensus/Verification/HundredTwo.json", "r")
  vectors: Dict[str, Any] = json.loads(file.read())
  file.close()

  transactions: Transactions = Transactions.fromJSON(vectors["transactions"])

  #Verifies the Transaction is added, it has the right holders, the holders Merit surpasses the threshold, yet it isn't verified.
  def verify() -> None:
    for tx in transactions.txs:
      status: Dict[str, Any] = rpc.call("consensus", "getStatus", [tx.hex()])
      if set(status["verifiers"]) != set([0, 1]):
        raise TestError("Meros doesn't have the right list of verifiers for this Transaction.")

      if status["merit"] != 80:
        raise TestError("Meros doesn't have the right amount of Merit for this Transaction.")

      if rpc.call("merit", "getMerit", [0])["merit"] + rpc.call("merit", "getMerit", [1])["merit"] < status["threshold"]:
        raise TestError("Merit sum of holders is less than the threshold.")

      if status["verified"]:
        raise TestError("Meros verified the Transaction which won't have enough Merit by the time the Transaction finalizes.")

  Liver(rpc, vectors["blockchain"], transactions, callbacks={100: verify}).live()
Пример #25
0
def MultiInputClaimTest(rpc: RPC) -> None:
    with open("e2e/Vectors/Transactions/MultiInputClaim.json", "r") as file:
        vectors: Dict[str, Any] = json.loads(file.read())
        transactions: Transactions = Transactions.fromJSON(
            vectors["transactions"])
        Liver(rpc, vectors["blockchain"], transactions).live()
        Syncer(rpc, vectors["blockchain"], transactions).sync()
Пример #26
0
def ImpossibleFamilyTest(
  rpc: RPC
) -> None:
  vectors: Dict[str, Any]
  with open("e2e/Vectors/Consensus/Families/ImpossibleFamily.json", "r") as file:
    vectors = json.loads(file.read())
  sends: List[Send] = [Send.fromJSON(send) for send in vectors["sends"]]

  def sendSends() -> None:
    for s in range(len(sends)):
      if rpc.meros.liveTransaction(sends[s]) != rpc.meros.live.recv():
        raise TestError("Meros didn't broadcast a Send.")

  def verifyPossibleWon() -> None:
    if rpc.call("consensus", "getStatus", [sends[1].hash.hex()])["verified"]:
      raise TestError("Meros verified an impossible Transaction.")
    if not rpc.call("consensus", "getStatus", [sends[0].hash.hex()])["verified"]:
      raise TestError("Meros didn't verify the only possible Transaction.")

  Liver(
    rpc,
    vectors["blockchain"],
    Transactions.fromJSON(vectors["transactions"]),
    callbacks={
      42: sendSends,
      48: verifyPossibleWon
    }
  ).live()
def ShorterChainMoreWorkTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Merit/Reorganizations/ShorterChainMoreWork.json", "r")
  chains: Dict[str, List[Dict[str, Any]]] = json.loads(file.read())
  file.close()

  #Load the alternate blockchain.
  alt: Blockchain = Blockchain.fromJSON(chains["alt"])

  #Send the alternate tip.
  def sendAlternateTip() -> None:
    header: bytes = rpc.meros.liveBlockHeader(alt.blocks[-1].header)

    req: bytes = rpc.meros.sync.recv()
    if MessageType(req[0]) != MessageType.BlockListRequest:
      raise TestError("Meros didn't request the list of previous BlockHeaders.")
    if req[3 : 35] != alt.blocks[-2].header.hash:
      raise TestError("Meros didn't request the list of previous BlockHeaders for THIS header.")

    blockList: List[bytes] = []
    b: int = len(alt.blocks) - 3
    while b != -1:
      blockList.append(alt.blocks[b].header.hash)
      b -= 1
    rpc.meros.blockList(blockList)

    diff = -4
    while diff != -1:
      req = rpc.meros.sync.recv()
      if req != (MessageType.BlockHeaderRequest.toByte() + alt.blocks[diff].header.hash):
        raise TestError("Meros didn't request a previous BlockHeader.")
      rpc.meros.syncBlockHeader(alt.blocks[diff].header)
      diff += 1

    diff = -4
    while diff != 0:
      req = rpc.meros.sync.recv()
      if req != (MessageType.BlockBodyRequest.toByte() + alt.blocks[diff].header.hash):
        raise TestError("Meros didn't request a previous BlockBody.")
      rpc.meros.blockBody(alt.blocks[diff])
      diff += 1

    if rpc.meros.live.recv() != header:
      raise TestError("Meros didn't send back the BlockHeader.")

    #Verify the alternate Blockchain.
    verifyBlockchain(rpc, alt)

    #Raise SuccessError so the Liver doesn't fail when verifying the original chain.
    raise SuccessError("Meros re-organized to the alternate chain.")

  with raises(SuccessError):
    Liver(
      rpc,
      chains["main"],
      callbacks={
        25: sendAlternateTip
      }
    ).live()
Пример #28
0
def ChainAdvancementTest(rpc: RPC) -> None:
    file: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r")
    blocks: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    #Create and execute a Liver/Syncer.
    Liver(rpc, blocks).live()
    Syncer(rpc, blocks).sync()
Пример #29
0
def KeepUnlockedTest(rpc: RPC) -> None:
    def verifyUnlocked(_: int) -> None:
        if rpc.call("merit", "getMerit", {"nick": 0})["status"] != "Unlocked":
            raise TestError("Meros didn't keep Merit unlocked.")

    with open("e2e/Vectors/Merit/LockedMerit/KeepUnlocked.json", "r") as file:
        for chain in json.loads(file.read()):
            Liver(rpc, chain, everyBlock=verifyUnlocked).live()
            Syncer(rpc, chain).sync()
Пример #30
0
def KeyChangeTest(
  rpc: RPC
) -> None:
  file: IO[Any] = open("e2e/Vectors/Merit/RandomX/KeyChange.json", "r")
  chain: List[Dict[str, Any]] = json.loads(file.read())
  file.close()

  Liver(rpc, chain).live()
  Syncer(rpc, chain).sync()