Exemple #1
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()
Exemple #2
0
#Ed25519 lib.
import ed25519

#Blake2b standard function.
from hashlib import blake2b

#JSON standard lib.
import json

#Blank Blocks.
bbFile: IO[Any] = open("e2e/Vectors/Merit/BlankBlocks.json", "r")
blankBlocks: List[Dict[str, Any]] = json.loads(bbFile.read())
bbFile.close()

#Transactions.
transactions: Transactions = Transactions()
#Merit.
merit: Merit = Merit()

#SpamFilter.
dataFilter: SpamFilter = SpamFilter(5)

#Ed25519 keys.
edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32)
edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key()

#BLS keys.
blsPrivKey: PrivateKey = PrivateKey(blake2b(b'\0', digest_size=32).digest())
blsPubKey: PublicKey = blsPrivKey.toPublicKey()

#Add 1 Blank Block.
Exemple #3
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)
Exemple #4
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)
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()