Example #1
0
def PartialTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/Partial.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    keys: Dict[bytes, int] = {
        bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]): 0
    }
    nicks: List[bytes] = [
        bytes.fromhex(vectors["blockchain"][0]["header"]["miner"])
    ]

    #MeritRemoval.
    #pylint: disable=no-member
    removal: PartialMeritRemoval = PartialMeritRemoval.fromSignedJSON(
        keys, 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.recv() != (MessageType.SignedMeritRemoval.toByte() +
                                removal.signedSerialize(nicks)):
            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.signedElement(removal) != rpc.meros.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)
Example #2
0
def SameNonceTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/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)
Example #3
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()
Example #4
0
def DepthOneTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/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.")

    #Create and execute a Liver.
    Liver(
        rpc,
        chains["main"],
        callbacks={
            3: sendAlternateTip
        }
    ).live()
def DelayedMeritHolderTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Merit/Reorganizations/DelayedMeritHolder.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[-1].header.hash:
            raise TestError("Meros didn't request the list of previous BlockHeaders for THIS header.")

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

        diff = -2
        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 = -2
        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.")

    #Create and execute a Liver.
    Liver(
        rpc,
        chains["main"],
        callbacks={
            6: sendAlternateTip
        }
    ).live()
Example #6
0
def SendDifficultyTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/Difficulties/SendDifficulty.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

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

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

    def vEarnedBack() -> None:
        vddEarnedVote()

    #Create and execute a Liver/Syncer.
    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              26: vddStarting,
              50: vddEarnedVote,
              51: vddVoted,
              52: vmr,
              102: vEarnedBack
          }).live()
    Syncer(rpc, vectors["blockchain"]).sync()
Example #7
0
def HundredTwoTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Consensus/Verification/HundredTwo.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

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

    #Create and execute a Liver.
    Liver(rpc, vectors["blockchain"], transactions, callbacks={100: verify}).live()
Example #8
0
def VCompetingTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/Verification/Competing.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Blockchain.
    blockchain: Blockchain = Blockchain.fromJSON(
        b"MEROS_DEVELOPER_NETWORK", 60,
        int(
            "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            16), vectors["blockchain"])
    #Consensus.
    consensus: Consensus = Consensus.fromJSON(
        bytes.fromhex(
            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        ),
        bytes.fromhex(
            "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
        ), vectors["consensus"])
    #Transactions.
    transactions: Transactions = Transactions.fromJSON(vectors["transactions"])

    #Create and execute a Liver/Syncer.
    Liver(rpc, blockchain, consensus, transactions).live()
    Syncer(rpc, blockchain, consensus, transactions).sync()
Example #9
0
def ChainAdvancementTest(rpc: RPC) -> None:
    file: IO[Any] = open("PythonTests/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()
def InvalidCompetingTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Consensus/MeritRemoval/InvalidCompeting.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    keys: Dict[bytes, int] = {
        bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]): 0
    }

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

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

    #Create and execute a Liver to handle the MeritRemoval.
    def sendMeritRemoval() -> None:
        #Send and verify the MeritRemoval.
        removalBytes: bytes = rpc.meros.signedElement(removal)

        done: bool = False
        while True:
            try:
                msg: bytes = rpc.meros.recv()
            except TestError:
                raise TestError("Node disconnected us.")

            if MessageType(msg[0]) == MessageType.Syncing:
                rpc.meros.syncingAcknowledged()
            elif MessageType(msg[0]) == MessageType.TransactionRequest:
                rpc.meros.transaction(transactions.txs[msg[1 : 33]])
            elif MessageType(msg[0]) == MessageType.SyncingOver:
                if done:
                    break
                done = True

        if removalBytes != rpc.meros.recv():
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 11, 11, removal.holder, True)

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

    #Create and execute a Syncer to handle the MeritRemoval.
    Syncer(rpc, vectors["blockchain"], transactions).sync()
    verifyMeritRemoval(rpc, 11, 11, removal.holder, False)
Example #11
0
def FiftyTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Transactions/Fifty.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Create and execute a Liver/Syncer.
    Liver(rpc, vectors["blockchain"], Transactions.fromJSON(vectors["transactions"])).live()
    Syncer(rpc, vectors["blockchain"], Transactions.fromJSON(vectors["transactions"])).sync()
