Пример #1
0
    def getMessageFromDb(self, transId, retry=True, silentErrors=False):
        for _ in range(2):
            cmd = "%s %s" % (Utils.MongoPath, self.mongoEndpointArgs)
            subcommand = 'db.Messages.findOne( { "transaction_id": "%s" } )' % (
                transId)
            if Utils.Debug:
                Utils.Print("cmd: echo '%s' | %s" % (subcommand, cmd))
            try:
                trans = Node.runMongoCmdReturnJson(cmd.split(), subcommand)
                if trans is not None:
                    return trans
            except subprocess.CalledProcessError as ex:
                if not silentErrors:
                    msg = ex.output.decode("utf-8")
                    Utils.Print(
                        "ERROR: Exception during get db node get message. %s" %
                        (msg))
                return None
            if not retry:
                break
            if self.mongoSyncTime is not None:
                if Utils.Debug:
                    Utils.Print("cmd: sleep %d seconds" % (self.mongoSyncTime))
                time.sleep(self.mongoSyncTime)

        return None
Пример #2
0
    def createAccount(self,
                      account,
                      creatorAccount,
                      stakedDeposit=1000,
                      waitForTransBlock=False):
        cmd = "%s %s create account -j %s %s %s %s" % (
            Utils.EosClientPath, self.endpointArgs, creatorAccount.name,
            account.name, account.ownerPublicKey, account.activePublicKey)

        if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
        trans = None
        try:
            trans = Node.runCmdReturnJson(cmd)
            transId = Node.getTransId(trans)
        except subprocess.CalledProcessError as ex:
            msg = ex.output.decode("utf-8")
            Utils.Print("ERROR: Exception during account creation. %s" % (msg))
            return None

        if stakedDeposit > 0:
            self.waitForTransIdOnNode(
                transId
            )  # seems like account creation needs to be finlized before transfer can happen
            trans = self.transferFunds(
                creatorAccount, account,
                "%0.04f %s" % (stakedDeposit / 10000, CORE_SYMBOL), "init")
            transId = Node.getTransId(trans)

        if waitForTransBlock and not self.waitForTransIdOnNode(transId):
            return None

        return trans
Пример #3
0
    def isTransInBlock(self, transId, blockId):
        """Check if transId is within block identified by blockId"""
        assert (transId)
        assert (isinstance(transId, str))
        assert (blockId)
        assert (isinstance(blockId, str))

        block = self.getBlock(blockId)
        transactions = None
        try:
            transactions = block["transactions"]
        except (AssertionError, TypeError, KeyError) as _:
            Utils.Print("Failed to parse block. %s" % (block))
            raise

        if transactions is not None:
            for trans in transactions:
                assert (trans)
                try:
                    myTransId = trans["trx"]["id"]
                    if transId == myTransId:
                        return True
                except (TypeError, KeyError) as _:
                    Utils.Print("Failed to parse block transactions. %s" %
                                (trans))

        return False
Пример #4
0
    def getBlockIdByTransId(self, transId):
        """Given a transaction Id (string), will return block id (string) containing the transaction"""
        assert (transId)
        assert (isinstance(transId, str))
        trans = self.getTransaction(transId)
        assert (trans)

        refBlockNum = None
        try:
            refBlockNum = trans["trx"]["trx"]["ref_block_num"]
            refBlockNum = int(refBlockNum) + 1
        except (TypeError, ValueError, KeyError) as _:
            Utils.Print("transaction parsing failed. Transaction: %s" %
                        (trans))
            raise

        headBlockNum = self.getIrreversibleBlockNum()
        assert (headBlockNum)
        try:
            headBlockNum = int(headBlockNum)
        except (ValueError) as _:
            Utils.Print("Info parsing failed. %s" % (headBlockNum))

        for blockNum in range(refBlockNum, headBlockNum + 1):
            if self.isTransInBlock(str(transId), str(blockNum)):
                return str(blockNum)

        return None
Пример #5
0
    def kill(self, killSignal):
        if Utils.Debug: Utils.Print("Killing node: %s" % (self.cmd))
        assert (self.pid is not None)
        try:
            os.kill(self.pid, killSignal)
        except OSError as ex:
            Utils.Print("ERROR: Failed to kill node (%d)." % (self.cmd), ex)
            return False

        # wait for kill validation
        def myFunc():
            try:
                os.kill(self.pid, 0)  # check if process with pid is running
            except OSError as _:
                return True
            return False

        if not Utils.waitForBool(myFunc):
            Utils.Print("ERROR: Failed to kill node (%s)." % (self.cmd))
            return False

        # mark node as killed
        self.pid = None
        self.killed = True
        return True
