def wss_handshake(rpc): """ Create a websocket handshake """ while True: nodes = json_ipc(doc="nodes.txt") try: rpc.close() except Exception: pass try: shuffle(nodes) node = nodes[0] start = time.time() rpc = wss(node, timeout=4) if time.time() - start < 3: # print(node) break except Exception: nodes = [n for n in nodes if n != node] if len(nodes) < 7: nodes = bitshares_nodes() json_ipc(doc="nodes.txt", text=json_dumps(nodes)) return rpc
def unit_test_issue(network): """ print chain state issue, transfer, reserve a BitShares UIA print chain state again """ gate_header = { "asset_id": GATE["uia"][network]["asset_id"], "asset_precision": GATE["uia"][network]["asset_precision"], # gate account details "account_id": GATE["uia"][network]["issuer_id"], "account_name": GATE["uia"][network]["issuer_public"], "wif": GATE["uia"][network]["issuer_private"], } test_header = { "asset_id": GATE["uia"][network]["asset_id"], "asset_precision": GATE["uia"][network]["asset_precision"], # test account details "account_id": TEST["bts"]["id"], "account_name": TEST["bts"]["public"], "wif": TEST["bts"]["private"], } order = {"nodes": bitshares_nodes()} # login to accounts order["edicts"] = [{"op": "login"}] order["header"] = test_header print("Log In", order["header"]["account_name"], broker(order), "\n\n") order["header"] = gate_header print("Log In", order["header"]["account_name"], broker(order), "\n\n") # issue asset order["edicts"] = [{ "op": "issue", "amount": AMOUNT, "account_id": test_header["account_id"], "memo": "", }] print({k: v for k, v in order["header"].items() if k != "wif"}) print("Issue Asset", order["edicts"], broker(order), "\n\n") # transfer order["header"] = test_header order["edicts"] = [{ "op": "transfer", "amount": AMOUNT, "account_id": gate_header["account_id"], "memo": "", }] print({k: v for k, v in order["header"].items() if k != "wif"}) print("Transfer Asset", order["edicts"], broker(order), "\n\n") # reserve asset order["header"] = gate_header order["edicts"] = [{"op": "reserve", "amount": AMOUNT}] print({k: v for k, v in order["header"].items() if k != "wif"}) print("Reserve Asset", order["edicts"], broker(order), "\n\n")
def refill_test_account(): """ manually add uia funds to continue testing """ networks = ["xrp", "eos"] for network in networks: order = {"nodes": bitshares_nodes()} order["header"] = { "asset_id": GATE["uia"][network]["asset_id"], "asset_precision": GATE["uia"][network]["asset_precision"], # gate account details "account_id": GATE["uia"][network]["issuer_id"], "account_name": GATE["uia"][network]["issuer_public"], "wif": GATE["uia"][network]["issuer_private"], } order["edicts"] = [{ "op": "issue", "amount": 100, "account_id": TEST["bts"]["id"], "memo": "", }] print({k: v for k, v in order["header"].items() if k != "wif"}) print("Issue Asset", order["edicts"], broker(order), "\n\n")
def listener_bitshares(selection=None): """ primary listener event loop :param int(selection) or None: user choice for demonstration of listener :run forever: """ # get node list from github repo for bitshares ui staging; write to file nodes = bitshares_nodes() options = raw_operations() json_ipc(doc="nodes.txt", text=json_dumps(nodes)) # create a subfolder for the database; write to file create_database() # initialize block number last_block_num = curr_block_num = 0 # bypass user input... gateway transfer ops act = print_op if selection is None: selection = 0 act = withdraw # spawn subprocesses for gathering streaming consensus irreversible block number spawn_block_num_processes() # continually listen for last block["transaction"]["operations"] print(it("red", "\nINITIALIZING WITHDRAWAL LISTENER\n\n")) while True: try: # get the irreversible block number reported by each maven subprocess block_numbers = [] for maven_id in range(BLOCK_NUM_MAVENS): block_num = json_ipc(doc=f"block_num_maven_{maven_id}.txt")[0] block_numbers.append(block_num) # the current block number is the statistical mode of the mavens # NOTE: may throw StatisticsError when no mode curr_block_num = mode(block_numbers) # print(curr_block_num) json_ipc(doc=f"block_number.txt", text=json_dumps([ curr_block_num, ])) # if the irreverisble block number has advanced if curr_block_num > last_block_num: print( "\033[F", # go back one line it("blue", "BitShares Irreversible Block"), it("yellow", curr_block_num), time.ctime()[11:19], it("blue", int(time.time())), ) if last_block_num > 0: # not on first iter # spawn some new mavens to get prospective block data start = last_block_num + 1 stop = curr_block_num + 1 spawn_block_processes(start, stop) # inititialize blocks as a dict of empty transaction lists blocks = {} for block_num in range(start, stop): blocks[block_num] = [] # get block transactions from each maven subprocesses for maven_id in range(BLOCK_MAVENS): # print(maven_id) maven_blocks = json_ipc( doc=f"block_maven_{maven_id}.txt") # for each block that has past since last update for block_num in range(start, stop): # print(block_num) # get the maven's version of that block from the dictionary # NOTE: may throw KeyError, TODO: find out why? maven_block = maven_blocks[str(block_num)] # append that version to the list # of maven opinions for that block number blocks[block_num].append(json_dumps(maven_block)) # get the mode of the mavens for each block in the blocks dict # NOTE: may throw StatisticsError when no mode # for example half the nodes are on the next block number blocks = { k: json_loads(mode(v)) for k, v in blocks.items() } # triple nested: # for each operation, in each transaction, on each block for block_num, transactions in blocks.items(): for item, trx in enumerate(transactions): for op in trx["operations"]: # add the block and transaction numbers to the operation op[1]["block"] = block_num op[1]["trx"] = item + 1 op[1]["operation"] = (op[0], options[op[0]]) # spin off withdrawal act so listener can continue process = Process(target=act, args=(op, )) process.start() last_block_num = curr_block_num time.sleep(6) # statistics and key errors can be safely ignored, restart loop except (StatisticsError, KeyError): continue # in all other cases provide stack trace except Exception as error: print("\n\n", it("yellow", error), "\n\n") print(traceback.format_exc(), "\n") continue
from json import loads as json_loads from statistics import mode, StatisticsError # GRAPHENE PYTHON GATEWAY MODULES from utilities import json_ipc, from_iso_date, it, raw_operations, timestamp from utilities import wss_handshake, wss_query, block_ops_logo, line_number from listener_eosio import listener_eosio, verify_eosio_account from listener_ripple import listener_ripple, verify_ripple_account from nodes import bitshares_nodes, eosio_nodes from signing_eosio import eos_transfer from signing_ripple import xrp_transfer from decoder_ring import ovaltine from config import configure # CONSTANTS BLOCK_MAVENS = min(5, len(bitshares_nodes())) BLOCK_NUM_MAVENS = min(5, len(bitshares_nodes())) BEGIN = int(time.time()) GATE = configure()["gate"] PATH = str(os.path.dirname(os.path.abspath(__file__))) + "/" def create_database(): """ initialize an empty text pipe IPC json_ipc :return None: """ os.makedirs(PATH + "pipe", exist_ok=True) for maven_id in range(BLOCK_NUM_MAVENS): json_ipc(doc=f"block_num_maven_{maven_id}.txt", text=json_dumps([ 0,