Example #12
0
def RepeatTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/Repeat.json", "r")
    vectors: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    keys: Dict[bytes, int] = {bytes.fromhex(vectors[0]["header"]["miner"]): 0}

    def sendBlock() -> None:
        #Send the Block with the MeritRemoval archived again.
        block: Block = Block.fromJSON(keys, vectors[-1])
        rpc.meros.blockHeader(block.header)

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

        #Handle sync requests.
        reqHash: bytes = bytes()
        while True:
            try:
                msg: bytes = rpc.meros.recv()
            except TestError:
                if not blockBodySynced:
                    raise TestError(
                        "Node disconnected us before syncing the body.")
                raise SuccessError(
                    "Meros didn't add the same MeritRemoval twice.")

            if MessageType(msg[0]) == MessageType.Syncing:
                rpc.meros.syncingAcknowledged()

            elif 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)

            elif MessageType(msg[0]) == MessageType.SyncingOver:
                pass

            elif MessageType(msg[0]) == MessageType.BlockHeader:
                #Raise a TestError if the Block was added.
                raise TestError(
                    "Meros synced a Block with a repeat MeritRemoval.")

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

    Liver(rpc, vectors, callbacks={3: sendBlock}).live()
def InvalidCompetingTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/InvalidCompeting.json",
        "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

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

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

    #Create and execute a Liver to handle the MeritRemoval.
    def sendMeritRemoval() -> None:
        #Send and verify the MeritRemoval.
        removalBytes: bytes = rpc.meros.signedElement(removal)

        sent: int = 0
        while True:
            if sent == 2:
                break

            msg: bytes = rpc.meros.sync.recv()
            if MessageType(msg[0]) == MessageType.TransactionRequest:
                rpc.meros.syncTransaction(transactions.txs[msg[1:33]])
                sent += 1
            else:
                raise TestError("Unexpected message sent: " +
                                msg.hex().upper())

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

    #Verify the MeritRemoval and the Blockchain.
    def verify() -> None:
        verifyMeritRemoval(rpc, 1, 1, removal.holder, False)
        verifyBlockchain(rpc, Blockchain.fromJSON(vectors["blockchain"]))
        raise SuccessError(
            "MeritRemoval and Blockchain were properly handled.")

    Liver(rpc,
          vectors["blockchain"],
          transactions,
          callbacks={
              1: sendMeritRemoval,
              2: verify
          }).live()
Example #14
0
def DifficultyTest(rpc: RPC) -> None:
    #Blocks.
    file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r")
    blocks: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    #Blockchain.
    blockchain: Blockchain = Blockchain.fromJSON(blocks)

    def checkDifficulty(block: int) -> None:
        if int(rpc.call("merit", "getDifficulty"),
               16) != blockchain.difficulties[block][0]:
            raise TestError("Difficulty doesn't match.")

    Liver(rpc, blocks, everyBlock=checkDifficulty).live()
def HundredFortySevenTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Transactions/ClaimedMint.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Merit.
    merit: Merit = Merit.fromJSON(vectors["blockchain"])
    #Transactions.
    transactions: Transactions = Transactions.fromJSON(vectors["transactions"])

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

    #Grab the Claim hash,
    claim: bytes = merit.blockchain.blocks[-1].body.packets[0].hash

    #Create a Send which underflows.
    send: Send = Send(
        [(claim, 0)],
        [
            (pubKey.to_bytes(), 18446744073709551231),
            (pubKey.to_bytes(), 385 + Claim.fromTransaction(transactions.txs[claim]).amount)
        ]
    )
    send.sign(privKey)
    send.beat(SpamFilter(3))

    #Custom function to send the last Block and verify it errors at the right place.
    def checkFail() -> None:
        #Send the Send.
        rpc.meros.liveTransaction(send)

        #Handle sync requests.
        while True:
            #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 an invalid Transaction.")
            except Exception:
                raise TestError("Meros sent a keep-alive.")

    #Create and execute a Liver.
    Liver(rpc, vectors["blockchain"], transactions, callbacks={12: checkFail}).live()
