Ejemplo n.º 1
0
 def deploy_and_propose(self, deploy_key, contract, phlo_price, phlo_limit):
     with grpc.insecure_channel(self.grpc_host) as channel:
         client = RClient(channel)
         try:
             return client.propose()
         except RClientException as e:
             logging.info(
                 "The node {} doesn't have new deploy. Going to deploy now".
                 format(self.host_name))
             error_message = e.args[0]
             if "NoNewDeploys" in error_message:
                 deploy_id = client.deploy_with_vabn_filled(
                     deploy_key, contract, phlo_price, phlo_limit,
                     int(time.time() * 1000))
                 logging.info("Succefully deploy {}".format(deploy_id))
                 return client.propose()
             else:
                 raise e
Ejemplo n.º 2
0
import grpc
import logging
import sys
from rchain.crypto import PrivateKey
from rchain.client import RClient
import time
import subprocess

root = logging.getLogger()
root.setLevel(logging.DEBUG)

config_path = str(sys.argv[3])

with grpc.insecure_channel('localhost:40401') as channel:
    client = RClient(channel)
    with open(sys.argv[2]) as file:
        data = file.read()
        start_time = time.time()
        client.deploy_with_vabn_filled(PrivateKey.from_hex(sys.argv[1]), data,
                                       1, 1000000000)
        dur = time.time() - start_time
        subprocess.run([
            'python3', 'reportInfluxDBMetric.py', 'pyrchain.deploytime',
            str(dur), config_path
        ])
