def get_the_latest_block(): with grpc.insecure_channel("{}.{}.rchain-dev.tk:40404".format(target_node, target_net)) as g_channel: client = RClient(g_channel) blockList = client.show_blocks(1) latest_block = blockList[0] return latest_block
def is_contain_block_hash(self, block_hash): with grpc.insecure_channel(self.grpc_host) as channel: client = RClient(channel) try: client.show_block(block_hash) return True except RClientException: logging.info("node {} doesn't contain {}".format( self.host_name, block_hash)) return False
def main(): god_key = PrivateKey.generate() alice_key = PrivateKey.generate() bob_key = PrivateKey.generate() god_addr = god_key.get_public_key().get_rev_address() alice_addr = alice_key.get_public_key().get_rev_address() bob_addr = bob_key.get_public_key().get_rev_address() with grpc.insecure_channel('172.27.0.2:40401') as channel: client = RClient(channel) god_vault_api = VaultAPI(client, god_key) alice_vault_api = VaultAPI(client, alice_key) bob_vault_api = VaultAPI(client, bob_key) # Most methods without deploy_ prefix create block (propose) after # deploy. To deploy a batch and then create block do: # # alice_vault_api.deploy_create_vault() # bob_vault_api.deploy_create_vault() # client.propose() alice_vault_api.create_vault() bob_vault_api.create_vault() assert god_vault_api.get_balance() == 100_000 assert alice_vault_api.get_balance() == 0 assert bob_vault_api.get_balance() == 0 god_vault_api.transfer(None, alice_addr, 1000) # Example way to get balances in one block: god_bal_deploy_id = god_vault_api.deploy_get_balance() alice_bal_deploy_id = alice_vault_api.deploy_get_balance() bob_bal_deploy_id = bob_vault_api.deploy_get_balance() client.propose() god_bal = god_vault_api.get_balance_from_deploy_id(god_bal_deploy_id) alice_bal = alice_vault_api.get_balance_from_deploy_id( alice_bal_deploy_id) bob_bal = bob_vault_api.get_balance_from_deploy_id(bob_bal_deploy_id) assert god_bal == 99_000 assert alice_bal == 1000 assert bob_bal == 0 alice_vault_api.transfer(None, bob_addr, 400) assert god_vault_api.get_balance() == 99_000 assert alice_vault_api.get_balance() == 600 assert bob_vault_api.get_balance() == 400
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 faucet(address: str, request: Request): request_before = request_faucet_TTCache.get(request.client.host) if request_before: return FaucetResponse( deployID='', message='Your request for testnet rev is too high. Try later.') else: try: with RClient(setting.TARGET_TESTNET_HOST, setting.TARGET_TESTNET_PORT) as client: vault = VaultAPI(client) private = PrivateKey.from_hex( setting.TESTNET_FAUCET_PRIVATE_KEY) deployId = vault.transfer( private.get_public_key().get_rev_address(), address, setting.TESTNET_FAUCET_AMOUNT, private) request_faucet_TTCache[request.client.host] = address return FaucetResponse( deployID=deployId, message= "Transfer to your address is done. You will receive the rev in some time" ) except RClientException as e: return FaucetResponse( deployID='', message="There is something with server {}. " "Please contact the maintainer to solve it.".format(e))
def get_block(self, hash: str) -> BlockInfo: with RClient(self.get_self_host(), self.get_external_grpc_port()) as client: try: return client.show_block(hash) except RClientException as e: message = e.args[0] raise GetBlockError(('show-block',), 1, message) from e
def faucetPost(faucetRequest: FaucetRequest, request: Request): address = faucetRequest.address ip = ipaddress.ip_address(request.client.host) if ip.is_private: host = request.headers.get('X-Real-IP') if host: addr = ipaddress.ip_address(host) else: addr = request.client.host else: addr = request.client.host request_before = request_faucet_TTCache.get(addr) if request_before: return FaucetResponse(deployID=request_before[1], message='IP:{}, Your request for testnet rev to {} is too high. Try later'.format( addr, request_before[0])) else: try: with RClient(setting.TARGET_TESTNET_HOST, setting.TARGET_TESTNET_PORT) as client: vault = VaultAPI(client) private = PrivateKey.from_hex(setting.TESTNET_FAUCET_PRIVATE_KEY) deployId = vault.transfer_ensure(private.get_public_key().get_rev_address(), address, setting.TESTNET_FAUCET_AMOUNT, private) request_faucet_TTCache[addr] = (address, deployId, request.client.host) return FaucetResponse(deployID=deployId, message="Transfer to your address is done. You will receive the rev in some time") except RClientException as e: return FaucetResponse(deployID='', message="There is something with server {}. " "Please contact the maintainer to solve it.".format(e))
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
def test_client_is_finalized_block() -> None: class DummyDeployService(DeployServiceServicer): def isFinalized(self, request: IsFinalizedQuery, context: grpc.ServicerContext) -> IsFinalizedResponse: return IsFinalizedResponse(isFinalized=True) with deploy_service(DummyDeployService()) as (server, port), \ RClient(TEST_HOST, port) as client: assert client.is_finalized('asd')
def test_client_last_finalized_block() -> None: class DummyDeployService(DeployServiceServicer): def lastFinalizedBlock( self, request: LastFinalizedBlockQuery, context: grpc.ServicerContext) -> LastFinalizedBlockResponse: return LastFinalizedBlockResponse(blockInfo=BlockInfo()) with deploy_service(DummyDeployService()) as (server, port), \ RClient(TEST_HOST, port) as client: assert client.last_finalized_block()
def test_client_find_deploy() -> None: deploy_id = '61e594124ca6af84a5468d98b34a4f3431ef39c54c6cf07fe6fbf8b079ef64f6' class DummyDeployService(DeployServiceServicer): def findDeploy(self, request: FindDeployQuery, context: grpc.ServicerContext) -> FindDeployResponse: return FindDeployResponse(blockInfo=LightBlockInfo()) with deploy_service(DummyDeployService()) as (server, port), \ RClient(TEST_HOST, port) as client: assert client.find_deploy(deploy_id)
def deploy_string(self, rholang_code: str, private_key: PrivateKey, phlo_limit:int = DEFAULT_PHLO_LIMIT, phlo_price: int = DEFAULT_PHLO_PRICE, valid_after_block_no:int = 0) -> str: try: now_time = int(time.time()*1000) with RClient(self.get_self_host(), self.get_external_grpc_port()) as client: return client.deploy(private_key, rholang_code, phlo_price, phlo_limit, valid_after_block_no, now_time) except RClientException as e: message = e.args[0] if "Parsing error" in message: raise ParsingError(command=("propose", ), exit_code=1, output=message) from e # TODO out of phlogiston error raise e
def propose(self) -> str: try: with RClient(self.get_self_host(), self.get_internal_grpc_port()) as client: return client.propose() except RClientException as e: message = e.args[0] if "Must wait for more blocks from other validators" in message: raise SynchronyConstraintError(command=('propose',), exit_code=1, output=message) from e if "ReadOnlyMode" in message: raise NotAnActiveValidatorError(command=('propose',), exit_code=1, output=message) from e if "Validator does not have a latest message" in message: raise ValidatorNotContainsLatestMes(command=('propose',), exit_code=1, output=message) from e raise e
def submit_deploy(deployer: str, term: str, phlo_price: int, phlo_limit: int, valid_after_block_number: int, timestamp: int, sig_algorithm: str, sig: str, host: str, port: int) -> None: deploy = DeployDataProto(deployer=bytes.fromhex(deployer), term=term, phloPrice=phlo_price, phloLimit=phlo_limit, validAfterBlockNumber=valid_after_block_number, timestamp=timestamp, sigAlgorithm='secp256k1', sig=bytes.fromhex(sig)) with RClient(host, port) as client: client.send_deploy(deploy)
def test_client_propose() -> None: block_hash = "abcabcabc" class DummyProposeService(ProposeServiceServicer): def propose(self, request: PrintUnmatchedSendsQuery, context: grpc.ServicerContext) -> ProposeResponse: return ProposeResponse( result="Success! Block {} created and added.".format( block_hash)) with deploy_service(DummyProposeService()) as (server, port), \ RClient(TEST_HOST, port) as client: hash = client.propose() assert hash == block_hash
def fetch_transactions(block_hash: str): client = RClient(TARGET_RNODE_HOST, TARGET_RNODE_PORT, ( ('grpc.keepalive_time_ms', 10000), ('grpc.max_receive_message_length', 1619430400), ), True) client.install_param(mainnet_param) logging.info("request {} getTransaction from server {}".format( block_hash, TARGET_RNODE_HOST)) transactions = client.get_transaction(block_hash) logging.info("receive {} getTransaction {} from server {}".format( block_hash, transactions, TARGET_RNODE_HOST)) client.close() return json.dumps(to_dict(transactions)).encode('utf8')
def test_client_deploy(key: PrivateKey, terms: str, phlo_price: int, phlo_limit: int, valid_after_block_no: int, timestamp_millis: int) -> None: class DummyDeploySerivce(DeployServiceServicer): def doDeploy(self, request: DeployDataProto, context: grpc.ServicerContext) -> DeployResponse: return DeployResponse(result=request.sig.hex()) with deploy_service(DummyDeploySerivce()) as (server, port), \ RClient(TEST_HOST, port) as client: ret = client.deploy(key, terms, phlo_price, phlo_limit, valid_after_block_no, timestamp_millis) assert verify_deploy_data( key.get_public_key(), bytes.fromhex(ret), create_deploy_data(key, terms, phlo_price, phlo_limit, valid_after_block_no, timestamp_millis))
def faucetPost(faucetRequest: FaucetRequest, request: Request): address = faucetRequest.address realIp = request.headers.get('X-Real-IP') if realIp: addr = ipaddress.ip_address(realIp) else: addr = request.client.host request_before = request_faucet_TTCache.get(addr) if request_before: return FaucetResponse( deployID=request_before[1], message= 'IP:{}, Your request for testnet rev to {} is too high. Try later'. format(addr, request_before[0])) else: try: with RClient(setting.TARGET_TESTNET_HOST, setting.TARGET_TESTNET_PORT) as client: private = PrivateKey.from_hex( setting.TESTNET_FAUCET_PRIVATE_KEY) contract = render_contract_template( TRANSFER_ENSURE_TO_RHO_TPL, { 'from': private.get_public_key().get_rev_address(), 'to': address, 'amount': str(setting.TESTNET_FAUCET_AMOUNT) }) timestamp_mill = int(time.time() * 1000) deployId = client.deploy_with_vabn_filled( private, contract, TRANSFER_PHLO_PRICE, TRANSFER_PHLO_LIMIT, timestamp_mill, setting.TESTNET_FAUCET_SHARDID) request_faucet_TTCache[addr] = (address, deployId, request.client.host) return FaucetResponse( deployID=deployId, message= "Transfer to your address is done. You will receive the rev in some time" ) except RClientException as e: return FaucetResponse( deployID='', message="There is something with server {}. " "Please contact the maintainer to solve it.".format(e))
def last_finalized_block(self) -> BlockInfo: with RClient(self.get_self_host(), self.get_external_grpc_port()) as client: return client.last_finalized_block()
def find_deploy(self, deploy_id: str) -> LightBlockInfo: with RClient(self.get_self_host(), self.get_external_grpc_port()) as client: return client.find_deploy(deploy_id)
# Requires the following line in wallets.txt # # 0x06a441c277bf454c5d159b0e5bdafca69b296733,1000000,0 import grpc from rchain.crypto import PrivateKey from rchain.client import RClient from rchain.vault import VaultAPI alice_key = PrivateKey.from_hex( "2a6cd3b196a0b154446a23443cee70629cdb3db0398ea6fb099175708f47f590") alice_public_key = alice_key.get_public_key() print("Private key is " + alice_key.to_hex()) print("Public key is " + alice_public_key.to_hex()) print("Eth address is " + alice_public_key.get_eth_address()) print("Rev address is " + alice_public_key.get_rev_address()) with grpc.insecure_channel('localhost:10401') as channel: client = RClient(channel) alice_vault_api = VaultAPI(client, alice_key) alice_vault_api.bond(amount=100) alice_bal_deploy_id = alice_vault_api.deploy_get_balance() client.propose() alice_bal = alice_vault_api.get_balance_from_deploy_id(alice_bal_deploy_id) assert alice_bal == 999900
def test_client_show_block() -> None: request_block_hash = "asdasdasdasd" sender = "a" seqNum = 1 sig = "sig" sigAlgorithm = "sigal" shardId = "rchain" extraBytes = b"extraBytes" version = 1 timestamp = 10000000 headerExtraBytes = b"headerExtraBytes" parentsHashList = ["abc"] blockNumber = 1 preStateHash = "preStateHash" postStateHash = "postStateHash" bodyExtraBytes = b"bodyExtraBytes" bond = BondInfo(validator="a", stake=100) blockSize = "100" deployCount = 1 faultTolerance = 0.2 deploy = DeployInfo(deployer="a", term="1", timestamp=timestamp, sig=sig, sigAlgorithm=sigAlgorithm, phloPrice=1, phloLimit=100000, validAfterBlockNumber=1, cost=100, errored=False, systemDeployError="none") class DummyDeploySerivce(DeployServiceServicer): def getBlock(self, request: BlockQuery, context: grpc.ServicerContext) -> BlockResponse: return BlockResponse(blockInfo=BlockInfo(blockInfo=LightBlockInfo( blockHash=request_block_hash, sender=sender, seqNum=seqNum, sig=sig, sigAlgorithm=sigAlgorithm, shardId=shardId, extraBytes=extraBytes, version=version, timestamp=timestamp, headerExtraBytes=headerExtraBytes, parentsHashList=parentsHashList, blockNumber=blockNumber, preStateHash=preStateHash, postStateHash=postStateHash, bodyExtraBytes=bodyExtraBytes, bonds=[bond], blockSize=blockSize, deployCount=deployCount, faultTolerance=faultTolerance), deploys=[deploy])) with deploy_service(DummyDeploySerivce()) as (server, port), \ RClient(TEST_HOST, port) as client: block = client.show_block(request_block_hash) block_info = block.blockInfo assert block_info.blockHash == request_block_hash assert block_info.sender == sender assert block_info.seqNum == seqNum assert block_info.sig == sig assert block_info.sigAlgorithm == sigAlgorithm assert block_info.shardId == shardId assert block_info.extraBytes == extraBytes assert block_info.version == version assert block_info.timestamp == timestamp assert block_info.headerExtraBytes == headerExtraBytes assert block_info.parentsHashList == parentsHashList assert block_info.blockNumber == blockNumber assert block_info.preStateHash == preStateHash assert block_info.postStateHash == postStateHash assert block_info.bodyExtraBytes == bodyExtraBytes assert block_info.blockSize == blockSize assert block_info.deployCount == deployCount assert pytest.approx(block_info.faultTolerance, faultTolerance) bond_info = block_info.bonds[0] assert bond_info.validator == bond.validator assert bond_info.stake == bond.stake deploy_info = block.deploys[0] assert deploy_info.deployer == deploy.deployer assert deploy_info.term == deploy.term assert deploy_info.timestamp == deploy.timestamp assert deploy_info.sig == deploy.sig assert deploy_info.sigAlgorithm == deploy.sigAlgorithm assert deploy_info.phloPrice == deploy.phloPrice assert deploy_info.phloLimit == deploy.phloLimit assert deploy_info.validAfterBlockNumber == deploy.validAfterBlockNumber assert deploy_info.cost == deploy.cost assert deploy_info.errored == deploy.errored assert deploy_info.systemDeployError == deploy.systemDeployError
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]
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 ])
def test_client_show_blocks() -> None: request_block_hash = "asdasdasdasd" sender = "a" seqNum = 1 sig = "sig" sigAlgorithm = "sigal" shardId = "rchain" extraBytes = b"extraBytes" version = 1 timestamp = 10000000 headerExtraBytes = b"headerExtraBytes" parentsHashList = ["abc"] blockNumber = 1 preStateHash = "preStateHash" postStateHash = "postStateHash" bodyExtraBytes = b"bodyExtraBytes" bond = BondInfo(validator="a", stake=100) blockSize = "100" deployCount = 1 faultTolerance = 0.2 class DummyDeploySerivce(DeployServiceServicer): def getBlocks( self, request: BlocksQuery, context: grpc.ServicerContext ) -> Generator[BlockInfoResponse, None, None]: yield BlockInfoResponse( blockInfo=LightBlockInfo(blockHash=request_block_hash, sender=sender, seqNum=seqNum, sig=sig, sigAlgorithm=sigAlgorithm, shardId=shardId, extraBytes=extraBytes, version=version, timestamp=timestamp, headerExtraBytes=headerExtraBytes, parentsHashList=parentsHashList, blockNumber=blockNumber, preStateHash=preStateHash, postStateHash=postStateHash, bodyExtraBytes=bodyExtraBytes, bonds=[bond], blockSize=blockSize, deployCount=deployCount, faultTolerance=faultTolerance)) with deploy_service(DummyDeploySerivce()) as (server, port), \ RClient(TEST_HOST, port) as client: blocks = client.show_blocks() block_info = blocks[0] assert len(blocks) == 1 assert block_info.blockHash == request_block_hash assert block_info.sender == sender assert block_info.seqNum == seqNum assert block_info.sig == sig assert block_info.sigAlgorithm == sigAlgorithm assert block_info.shardId == shardId assert block_info.extraBytes == extraBytes assert block_info.version == version assert block_info.timestamp == timestamp assert block_info.headerExtraBytes == headerExtraBytes assert block_info.parentsHashList == parentsHashList assert block_info.blockNumber == blockNumber assert block_info.preStateHash == preStateHash assert block_info.postStateHash == postStateHash assert block_info.bodyExtraBytes == bodyExtraBytes assert block_info.blockSize == blockSize assert block_info.deployCount == deployCount assert pytest.approx(block_info.faultTolerance, faultTolerance) bond_info = block_info.bonds[0] assert bond_info.validator == bond.validator assert bond_info.stake == bond.stake
'node7.root-shard.mainnet.rchain.coop', 'node8.root-shard.mainnet.rchain.coop'] READONLY_SERVER = ['observer-asia.services.mainnet.rchain.coop', 'observer-us.services.mainnet.rchain.coop', 'observer-eu.services.mainnet.rchain.coop'] admin_key = PrivateKey.generate() contract = "@1!(2)" exploratory_term = 'new return in{return!("a")}' block_hash = '4d135ce5773a05a782d1c52a7dfb42c4142b1a471bc3c57d77eee4d5affdef9a' find_deploy = '3045022100c4cdd5e8bb05b1627c2302ffd90393cf30ed0ad693ef63d46e5d8b99856a44c40220055b2dff342934b59b3fac5ac1f81c7b7763db9ee945809d86b04dbd48867bd4' # read-only node can not deploy with deploy request with RClient(READONLY_SERVER[0], 40401) as client: # get the latest 10 block in the rnode block_infos = client.show_blocks(depth=10) # get the detailed info in the rnode block = client.show_block(block_hash) # get the last finalize block from the node last_finalize_block = client.last_finalized_block() # confirm if a block is finalized assert client.is_finalized(block_hash) # get blocks from blockNumber 10 to blockNumber 20 block_at_heights = client.get_blocks_by_heights(10, 20)
# https://github.com/tgrospic/rnode-client-js/blob/master/src/nodejs/client-insert-signed.js # the logic below mostly copied from the logic of the link above from rchain.crypto import PrivateKey, blake2b_32 from rchain.client import RClient from rchain.pb.RhoTypes_pb2 import Par, Expr, ETuple, Bundle, GPrivate, GUnforgeable host = "localhost" port = 40402 deployKey = PrivateKey.generate() timestamp = 1559156356769 nonce = 9223372036854775807 publicKey = deployKey.get_public_key() with RClient(host, port) as client: ret = client.previewPrivateNames(publicKey, timestamp, 3) unforgeable = ret.payload.ids[0] print(unforgeable) dataToSign = Par(exprs=[ Expr(e_tuple_body=ETuple(ps=[ Par(exprs=[Expr(g_int=nonce)]), Par(bundles=[ Bundle(body=Par(unforgeables=[ GUnforgeable(g_private_body=GPrivate(id=unforgeable)) ]), writeFlag=True, readFlag=False) ]) ]))
'node2.root-shard.mainnet.rchain.coop', 'node3.root-shard.mainnet.rchain.coop', 'node4.root-shard.mainnet.rchain.coop', 'node5.root-shard.mainnet.rchain.coop', 'node6.root-shard.mainnet.rchain.coop', 'node7.root-shard.mainnet.rchain.coop', 'node8.root-shard.mainnet.rchain.coop' ] READONLY_SERVER = [ 'observer-asia.services.mainnet.rchain.coop', 'observer-us.services.mainnet.rchain.coop', 'observer-eu.services.mainnet.rchain.coop' ] with RClient(TESTNET_READONLY[0], 40401) as client: from rchain.param import testnet_param # these param are fixed when the network starts on the genesis # the param will never change except hard-fork # but different network has different param based on the genesis block client.install_param(testnet_param) block_hash = '8012e93f480d561045f1046d74f8cb7c31a96206e49dbdf15b22a636e18a4693' testnet_transactions = client.get_transaction(block_hash) with RClient(READONLY_SERVER[0], 40401) as client: from rchain.param import mainnet_param # these param are fixed when the network starts on the genesis # the param will never change except hard-fork # but different network has different param based on the genesis block
help="private key of the sender vault") parser.add_argument("-r", "--receiver", action="store", type=str, required=True, dest="receiver", help="receiver of the transfer") parser.add_argument("-a", "--amount", action="store", type=int, required=True, dest="amount", help="the amount of the transfer") args = parser.parse_args() try: private_key = PrivateKey.from_hex(args.private_key) except: logging.error("The private you provided is not valid") sys.exit(1) with grpc.insecure_channel('localhost:40401') as channel: client = RClient(channel) vault = VaultAPI(client, private_key) vault.transfer(from_addr=None, to_addr=args.receiver, amount=args.amount) logging.info("Succeed transfer {} from {} to {} .".format( args.amount, private_key.get_public_key().get_rev_address(), args.receiver))
def get_blocks(self, depth: int) -> List[LightBlockInfo]: with RClient(self.get_self_host(), self.get_external_grpc_port()) as client: return client.show_blocks(depth)