Пример #6
0
    def relaunch(self, nodeId, chainArg):

        running = True
        try:
            os.kill(self.pid, 0)  # check if process with pid is running
        except OSError as _:
            running = False

        if running:
            Utils.Print(
                "WARNING: A process with pid (%d) is already running." %
                (self.pid))
        else:
            if Utils.Debug:
                Utils.Print("Launching node process, Id: %d" % (nodeId))
            dataDir = "var/lib/node_%02d" % (nodeId)
            dt = datetime.datetime.now()
            dateStr = "%d_%02d_%02d_%02d_%02d_%02d" % (
                dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
            stdoutFile = "%s/stdout.%s.txt" % (dataDir, dateStr)
            stderrFile = "%s/stderr.%s.txt" % (dataDir, dateStr)
            with open(stdoutFile, 'w') as sout, open(stderrFile, 'w') as serr:
                cmd = self.cmd + ("" if chainArg is None else (" " + chainArg))
                Utils.Print("cmd: %s" % (cmd))
                popen = subprocess.Popen(cmd.split(), stdout=sout, stderr=serr)
                self.pid = popen.pid

        self.killed = False
        return True
Пример #7
0
    def parseProducerKeys(configFile, nodeName):
        """Parse node config file for producer keys. Returns dictionary. (Keys: account name; Values: dictionary objects (Keys: ["name", "node", "private","public"]; Values: account name, node id returned by nodeNameToId(nodeName), private key(string)and public key(string)))."""

        configStr = None
        with open(configFile, 'r') as f:
            configStr = f.read()

        pattern = r"^\s*private-key\s*=\W+(\w+)\W+(\w+)\W+$"
        m = re.search(pattern, configStr, re.MULTILINE)
        if m is None:
            if Utils.Debug: Utils.Print("Failed to find producer keys")
            return None

        pubKey = m.group(1)
        privateKey = m.group(2)

        pattern = r"^\s*producer-name\s*=\W*(\w+)\W*$"
        matches = re.findall(pattern, configStr, re.MULTILINE)
        if matches is None:
            if Utils.Debug: Utils.Print("Failed to find producers.")
            return None

        producerKeys = {}
        for m in matches:
            if Utils.Debug: Utils.Print("Found producer : %s" % (m))
            nodeId = Cluster.nodeNameToId(nodeName)
            keys = {
                "name": m,
                "node": nodeId,
                "private": privateKey,
                "public": pubKey
            }
            producerKeys[m] = keys

        return producerKeys
Пример #8
0
    def verifyAccount(self, account):
        if not self.enableMongo:
            ret = self.getEosAccount(account.name)
            if ret is not None:
                account_name = ret["account_name"]
                if account_name is None:
                    Utils.Print("ERROR: Failed to verify account creation.",
                                account.name)
                    return None
                return ret
        else:
            for _ in range(2):
                ret = self.getEosAccountFromDb(account.name)
                if ret is not None:
                    account_name = ret["name"]
                    if account_name is None:
                        Utils.Print(
                            "ERROR: Failed to verify account creation.",
                            account.name)
                        return None
                    return ret
                if self.mongoSyncTime is not None:
                    if Utils.Debug:
                        Utils.Print("cmd: sleep %d seconds" %
                                    (self.mongoSyncTime))
                    time.sleep(self.mongoSyncTime)

        return None
Пример #9
0
    def initializeNodesFromJson(self, nodesJsonStr):
        nodesObj = json.loads(nodesJsonStr)
        if nodesObj is None:
            Utils.Print("ERROR: Invalid Json string.")
            return False

        if "keys" in nodesObj:
            keysMap = nodesObj["keys"]

            if "defproduceraPrivateKey" in keysMap:
                defproduceraPrivateKey = keysMap["defproduceraPrivateKey"]
                self.defproduceraAccount.ownerPrivateKey = defproduceraPrivateKey

            if "defproducerbPrivateKey" in keysMap:
                defproducerbPrivateKey = keysMap["defproducerbPrivateKey"]
                self.defproducerbAccount.ownerPrivateKey = defproducerbPrivateKey

        nArr = nodesObj["nodes"]
        nodes = []
        for n in nArr:
            port = n["port"]
            host = n["host"]
            node = Node(host, port)
            node.setWalletEndpointArgs(self.walletEndpointArgs)
            if Utils.Debug: Utils.Print("Node:", node)

            node.checkPulse()
            nodes.append(node)

        self.nodes = nodes
        return True
Пример #10
0
    def transferFunds(self,
                      source,
                      destination,
                      amount,
                      memo="memo",
                      force=False):
        assert isinstance(amount, str)

        cmd = "%s %s -v transfer -j %s %s" % (Utils.EosClientPath,
                                              self.endpointArgs, source.name,
                                              destination.name)
        cmdArr = cmd.split()
        cmdArr.append(amount)
        cmdArr.append(memo)
        if force:
            cmdArr.append("-f")
        s = " ".join(cmdArr)
        if Utils.Debug: Utils.Print("cmd: %s" % (s))
        trans = None
        try:
            trans = Node.__runCmdArrReturnJson(cmdArr)
            return trans
        except subprocess.CalledProcessError as ex:
            msg = ex.output.decode("utf-8")
            Utils.Print("ERROR: Exception during funds transfer. %s" % (msg))
            return None
Пример #11
0
    def createAccounts(self,
                       creator,
                       waitForTransBlock=True,
                       stakedDeposit=1000):
        if self.accounts is None:
            return True

        transId = None
        for account in self.accounts:
            if Utils.Debug: Utils.Print("Create account %s." % (account.name))
            trans = self.createAccountAndVerify(account, creator,
                                                stakedDeposit)
            if trans is None:
                Utils.Print("ERROR: Failed to create account %s." %
                            (account.name))
                return False
            if Utils.Debug: Utils.Print("Account %s created." % (account.name))
            transId = Node.getTransId(trans)

        if waitForTransBlock and transId is not None:
            node = self.nodes[0]
            if Utils.Debug:
                Utils.Print("Wait for transaction id %s on server port %d." %
                            (transId, node.port))
            if node.waitForTransIdOnNode(transId) is False:
                Utils.Print(
                    "ERROR: Failed waiting for transaction id %s on server port %d."
                    % (transId, node.port))
                return False

        return True
Пример #12
0
    def lockWallet(self, wallet):
        cmd = "%s %s wallet lock --name %s" % (Utils.EosClientPath,
                                               self.endpointArgs, wallet.name)
        if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
        if 0 != subprocess.call(cmd.split(), stdout=Utils.FNull):
            Utils.Print("ERROR: Failed to lock wallet %s." % (wallet.name))
            return False

        return True
Пример #13
0
    def lockAllWallets(self):
        cmd = "%s %s wallet lock_all" % (Utils.EosClientPath,
                                         self.endpointArgs)
        if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
        if 0 != subprocess.call(cmd.split(), stdout=Utils.FNull):
            Utils.Print("ERROR: Failed to lock all wallets.")
            return False

        return True
Пример #14
0
 def dumpErrorDetailImpl(fileName):
     Utils.Print(
         "================================================================="
     )
     Utils.Print("Contents of %s:" % (fileName))
     if os.path.exists(fileName):
         with open(fileName, "r") as f:
             shutil.copyfileobj(f, sys.stdout)
     else:
         Utils.Print("File %s not found." % (fileName))
Пример #15
0
 def isMongodDbRunning(self):
     cmd = "%s %s" % (Utils.MongoPath, self.mongoEndpointArgs)
     subcommand = "db.version()"
     if Utils.Debug: Utils.Print("echo %s | %s" % (subcommand, cmd))
     ret, outs, errs = Node.stdinAndCheckOutput(cmd.split(), subcommand)
     if ret is not 0:
         Utils.Print("ERROR: Failed to check database version: %s" %
                     (Node.byteArrToStr(errs)))
         return False
     if Utils.Debug: Utils.Print("MongoDb response: %s" % (outs))
     return True
Пример #16
0
 def dumpErrorDetails(self):
     Utils.Print(
         "================================================================="
     )
     if self.__walletPid is not None:
         Utils.Print("Contents of %s:" % (WalletMgr.__walletLogFile))
         Utils.Print(
             "================================================================="
         )
         with open(WalletMgr.__walletLogFile, "r") as f:
             shutil.copyfileobj(f, sys.stdout)
Пример #17
0
 def getInfo(self, silentErrors=False):
     cmd = "%s %s get info" % (Utils.EosClientPath, self.endpointArgs)
     if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
     try:
         trans = Node.runCmdReturnJson(cmd)
         return trans
     except subprocess.CalledProcessError as ex:
         if not silentErrors:
             msg = ex.output.decode("utf-8")
             Utils.Print("ERROR: Exception during get info. %s" % (msg))
         return None
Пример #18
0
 def getTable(self, contract, scope, table):
     cmd = "%s %s get table %s %s %s" % (
         Utils.EosClientPath, self.endpointArgs, contract, scope, table)
     if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
     try:
         trans = Node.runCmdReturnJson(cmd)
         return trans
     except subprocess.CalledProcessError as ex:
         msg = ex.output.decode("utf-8")
         Utils.Print("ERROR: Exception during table retrieval. %s" % (msg))
         return None
Пример #19
0
 def getTableRow(self, contract, scope, table, idx):
     if idx < 0:
         Utils.Print("ERROR: Table index cannot be negative. idx: %d" %
                     (idx))
         return None
     rows = self.getTableRows(contract, scope, table)
     if rows is None or idx >= len(rows):
         Utils.Print("ERROR: Retrieved table does not contain row %d" % idx)
         return None
     row = rows[idx]
     return row
Пример #20
0
 def getEosAccount(self, name):
     assert (isinstance(name, str))
     cmd = "%s %s get account -j %s" % (Utils.EosClientPath,
                                        self.endpointArgs, name)
     if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
     try:
         trans = Node.runCmdReturnJson(cmd)
         return trans
     except subprocess.CalledProcessError as ex:
         msg = ex.output.decode("utf-8")
         Utils.Print("ERROR: Exception during get account. %s" % (msg))
         return None
Пример #21
0
 def getServants(self, name):
     cmd = "%s %s get servants %s" % (Utils.EosClientPath,
                                      self.endpointArgs, name)
     if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
     try:
         trans = Node.runCmdReturnJson(cmd)
         return trans
     except subprocess.CalledProcessError as ex:
         msg = ex.output.decode("utf-8")
         Utils.Print("ERROR: Exception during servants retrieval. %s" %
                     (msg))
         return None
Пример #22
0
 def getCurrencyStats(self, contract, symbol=""):
     cmd = "%s %s get currency0000 stats %s %s" % (
         Utils.EosClientPath, self.endpointArgs, contract, symbol)
     if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
     try:
         trans = Node.runCmdReturnJson(cmd)
         return trans
     except subprocess.CalledProcessError as ex:
         msg = ex.output.decode("utf-8")
         Utils.Print("ERROR: Exception during get currency0000 stats. %s" %
                     (msg))
         return None
Пример #23
0
 def getEosAccountFromDb(self, name):
     cmd = "%s %s" % (Utils.MongoPath, self.mongoEndpointArgs)
     subcommand = 'db.Accounts.findOne({"name" : "%s"})' % (name)
     if Utils.Debug: Utils.Print("cmd: echo '%s' | %s" % (subcommand, cmd))
     try:
         trans = Node.runMongoCmdReturnJson(cmd.split(), subcommand)
         return trans
     except subprocess.CalledProcessError as ex:
         msg = ex.output.decode("utf-8")
         Utils.Print("ERROR: Exception during get account from db. %s" %
                     (msg))
         return None
Пример #24
0
 def getBlockFromDb(self, idx):
     cmd = "%s %s" % (Utils.MongoPath, self.mongoEndpointArgs)
     subcommand = "db.Blocks.find().sort({\"_id\":%d}).limit(1).pretty()" % (
         idx)
     if Utils.Debug:
         Utils.Print("cmd: echo \"%s\" | %s" % (subcommand, cmd))
     try:
         trans = Node.runMongoCmdReturnJson(cmd.split(), subcommand)
         return trans
     except subprocess.CalledProcessError as ex:
         msg = ex.output.decode("utf-8")
         Utils.Print("ERROR: Exception during get db block. %s" % (msg))
         return None
Пример #25
0
    def cleanup(self):
        for f in glob.glob("var/lib/node_*"):
            shutil.rmtree(f)
        for f in glob.glob("etc/eosio/node_*"):
            shutil.rmtree(f)

        if self.enableMongo:
            cmd = "%s %s" % (Utils.MongoPath, self.mongoEndpointArgs)
            subcommand = "db.dropDatabase()"
            if Utils.Debug: Utils.Print("echo %s | %s" % (subcommand, cmd))
            ret, _, errs = Node.stdinAndCheckOutput(cmd.split(), subcommand)
            if ret is not 0:
                Utils.Print("ERROR: Failed to drop database: %s" %
                            (Node.byteArrToStr(errs)))
Пример #26
0
    def unlockWallet(self, wallet):
        cmd = "%s %s wallet unlock --name %s" % (
            Utils.EosClientPath, self.endpointArgs, wallet.name)
        if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
        popen = subprocess.Popen(cmd.split(),
                                 stdout=Utils.FNull,
                                 stdin=subprocess.PIPE)
        _, errs = popen.communicate(input=wallet.password.encode("utf-8"))
        if 0 != popen.wait():
            Utils.Print("ERROR: Failed to unlock wallet %s: %s" %
                        (wallet.name, errs.decode("utf-8")))
            return False

        return True
Пример #27
0
    def getKeys(self):
        keys = []

        p = re.compile(r'\n\s+\"(\w+)\"\n', re.MULTILINE)
        cmd = "%s %s wallet keys" % (Utils.EosClientPath, self.endpointArgs)
        if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
        retStr = subprocess.check_output(cmd.split()).decode("utf-8")
        # Utils.Print("retStr: %s" % (retStr))
        m = p.findall(retStr)
        if m is None:
            Utils.Print("ERROR: wallet keys parser failure")
            return None
        keys = m

        return keys
Пример #28
0
    def validateSpreadFunds(self, expectedTotal):
        for node in self.nodes:
            if not node.killed:
                if Utils.Debug:
                    Utils.Print("Validate funds on %s server port %d." %
                                (Utils.EosServerName, node.port))
                if node.validateSpreadFundsOnNode(self.defproduceraAccount,
                                                  self.accounts,
                                                  expectedTotal) is False:
                    Utils.Print(
                        "ERROR: Failed to validate funds on eos node port: %d"
                        % (node.port))
                    return False

        return True
Пример #29
0
    def discoverLocalNodes(self, totalNodes, timeout=0):
        nodes = []

        pgrepOpts = "-fl"
        # pylint: disable=deprecated-method
        if platform.linux_distribution()[0] in [
                "Ubuntu", "LinuxMint", "Fedora", "CentOS Linux", "arch"
        ]:
            pgrepOpts = "-a"

        cmd = "pgrep %s %s" % (pgrepOpts, Utils.EosServerName)

        def myFunc():
            psOut = None
            try:
                if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
                psOut = subprocess.check_output(cmd.split()).decode("utf-8")
                return psOut
            except subprocess.CalledProcessError as _:
                pass
            return None

        psOut = Utils.waitForObj(myFunc, timeout)
        if psOut is None:
            Utils.Print("ERROR: No nodes discovered.")
            return nodes

        if Utils.Debug: Utils.Print("pgrep output: \"%s\"" % psOut)
        for i in range(0, totalNodes):
            pattern = r"[\n]?(\d+) (.* --data-dir var/lib/node_%02d)" % (i)
            m = re.search(pattern, psOut, re.MULTILINE)
            if m is None:
                Utils.Print("ERROR: Failed to find %s pid. Pattern %s" %
                            (Utils.EosServerName, pattern))
                break
            instance = Node(self.host,
                            self.port + i,
                            pid=int(m.group(1)),
                            cmd=m.group(2),
                            enableMongo=self.enableMongo,
                            mongoHost=self.mongoHost,
                            mongoPort=self.mongoPort,
                            mongoDb=self.mongoDb)
            instance.setWalletEndpointArgs(self.walletEndpointArgs)
            if Utils.Debug: Utils.Print("Node>", instance)
            nodes.append(instance)

        return nodes
Пример #30
0
    def initializeNodes(self,
                        defproduceraPrvtKey=None,
                        defproducerbPrvtKey=None,
                        onlyBios=False):
        port = Cluster.__BiosPort if onlyBios else self.port
        host = Cluster.__BiosHost if onlyBios else self.host
        node = Node(host,
                    port,
                    enableMongo=self.enableMongo,
                    mongoHost=self.mongoHost,
                    mongoPort=self.mongoPort,
                    mongoDb=self.mongoDb)
        node.setWalletEndpointArgs(self.walletEndpointArgs)
        if Utils.Debug: Utils.Print("Node:", node)

        node.checkPulse()
        self.nodes = [node]

        if defproduceraPrvtKey is not None:
            self.defproduceraAccount.ownerPrivateKey = defproduceraPrvtKey
            self.defproduceraAccount.activePrivateKey = defproduceraPrvtKey

        if defproducerbPrvtKey is not None:
            self.defproducerbAccount.ownerPrivateKey = defproducerbPrvtKey
            self.defproducerbAccount.activePrivateKey = defproducerbPrvtKey

        return True