Example #16
0
def ChainAdvancementTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r")
    blocks: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    blockchain: Blockchain = Blockchain.fromJSON(
        b"MEROS_DEVELOPER_NETWORK",
        60,
        int("FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16),
        blocks
    )

    #Create and execute a Liver/Syncer.
    Liver(rpc, blockchain).live()
    Syncer(rpc, blockchain).sync()
Example #17
0
def PruneUnaddableTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/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()
def HundredFortyTwoTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/Verification/HundredFortyTwo.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

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

    #Function to verify the Transaction includes unarchived Merit before finalization.
    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",
                                          [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.")

    #Function to verify the Transaction doesn't include unarchived Merit after finalization.
    def verifyArchivedMerit() -> None:
        status: Dict[str, Any] = rpc.call("consensus", "getStatus",
                                          [vectors["transaction"]])
        if status["verifiers"] != [0]:
            raise TestError(
                "Status included verifiers which were never archived.")
        if status["merit"] != 1:
            raise TestError("Status included Merit which was never archived.")

    #Create and execute a Liver.
    Liver(rpc,
          vectors["blockchain"],
          transactions,
          callbacks={
              7: verifyUnarchivedMerit,
              8: verifyArchivedMerit
          }).live()
Example #19
0
def RepeatTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/Repeat.json", "r")
    vectors: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

    def sendBlock() -> None:
        #Send the Block with the MeritRemoval archived again.
        block: Block = Block.fromJSON(vectors[-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:
                #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(
                        "Meros didn't add the same MeritRemoval twice.")
                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, callbacks={3: sendBlock}).live()
Example #20
0
def MultipleTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Consensus/MeritRemoval/Multiple.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #MeritRemovals.
    removals: List[SignedMeritRemoval] = [
        SignedMeritRemoval.fromSignedJSON(vectors["removals"][0]),
        SignedMeritRemoval.fromSignedJSON(vectors["removals"][1])
    ]

    #Send and verify the MeritRemoval.
    def sendMeritRemovals() -> None:
        removalBuf: bytes = rpc.meros.signedElement(removals[0])
        if removalBuf != rpc.meros.live.recv():
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 1, removals[0].holder, True)

        rpc.meros.signedElement(removals[1])
        if removalBuf != rpc.meros.live.recv():
            raise TestError("Meros didn't send us the first Merit Removal.")
        verifyMeritRemoval(rpc, 1, 1, removals[0].holder, True)

    #Verify the holder has 0 Merit and is marked as malicious.
    def verifyFirstMeritRemoval() -> None:
        verifyMeritRemoval(rpc, 0, 0, removals[0].holder, True)

    #Create and execute a Liver to handle the Signed MeritRemovals.
    Liver(
        rpc,
        vectors["blockchain"],
        callbacks={
            1: sendMeritRemovals,
            2: verifyFirstMeritRemoval,
            3: lambda: verifyMeritRemoval(rpc, 0, 0, removals[0].holder, False)
        }
    ).live()

    #Create and execute a Syncer to handle a Signed MeritRemoval.
    Syncer(rpc, vectors["blockchain"]).sync()
    verifyMeritRemoval(rpc, 0, 0, removals[0].holder, False)
Example #21
0
def HundredTwentyTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/HundredTwenty.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #DataDifficulty for the mempool.
    #pylint: disable=no-member
    mempoolDataDiff: SignedDataDifficulty = SignedDataDifficulty.fromSignedJSON(
        vectors["mempoolDataDiff"])
    #DataDifficulty for the Blockchain.
    #pylint: disable=no-member
    blockchainDataDiff: DataDifficulty = DataDifficulty.fromJSON(
        vectors["blockchainDataDiff"])

    def sendDataDifficulty() -> None:
        #Send the Data Difficulty for the mempool.
        rpc.meros.signedElement(mempoolDataDiff)

        #Verify its sent back.
        if rpc.meros.live.recv() != (MessageType.SignedDataDifficulty.toByte()
                                     + mempoolDataDiff.signedSerialize()):
            raise TestError(
                "Meros didn't send us the mempool Data Difficulty.")

    def receiveMeritRemoval() -> None:
        #We should receive a MeritRemoval, which is partial.
        #The unsigned Element should be the Block's DataDifficulty.
        #The signed Element should be the mempool's DataDifficulty.
        if rpc.meros.live.recv() != (
                MessageType.SignedMeritRemoval.toByte() + PartialMeritRemoval(
                    blockchainDataDiff, mempoolDataDiff, 0).signedSerialize()):
            raise TestError("Meros didn't create the partial Merit Removal.")

        #Verify Meros didn't just broadcast it, yet also added it.
        verifyMeritRemoval(rpc, 1, 1, 0, False)

    Liver(rpc,
          vectors["blockchain"],
          callbacks={
              1: sendDataDifficulty,
              2: receiveMeritRemoval
          }).live()
def HundredThirtyFiveTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/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()
Example #23
0
def StateTest(rpc: RPC) -> None:
    #Blocks.
    file: IO[Any] = open("PythonTests/Vectors/Merit/StateBlocks.json", "r")
    blocks: List[Dict[str, Any]] = json.loads(file.read())
    file.close()

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

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

        for miner in state.unlocked:
            if rpc.call("merit", "getMerit", [miner]) != {
                    "unlocked": True,
                    "malicious": False,
                    "merit": state.unlocked[miner]
            }:
                raise TestError("Merit doesn't match.")

    Liver(rpc, blocks, everyBlock=checkState).live()
Example #24
0
def VUnknownTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/Verification/Parsable.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Merit.
    merit: Merit = Merit.fromJSON(vectors["blockchain"])

    #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 attempts to sync our Transaction.
        syncedTX: bool = False

        #Grab the Block.
        block: Block = merit.blockchain.blocks[2]

        #Send the Block.
        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, Verification."
                    )
                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="big")):
                    sketchHash: int = int.from_bytes(msg[37 + (h * 8):45 +
                                                         (h * 8)],
                                                     byteorder="big")
                    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:
                rpc.meros.dataMissing()
                syncedTX = True

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

    #Create and execute a Liver.
    Liver(rpc, vectors["blockchain"], callbacks={1: checkFail}).live()
Example #25
0
def MultipleTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/Multiple.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Blockchain
    blockchain: Blockchain = Blockchain.fromJSON(
        b"MEROS_DEVELOPER_NETWORK", 60,
        int(
            "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            16), vectors["blockchain"])

    #MeritRemovals.
    removal1: SignedMeritRemoval = SignedMeritRemoval.fromJSON(
        vectors["removal1"])
    removal2: SignedMeritRemoval = SignedMeritRemoval.fromJSON(
        vectors["removal2"])

    #Data.
    data: Data = Data.fromJSON(vectors["data"])

    #Create and execute a Liver to cause multiple MeritRemovals.
    def sendElements() -> None:
        #Send the Data.
        if rpc.meros.transaction(data) != rpc.meros.recv():
            raise TestError("Unexpected message sent.")

        #Send the first SignedElement.
        if rpc.meros.signedElement(removal1.se1) != rpc.meros.recv():
            raise TestError("Unexpected message sent.")
        #Send the second.
        rpc.meros.signedElement(removal1.se2)

        #Verify the first MeritRemoval.
        if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() +
                                removal1.signedSerialize()):
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 100, removal1, True)

        #Send the third SignedElement.
        rpc.meros.signedElement(removal2.se2)

        #Meros should treat the first created MeritRemoval as the default MeritRemoval.
        if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() +
                                removal1.signedSerialize()):
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 100, removal1, True)

    Liver(rpc,
          blockchain,
          callbacks={
              1: sendElements,
              2: lambda: verifyMeritRemoval(rpc, 1, 100, removal2, False)
          }).live()

    #Create and execute a Liver to handle multiple MeritRemovals.
    def sendMeritRemovals() -> None:
        #Send and verify the first MeritRemoval.
        msg = rpc.meros.signedElement(removal1)
        if msg != rpc.meros.recv():
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 100, removal1, True)

        #Send the second MeritRemoval.
        rpc.meros.signedElement(removal2)
        #Meros should treat the first created MeritRemoval as the default.
        if msg != rpc.meros.recv():
            raise TestError("Meros didn't send us the Merit Removal.")
        verifyMeritRemoval(rpc, 1, 100, removal1, True)

    Liver(rpc,
          blockchain,
          callbacks={
              1: sendMeritRemovals,
              2: lambda: verifyMeritRemoval(rpc, 1, 100, removal2, False)
          }).live()