Ejemplo n.º 3
0
class rgovAPI:
    def __init__(self, net_name: str):
        if net_name in NETWORKS:
            #print('Using ', net_name)
            network = NETWORKS[net_name]
            self.client = RClient(network['observerBase']['host'],
                                  network['observerBase']['port'])
            self.network = network
            self.net_name = net_name
            self.keyVault = self.import_shared_private_keys()
        else:
            reason = 'Network ' + net_name + ' NOT Found as an option'
            raise Exception(reason)

    def close(self) -> None:
        self.client.close()

    def __enter__(self) -> 'rgovAPI':
        return self

    def __exit__(self, exc_type: Optional[Type[BaseException]],
                 exc_val: Optional[BaseException],
                 exc_tb: Optional[TracebackType]) -> None:
        self.close()

    def import_shared_private_keys(self) -> Mapping[str, str]:
        search = PRIVATE_KEYS + "pk.*"
        keys = {}
        for fname in glob.glob(search):
            name = fname.split("/")[-1]
            names = name.split(".")
            if len(names) == 2:
                file = open(fname)
                pk = file.read()
                file.close()
                keys[names[1]] = pk
        return keys

    def get_private_key(self, name: str) -> PrivateKey:
        if name in self.keyVault:
            return PrivateKey.from_hex(self.keyVault[name])
        reason = 'No key found in vault for ' + name
        raise Exception(reason)

    def getDeploy(self, deployId: str, tries: int = 10):
        print("getBlock ", self.network['validatorBase']['host'])
        url = self.network['validatorBase']['url'] + self.network[
            'validatorBase']['host']
        if self.network['validatorBase']['port'] > 0:
            url += ':' + str(self.network['validatorBase']['port'])

        url += '/api/deploy/' + deployId
        print("Get Deploy ", url)
        while tries > 0:
            result = requests.get(url)
            print("Got ", result)
            if result.status_code == 200:
                break
            tries = tries - 1
            time.sleep(1.0)
            print("Try again ", tries)
        print(result.json())
        return result.json()

    def getBlock(self, block_hash: str):
        print("getBlock ", self.network['validatorBase']['host'])
        url = self.network['validatorBase']['url'] + self.network[
            'validatorBase']['host']
        if self.network['validatorBase']['port'] > 0:
            url += ':' + str(self.network['validatorBase']['port'])

        url += '/api/block/' + block_hash
        print("Get Block ", url)
        result = requests.get(url)
        return result.json()

    def getDeployData(self, block_hash: str):
        #print("getDeployData ", self.network['validatorBase']['host'])
        url = self.network['validatorBase']['url'] + self.network[
            'validatorBase']['host']
        if self.network['validatorBase']['port'] > 0:
            url += ':' + str(self.network['validatorBase']['port'])

        url += '/api/data-at-name'
        data = '{"depth": 1, "name": {"UnforgDeploy": {"data": "' + block_hash + '"}}}'
        #print("Post ", url, data)
        headers = {'Content-type': 'text/plain', 'Accept': '*/*'}
        result = requests.post(url, data, headers=headers)
        return result.json()

    def propose(self) -> None:
        if self.network['adminBase']['url']:
            url = self.network['adminBase']['url'] + self.network['adminBase'][
                'host']
            if self.network['adminBase']['port'] > 0:
                url += ':' + str(self.network['adminBase']['port'])

            url += '/api/propose'
            time.sleep(0.5)
            result = requests.post(url)
            return result.json()

    def checkBalance(self, rev_addr: str, block_hash: str = '') -> int:
        contract = render_contract_template(
            CHECK_BALANCE_RHO_TPL,
            {
                'addr': rev_addr,
                'myBalance': "mybal"
            },
        )
        result = self.client.exploratory_deploy(contract, block_hash)
        return result[0].exprs[0].e_list_body.ps[2].exprs[0].g_int

    def transfer(self, from_addr: str, to_addr: str, amount: int,
                 key: PrivateKey) -> str:
        contract = render_contract_template(
            TRANSFER_RHO_TPL,
            {
                'from': from_addr,
                'to': to_addr,
                'amount': amount
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        #print("transfer ", deployId)
        self.propose()
        result = self.client.get_data_at_deploy_id(deployId, 5)
        result = result.blockInfo[0].postBlockData[0].exprs[0].e_tuple_body
        status = result.ps[0].exprs[0].g_bool
        msg = result.ps[1].exprs[0].g_string
        return [status, msg]

    def newInbox(self, key: PrivateKey) -> str:
        fname = MASTERURI + self.net_name + '.json'
        file = open(fname)
        masterstr = file.read()
        file.close()
        start = masterstr.find('rho:id:')
        end = masterstr.find('`', start)
        if start < 0 or end < 0:
            return [False, "masterURI file corrupt"]

        masterURI = masterstr[start:end]
        contract = render_contract_template(
            NEWINBOX_RHO_TPL,
            {'masterURI': masterURI},  #, 'inbox': 'inboxURI'},
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("newInbox ", deployId)
        result = self.propose()
        result = self.client.get_data_at_deploy_id(deployId, 5)
        if result is None:
            return [False, "no deploy data"]
        if len(result.blockInfo) == 0:
            return [False, "no deploy data"]
        if (len(result.blockInfo[0].postBlockData)) == 0:
            return [False, "no deploy data"]

        status = [False, "URI not found"]
        if (len(result.blockInfo[0].postBlockData[0].exprs) > 0):
            if (result.blockInfo[0].postBlockData[0].exprs[0].HasField(
                    'e_list_body')):
                for data in result.blockInfo[0].postBlockData[0].exprs[
                        0].e_list_body.ps:
                    #if data.exprs[0].HasField("g_string"):
                    #    print("Found (mystuff)", data.exprs[0].g_string)
                    if data.exprs[0].HasField("e_map_body"):
                        for kvs in data.exprs[0].e_map_body.kvs:
                            if kvs.key.exprs[0].g_string == "inbox":
                                if kvs.value.exprs[0].HasField("e_map_body"):
                                    for inbox in kvs.value.exprs[
                                            0].e_map_body.kvs:
                                        if inbox.key.exprs[
                                                0].g_string == "URI":
                                            status = [
                                                True,
                                                inbox.value.exprs[0].g_uri
                                            ]

        return status

    def newIssue(self, key: PrivateKey, inbox: str, issue: str,
                 options: list) -> str:
        if len(options) < 2:
            return [False, "newIssue: options must have at least 2 choices"]

        choices = '"' + '", "'.join(options) + '"'
        contract = render_contract_template(
            NEWISSUE_RHO_TPL,
            {
                'inbox': inbox,
                'issue': issue,
                'choices': choices
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("newIssue ", deployId)
        self.propose()
        result = self.client.get_data_at_deploy_id(deployId, 5)
        if result is None:
            return [False, "no deploy data"]
        msg = "No status messages found"
        status = False
        if (len(result.blockInfo[0].postBlockData) > 0):
            for post in result.blockInfo[0].postBlockData:
                if post.exprs[0].HasField("g_string"):
                    if status:
                        msg = msg + " " + post.exprs[0].g_string
                    else:
                        msg = post.exprs[0].g_string
                    status = True
        return [status, msg, result]

    def addVoterToIssue(self, key: PrivateKey, locker: str, voter: str,
                        issue: str) -> str:
        contract = render_contract_template(
            ADDVOTER_RHO_TPL,
            {
                'inbox': locker,
                'voterURI': voter,
                'issue': issue
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("addVoterToIssue ", deployId)
        self.propose()
        result = self.client.get_data_at_deploy_id(deployId)
        if result is None:
            return [False, "no deploy data"]
        return [True, result]

    def peekInbox(self, key: PrivateKey, inbox: str, type: str, subtype: str):
        contract = render_contract_template(
            PEEKINBOX_RHO_TPL,
            {
                'inbox': inbox,
                'type': type,
                'subtype': subtype
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("peekInbox ", deployId)
        self.propose()
        result = self.client.get_data_at_deploy_id(deployId, 5)
        if result is None:
            return [False, "no deploy data"]
        status = [False, "URI Not found"]
        if len(result.blockInfo) > 0:
            for post in result.blockInfo[0].postBlockData:
                if len(post.exprs) > 0:
                    if post.exprs[0].HasField("e_map_body"):
                        for kvs in post.exprs[0].e_map_body.kvs:
                            if kvs.key.exprs[0].HasField("g_string"):
                                if kvs.key.exprs[0].g_string == "URI":
                                    status = [True, kvs.value.exprs[0].g_uri]

        return status

    def castVote(self, key: PrivateKey, inbox: str, issue: str, choice: str):
        contract = render_contract_template(
            CASTVOTE_RHO_TPL,
            {
                'inbox': inbox,
                'issue': issue,
                'choice': choice
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("castVote ", deployId)
        self.propose()
        result = self.client.get_data_at_deploy_id(deployId)
        if result is None:
            return [False, "no deploy data"]
        oldvote = ""
        newvote = ""
        badvote = ""
        choices = ""
        if len(result.blockInfo) == 1:
            for post in result.blockInfo[0].postBlockData:
                if post.exprs[0].HasField("e_list_body"):
                    if post.exprs[0].e_list_body.ps[0].exprs[
                            0].g_string == "oldvote was":
                        if len(post.exprs[0].e_list_body.ps) > 1:
                            if len(post.exprs[0].e_list_body.ps[1].exprs) > 0:
                                oldvote = post.exprs[0].e_list_body.ps[
                                    1].exprs[0].g_string
                    if post.exprs[0].e_list_body.ps[0].exprs[
                            0].g_string == "newvote is":
                        if len(post.exprs[0].e_list_body.ps) > 1:
                            if len(post.exprs[0].e_list_body.ps[1].exprs) > 0:
                                newvote = post.exprs[0].e_list_body.ps[
                                    1].exprs[0].g_string
                if post.exprs[0].HasField("e_map_body"):
                    for kvs in post.exprs[0].e_map_body.kvs:
                        if kvs.key.exprs[0].g_string == "unknown proposal":
                            badvote = kvs.value.exprs[0].g_string
                        if kvs.key.exprs[0].g_string == "valid proposals":
                            for proposals in kvs.value.exprs[0].e_set_body.ps:
                                if choices == "":
                                    choices = proposals.exprs[0].g_string
                                else:
                                    choices = choices + ", " + proposals.exprs[
                                        0].g_string
        if badvote != "":
            return [False, [badvote, choices]]
        else:
            return [True, [oldvote, newvote]]

    def delegateVote(self, key: PrivateKey, inbox: str, issue: str,
                     delegate: str) -> str:
        contract = render_contract_template(
            DELEGATEVOTE_RHO_TPL,
            {
                'inbox': inbox,
                'issue': issue,
                'delegate': delegate
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("delegateVote ", deployId)
        self.propose()
        result = self.client.get_data_at_deploy_id(deployId)
        if result.length == 0:
            return [False, "No issue found"]
        status = [False, "URI Not found"]
        for post in result.blockInfo[0].postBlockData:
            if len(post.exprs) > 0:
                if post.exprs[0].HasField("e_tuple_body"):
                    body = post.exprs[0].e_tuple_body
                    status = [
                        True,
                        [
                            body.ps[1].exprs[0].g_string,
                            body.ps[2].exprs[0].g_uri
                        ]
                    ]
        return status

    def tallyVotes(self, key: PrivateKey, inbox: str, issue: str) -> str:
        contract = render_contract_template(
            TALLYVOTES_RHO_TPL,
            {
                'inbox': inbox,
                'issue': issue
            },
        )
        deployId = self.client.deploy_with_vabn_filled(key, contract,
                                                       TRANSFER_PHLO_PRICE,
                                                       TRANSFER_PHLO_LIMIT)
        print("tallyVotes ", deployId)
        self.propose()
        #result = self.getDeployData(deployId)
        result = self.client.get_data_at_deploy_id(deployId)
        if result.length == 0:
            return [False, "No issue found"]
        votes = {}
        found_counts = False
        found_done = False
        for BData in result.blockInfo[0].postBlockData:
            if len(BData.exprs) > 0:
                if BData.exprs[0].HasField("g_string"):
                    found_done = True
                if BData.exprs[0].HasField("e_list_body"):
                    for BList in BData.exprs[0].e_list_body.ps:
                        if BList.exprs[0].HasField("g_string"):
                            if BList.exprs[0].g_string == "counts":
                                found_counts = True
                        if BList.exprs[0].HasField("e_map_body"):
                            for voted in BList.exprs[0].e_map_body.kvs:
                                votes[voted.key.exprs[0].
                                      g_string] = voted.value.exprs[0].g_int
        return [found_counts and found_done, votes]