def create(start_i, end_i): local_accounts = [] for j in range(start_i, end_i): acc_name = f"{import_account_name_prefix}{name_prefix}_{j}" create_account(acc_name) addr = cli.get_address(acc_name) while addr is None: # Just added accounts, need to ensure we can fetch from keystore, TODO must improve. addr = cli.get_address(acc_name) Loggers.general.info(f"Created account: {addr} ({acc_name})") local_accounts.append(acc_name) return local_accounts
def return_balances(accounts, wait=False): """ The will return the balance of all accounts in `accounts` to the address specified in the config where `accounts` is an iterable of account-names/wallet-names. One can choose to `wait` for each transaction to succeed. This will return a list of "transaction-hashs" once all the transactions is sent. """ config = get_config() Loggers.general.info("Refunding accounts...") txn_hashes = [] account_addresses = [] for account in accounts: for shard_index in range(len(config['ENDPOINTS'])): balances = get_balances( account ) # There is a chance that you don't get all balances (b/c of latency) if shard_index < len(balances): amount = balances[shard_index]["amount"] amount -= config["ESTIMATED_GAS_PER_TXN"] if amount > config['ESTIMATED_GAS_PER_TXN']: from_address = cli.get_address(account) to_address = config['REFUND_ACCOUNT'] account_addresses.append(from_address) passphrase = get_passphrase(account) txn_hash = send_transaction(from_address, to_address, shard_index, shard_index, amount, passphrase=passphrase, wait=wait) txn_hashes.append({"shard": shard_index, "hash": txn_hash}) Loggers.general.info(f"Refund transaction hashes: {txn_hashes}") return txn_hashes
def load(start, end): for j, file_name in enumerate(key_paths[start:end]): # STRONG assumption about imported key-files. if file_name.endswith(".key") or not file_name.startswith("."): file_path = f"{keystore_path}/{file_name}" account_name = f"{import_account_name_prefix}{name_prefix}{j + start}" if not cli.get_address(account_name): cli.remove_account( account_name ) # Just in-case there is a folder with nothing in it. Loggers.general.info( f"Adding key file: ({j + start}) {file_name}") if fast_load: keystore_acc_dir = f"{cli.get_account_keystore_path()}/{account_name}" os.makedirs(keystore_acc_dir, exist_ok=True) shutil.copy(file_path, f"{keystore_acc_dir}/{file_name}") else: cli.single_call( f"hmy keys import-ks {file_path} {account_name} " f"--passphrase={passphrase}") _loaded_passphrase[account_name] = passphrase accounts_added.append(account_name) _accounts_added.add(account_name) account_balances[account_name] = get_balances(account_name)
def load_accounts(): accs_info = [] assert os.path.isfile(args.config), f"`{args.config}` is not a file" with open(args.config, 'r') as f: config = json.load(f) cli_dir = cli.get_account_keystore_path() for j, src_info in enumerate(config): sys.stdout.write(f"Key import progress: {j}/{len(config)} \r") sys.stdout.flush() # Passphrase parsing if "passphrase-file-path" in src_info.keys(): pw_path = src_info['passphrase-file-path'] assert os.path.isfile(pw_path), f"`{pw_path}` is not a file." with open(pw_path, 'r') as f: passphrase = f.read().strip() elif "passphrase" in src_info.keys(): passphrase = src_info['passphrase'] else: passphrase = '' # CLI default passphrase # Load key acc_name = f"{prefix}{j}" cli.remove_account(acc_name) if "keystore-file-path" in src_info.keys(): ks_path = src_info['keystore-file-path'] assert os.path.isfile(ks_path), f"`{ks_path}` is not a file." os.makedirs(f"{cli_dir}/{acc_name}") shutil.copy(ks_path, f"{cli_dir}/{acc_name}") address = cli.get_address(acc_name) if address is None: raise RuntimeError(f"Could not import key for config {j}") added_key_names.append(acc_name) elif "private-key" in src_info.keys(): cli.single_call( f"hmy keys import-private-key {src_info['private-key']} {acc_name}" ) address = cli.get_address(acc_name) if address is None: raise RuntimeError(f"Could not import key for config {j}") else: raise RuntimeError(f"No key to import for config {j}") accs_info.append({'address': address, 'passphrase': passphrase}) return accs_info
def _fund(src_acc, accounts, amount, shard_index): """ Internal method to fund a list of accounts given one source accounts on a specific shard for a given amount. Note that this function is meant to be threaded upon. """ if not accounts: return [] hashes = [] for account in accounts: from_address = cli.get_address(src_acc) to_address = cli.get_address(account) passphrase = get_passphrase(src_acc) h = send_transaction(from_address, to_address, shard_index, shard_index, amount, passphrase=passphrase, retry=True, wait=True) if h is None: raise RuntimeError(f"Failed to send tx from {from_address} to {to_address}") hashes.append(h) return hashes
def get_balances(account_name): """ This gets the balances for the address associated with the `account_name` (aka wallet-name) in the CLI's keystore. """ config = get_config() address = cli.get_address(account_name) if not address: return {} response = cli.single_call( f"hmy balances {address} --node={config['ENDPOINTS'][0]}", timeout=60) balances = eval( response ) # There is a chance that the CLI returns a malformed json array. info = { 'address': address, 'balances': balances, 'time-utc': str(datetime.datetime.utcnow()) } Loggers.balance.info(json.dumps(info)) account_balances[account_name] = balances return balances
def remove_accounts(accounts, backup=False): """ This will remove all `accounts`, where `accounts` is an iterable of accounts name. One can specify `backup` if one wishes to log the private keys of all removed accounts. """ for acc in accounts: address = cli.get_address(acc) private_key = "" if backup: try: private_key = cli.single_call( f"hmy keys export-private-key {address}").strip() except RuntimeError: Loggers.general.error( f"{address} ({acc}) was not imported via CLI, cannot backup" ) private_key = "NOT-IMPORTED-USING-CLI" cli.remove_account(acc) if acc in _accounts_added: _accounts_added.remove(acc) if acc in _loaded_passphrase: del _loaded_passphrase[acc] removed_account = {"address": address, "private-key": private_key} Loggers.general.info(f"Removed Account: {removed_account}")
def generate_transactions(src_accounts, snk_accounts): nonlocal txn_count batch = BatchTransactions() src_accounts_iter = itertools.cycle(src_accounts) snk_accounts_iter = itertools.cycle(acc for _ in range(len(src_accounts)) for acc in snk_accounts) while _is_running: src_name = next(src_accounts_iter) src_address = cli.get_address(src_name) passphrase = get_passphrase(src_name) # TODO: look into a way to account for a slow get nonce, which might make tx fail... # Maybe cooldown per src account..., have to redo shuffle technique, make sure to loop over all src accs... ref_nonce = [ _get_nonce(endpoints[j], src_address) for j in range(len(endpoints)) ] for _ in range(len(snk_accounts)): snk_address = cli.get_address(next(snk_accounts_iter)) txn_amt = round( random.uniform(config["AMT_PER_TXN"][0], config["AMT_PER_TXN"][1]), 18) src_shard, snk_shard = generate_to_and_from_shard() if config["ENFORCE_NONCE"]: n = ref_nonce[src_shard] curr_nonce = _get_nonce(endpoints[src_shard], src_address) if curr_nonce < n: continue if curr_nonce > n: # sync nonce if too big ref_nonce[src_shard] = curr_nonce ref_nonce[src_shard] += 1 if config["MAX_TXN_GEN_COUNT"] is not None: count_lock.acquire() if txn_count >= config["MAX_TXN_GEN_COUNT"]: count_lock.release() batch.send( config["ENDPOINTS"] [0]) # p2p broadcasts to all shards for txns return txn_count += 1 if config[ "ENFORCE_NONCE"] else _implicit_gen_txn_nonce count_lock.release() if config["ENFORCE_NONCE"]: send_transaction(src_address, snk_address, src_shard, snk_shard, txn_amt, passphrase=passphrase, wait=False) else: curr_nonce = ref_nonce[src_shard] gen_count = _implicit_gen_txn_nonce if config["MAX_TXN_GEN_COUNT"]: gen_count = min( config["MAX_TXN_GEN_COUNT"] - txn_count, gen_count) for j in range(gen_count): batch.add(src_address, snk_address, src_shard, snk_shard, txn_amt, nonce=curr_nonce + j, passphrase=passphrase, error_ok=True) ref_nonce[src_shard] += gen_count batch.send(config["ENDPOINTS"][0], chain_id=config["CHAIN_ID"] ) # p2p broadcasts to all shards for txns
#create a user cli.single_call("hmy keys add difeng") print("difeng has been successfully created") if "dfxx" not in name_dict.keys(): #create a user cli.single_call("hmy keys add dfxx") print("dfxx has been successfully created") if "test1" not in name_dict.keys(): #create a user cli.single_call("hmy keys add test1") #get address of account difeng_address = cli.get_address("difeng") dfxx_address = cli.get_address("dfxx") test1_address = cli.get_address("test1") print("The one address of account difeng is %s"%(difeng_address)) print("The one address of account dfxx is %s"%(dfxx_address)) #import keystore cli.single_call("hmy keys import-ks /root/go/src/github.com/harmony-one/harmony/.hmy/keystore/one103q7qe5t2505lypvltkqtddaef5tzfxwsse4z7.keyimport_key1") #remove address cli.remove_address(test1_address) print("%s has been successfully removed"%test1_address) #go to website https://faucet.pops.one/ #input your address and get test one
tx_gen.Loggers.report.logger.addHandler(logging.StreamHandler(sys.stdout)) log_writer_pool = ThreadPool(processes=1) log_writer_pool.apply_async(log_writer, (5,)) # === Generate private funding keys === print("Bootstrapping funding process using faucet key(s) in `./devnet_faucet_key`") tx_gen.load_accounts("./faucet_key", "", fast_load=True) private_faucet_keys = tx_gen.create_accounts(15, "PRIVATE_FAUCET") tx_gen.fund_accounts(private_faucet_keys) for key_dir in os.listdir(key_store_path): if "PRIVATE_FAUCET" in key_dir: shutil.copytree(os.path.join(key_store_path, key_dir), f"{private_keys_dir}/{key_dir}") with open("private_faucet_keys.txt", 'w') as f: for n in private_faucet_keys: f.write(str((cli.get_address(n), export_private_key(n).strip())) + "\n") # === Generate p-ops keys === print("Funding p-ops keys...") tx_gen.set_config({ "ESTIMATED_GAS_PER_TXN": 1e-3, "INIT_SRC_ACC_BAL_PER_SHARD": 2500, "TXN_WAIT_TO_CONFIRM": 600, "MAX_THREAD_COUNT": None, "ENDPOINTS": ENDPOINTS, "CHAIN_ID": CHAIN_ID }) pops_faucet_keys = tx_gen.create_accounts(42, "POPS_FAUCET") tx_gen.fund_accounts(pops_faucet_keys, [2]) for key_dir in os.listdir(key_store_path): if "POPS_FAUCET" in key_dir: