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")
Esempio n. 4
0
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
Esempio n. 5
0
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,