Example #26
0
def SameNonceTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/SameNonce.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Blockchain
    blockchain: Blockchain = Blockchain.fromJSON(
        b"MEROS_DEVELOPER_NETWORK", 60,
        int(
            "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            16), vectors["blockchain"])

    #MeritRemoval.
    removal: SignedMeritRemoval = SignedMeritRemoval.fromJSON(
        vectors["removal"])
    #Consensus.
    consensus: Consensus = Consensus(
        bytes.fromhex(
            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        ),
        bytes.fromhex(
            "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
        ))
    consensus.add(removal)

    #Data.
    data: Data = Data.fromJSON(vectors["data"])

    #Create and execute a Liver to cause a SameNonce MeritRemoval.
    def sendElements() -> None:
        #Send the Data/SignedVerifications.
        if rpc.meros.transaction(data) != rpc.meros.recv():
            raise TestError("Unexpected message sent.")

        if rpc.meros.signedElement(removal.se1) != rpc.meros.recv():
            raise TestError("Unexpected message sent.")
        rpc.meros.signedElement(removal.se2)

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

    Liver(rpc,
          blockchain,
          consensus,
          callbacks={
              1: sendElements,
              2: lambda: verifyMeritRemoval(rpc, 1, 100, removal, False)
          }).live()

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

    Liver(rpc,
          blockchain,
          consensus,
          callbacks={
              1: sendMeritRemoval,
              2: lambda: verifyMeritRemoval(rpc, 1, 100, removal, False)
          }).live()

    #Create and execute a Syncer to handle a SameNonce MeritRemoval.
    Syncer(rpc, blockchain, consensus).sync()
    verifyMeritRemoval(rpc, 1, 100, removal, False)
Example #27
0
def VerifyCompetingTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/VerifyCompeting.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    keys: Dict[bytes, int] = {
        bytes.fromhex(vectors["blockchain"][0]["header"]["miner"]): 0
    }
    nicks: List[bytes] = [
        bytes.fromhex(vectors["blockchain"][0]["header"]["miner"])
    ]

    #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(
        keys, 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.transaction(data) != rpc.meros.recv():
                raise TestError("Meros didn't send us the Data.")

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

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

        #Trigger the MeritRemoval.
        rpc.meros.signedElement(removal.se2)
        if rpc.meros.recv() != (MessageType.SignedMeritRemoval.toByte() +
                                removal.signedSerialize(nicks)):
            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.transaction(data) != rpc.meros.recv():
                raise TestError("Meros didn't send us the Data.")

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

        #Send and verify the MeritRemoval.
        if rpc.meros.signedElement(removal) != rpc.meros.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)
Example #28
0
    def testBlockchain(i: int) -> None:
        #First MeritRemoval.
        mr: SignedMeritRemoval = SignedMeritRemoval.fromSignedJSON(
            vectors["removals"][i])

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

        def sendRepeatMeritRemoval() -> None:
            #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 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["blockchains"][i],
              transactions,
              callbacks={
                  1: sendMeritRemoval,
                  2: sendRepeatMeritRemoval
              }).live()
Example #29
0
def PendingActionsTest(rpc: RPC) -> None:
    file: IO[Any] = open(
        "PythonTests/Vectors/Consensus/MeritRemoval/PendingActions.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Blockchain.
    blockchain: Blockchain = Blockchain.fromJSON(
        b"MEROS_DEVELOPER_NETWORK", 60,
        int(
            "FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            16), vectors["blockchain"])

    #SignedVerifications.
    verifs: List[SignedVerification] = []
    for verif in vectors["verifications"]:
        verifs.append(SignedVerification.fromJSON(verif))
    #Removal.
    removal: SignedMeritRemoval = SignedMeritRemoval.fromJSON(
        vectors["removal"])

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

    #Send every Data/Verification.
    def sendDatasAndVerifications() -> None:
        #Send the Datas.
        for data in datas:
            if rpc.meros.transaction(data) != rpc.meros.recv():
                raise TestError("Unexpected message sent.")

        #Send the Verifications.
        for verif in verifs:
            if rpc.meros.signedElement(verif) != rpc.meros.recv():
                raise TestError("Unexpected message sent.")

        #Verify every Data has 100 Merit.
        for data in datas:
            if rpc.call("consensus", "getStatus",
                        [data.hash.hex()])["merit"] != 100:
                raise TestError(
                    "Meros didn't verify Transactions with received Verifications."
                )

    #Cause a MeritRemoval.
    def causeMeritRemoval() -> None:
        #Send every Data/;Verification.
        sendDatasAndVerifications()

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

        #Verify every Data has 0 Merit.
        for data in datas:
            if rpc.call("consensus", "getStatus",
                        [data.hash.hex()])["merit"] != 0:
                raise TestError(
                    "Meros didn't revert pending actions of a malicious MeritHolder."
                )

    #Send a MeritRemoval.
    def sendMeritRemoval() -> None:
        #Send every Data/;Verification.
        sendDatasAndVerifications()

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

        #Verify every Data has 0 Merit.
        for data in datas:
            if rpc.call("consensus", "getStatus",
                        [data.hash.hex()])["merit"] != 0:
                raise TestError(
                    "Meros didn't revert pending actions of a malicious MeritHolder."
                )

    #Check the Data's finalized with the proper amount of Merit and update the MeritRemoval.
    def check() -> None:
        #Verify the Datas have the Merit they should.
        for data in datas:
            if rpc.call("consensus", "getStatus",
                        [data.hash.hex()])["merit"] != 0:
                raise TestError(
                    "Meros didn't finalize with the reverted pending actions of a malicious MeritHolder."
                )

        #Update the MeritRemoval's nonce.
        removal.nonce = 6

        #Verify the MeritRemoval is now accessible with a nonce of 6.
        verifyMeritRemoval(rpc, 7, 0, removal, False)

    #Create and execute a Liver to cause a MeritRemoval.
    Liver(rpc, blockchain, callbacks={1: causeMeritRemoval, 7: check}).live()

    #Reset the MeritRemoval nonce.
    removal.nonce = 0

    #Create and execute a Liver to handle a MeritRemoval.
    Liver(rpc, blockchain, callbacks={1: sendMeritRemoval, 7: check}).live()
def CompetingFinalizedTest(
    rpc: RPC
) -> None:
    file: IO[Any] = open("PythonTests/Vectors/Transactions/CompetingFinalized.json", "r")
    vectors: Dict[str, Any] = json.loads(file.read())
    file.close()

    #Merit.
    merit: Merit = Merit.fromJSON(vectors["blockchain"])
    #Transactions.
    transactions: Transactions = Transactions.fromJSON(vectors["transactions"])

    #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

        #Grab the Block.
        block: Block = merit.blockchain.blocks[-1]

        #Send the Block.
        rpc.meros.blockHeader(block.header)

        #Handle sync requests.
        reqHash: bytes = bytes()
        while True:
            try:
                msg: bytes = rpc.meros.recv()
            except TestError:
                if syncedTX:
                    raise SuccessError("Node disconnected us after we sent an invalid Transaction.")
                raise TestError("Node errored before syncing our Transaction.")

            if MessageType(msg[0]) == MessageType.Syncing:
                rpc.meros.syncingAcknowledged()

            elif 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(merit.state.nicks, 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="big")):
                    sketchHash: int = int.from_bytes(msg[37 + (h * 8) : 45 + (h * 8)], byteorder="big")
                    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.transaction(transactions.txs[reqHash])
                syncedTX = True

            elif MessageType(msg[0]) == MessageType.SyncingOver:
                pass

            elif MessageType(msg[0]) == MessageType.BlockHeader:
                #Raise a TestError if the Block was added.
                raise TestError("Meros synced a Transaction which competed with a finalized Transaction.")

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

    #Create and execute a Liver.
    Liver(rpc, vectors["blockchain"], transactions, callbacks={7: checkFail}).live()