From 91055a023e99c96ad366501555e0d2468801bc09 Mon Sep 17 00:00:00 2001 From: Eric Iles Date: Fri, 25 May 2018 16:09:16 -0400 Subject: [PATCH] Add configuration arguments --- .../bios-boot-tutorial/bios-boot-tutorial.py | 183 ++++++++++-------- 1 file changed, 98 insertions(+), 85 deletions(-) diff --git a/tutorials/bios-boot-tutorial/bios-boot-tutorial.py b/tutorials/bios-boot-tutorial/bios-boot-tutorial.py index 0f85d2e7c..789ac295c 100755 --- a/tutorials/bios-boot-tutorial/bios-boot-tutorial.py +++ b/tutorials/bios-boot-tutorial/bios-boot-tutorial.py @@ -10,29 +10,12 @@ import subprocess import sys import time -genesis = './genesis.json' -walletDir = os.path.abspath('./wallet/') +args = None +logFile = None + unlockTimeout = 99999999999 -nodesDir = './nodes/' -contractsDir = '../../build/contracts/' -cleos = 'cleos --wallet-url http://localhost:6666 ' -nodeos = 'nodeos' fastUnstakeSystem = './fast.refund/eosio.system/eosio.system.wasm' -logFile = open('test.log', 'a') - -symbol = 'SYS' -maxUserKeys = 10 # Maximum user keys to import into wallet -minProducerStake = 200.0000 # Minimum producer CPU and BW stake -extraIssue = 10.0000 # Extra amount to issue to cover buying ram -limitUsers = 0 # Limit number of users if >0 -limitProducers = 0 # Limit number of producers if >0 -numVoters = 10 # Number of users which cast votes -numProducersToVoteFor = 20 # Number of producers each user votes for -numSenders = 10 # Number of users to transfer funds randomly -producerSyncDelay = 80 # Time (s) to sleep to allow producers to sync - -eosioPub = 'EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvr' -eosioPvt = '5K463ynhZoCDDa4RDcr63cUwWLTnKqmdcoTKTHBjqoKfv4u5V7p' + systemAccounts = [ 'eosio.bpay', 'eosio.msig', @@ -45,17 +28,6 @@ systemAccounts = [ 'eosio.vpay', ] -with open('accounts.json') as f: - a = json.load(f) - if limitUsers: - del a['users'][limitUsers:] - if limitProducers: - del a['producers'][limitProducers:] - firstProducer = len(a['users']) - numProducers = len(a['producers']) - accounts = a['users'] + a['producers'] - -maxClients = numProducers + 10 def jsonArg(a): return " '" + json.dumps(a) + "' " @@ -99,31 +71,31 @@ def sleep(t): print('resume') def startWallet(): - run('rm -rf ' + walletDir) - run('mkdir -p ' + walletDir) - background('keosd --unlock-timeout %d --http-server-address 127.0.0.1:6666 --wallet-dir %s' % (unlockTimeout, walletDir)) + run('rm -rf ' + os.path.abspath(args.wallet_dir)) + run('mkdir -p ' + os.path.abspath(args.wallet_dir)) + background(args.keosd + ' --unlock-timeout %d --http-server-address 127.0.0.1:6666 --wallet-dir %s' % (unlockTimeout, os.path.abspath(args.wallet_dir))) sleep(.4) - run(cleos + 'wallet create') + run(args.cleos + 'wallet create') def importKeys(): - run(cleos + 'wallet import ' + eosioPvt) + run(args.cleos + 'wallet import ' + args.private_key) keys = {} for a in accounts: key = a['pvt'] if not key in keys: - if len(keys) >= maxUserKeys: + if len(keys) >= args.max_user_keys: break keys[key] = True - run(cleos + 'wallet import ' + key) + run(args.cleos + 'wallet import ' + key) for i in range(firstProducer, firstProducer + numProducers): a = accounts[i] key = a['pvt'] if not key in keys: keys[key] = True - run(cleos + 'wallet import ' + key) + run(args.cleos + 'wallet import ' + key) def startNode(nodeIndex, account): - dir = nodesDir + ('%02d-' % nodeIndex) + account['name'] + '/' + dir = args.nodes_dir + ('%02d-' % nodeIndex) + account['name'] + '/' run('rm -rf ' + dir) run('mkdir -p ' + dir) otherOpts = ''.join(list(map(lambda i: ' --p2p-peer-address localhost:' + str(9000 + i), range(nodeIndex)))) @@ -132,10 +104,10 @@ def startNode(nodeIndex, account): ' --plugin eosio::history_api_plugin' ) cmd = ( - nodeos + + args.nodeos + ' --max-transaction-time 200' ' --contracts-console' - ' --genesis-json ' + genesis + + ' --genesis-json ' + os.path.abspath(args.genesis) + ' --blocks-dir ' + os.path.abspath(dir) + '/blocks' ' --config-dir ' + os.path.abspath(dir) + ' --data-dir ' + os.path.abspath(dir) + @@ -160,10 +132,10 @@ def startProducers(b, e): def createSystemAccounts(): for a in systemAccounts: - run(cleos + 'create account eosio ' + a + ' ' + eosioPub) + run(args.cleos + 'create account eosio ' + a + ' ' + args.public_key) def intToCurrency(i): - return '%d.%04d %s' % (i // 10000, i % 10000, symbol) + return '%d.%04d %s' % (i // 10000, i % 10000, args.symbol) def fillStake(b, e): dist = numpy.random.pareto(1.161, e - b).tolist() # 1.161 = 80/20 rule @@ -174,58 +146,58 @@ def fillStake(b, e): for i in range(b, e): stake = round(factor * dist[i - b] * 10000 / 2) if i >= firstProducer and i < firstProducer + numProducers: - stake = max(stake, round(minProducerStake * 10000)) + stake = max(stake, round(args.min_producer_stake * 10000)) total += stake * 2 accounts[i]['stake'] = stake - return total + round(extraIssue * 10000) + return total + round(args.extra_issue * 10000) def createStakedAccounts(b, e): for i in range(b, e): a = accounts[i] stake = intToCurrency(a['stake']) - run(cleos + 'system newaccount eosio --transfer ' + a['name'] + ' ' + a['pub'] + ' --stake-net "' + stake + '" --stake-cpu "' + stake + '"') + run(args.cleos + 'system newaccount eosio --transfer ' + a['name'] + ' ' + a['pub'] + ' --stake-net "' + stake + '" --stake-cpu "' + stake + '"') def regProducers(b, e): for i in range(b, e): a = accounts[i] - retry(cleos + 'system regproducer ' + a['name'] + ' ' + a['pub'] + ' https://' + a['name'] + '.com' + '/' + a['pub']) + retry(args.cleos + 'system regproducer ' + a['name'] + ' ' + a['pub'] + ' https://' + a['name'] + '.com' + '/' + a['pub']) def listProducers(): - run(cleos + 'system listproducers') + run(args.cleos + 'system listproducers') def vote(b, e): for i in range(b, e): voter = accounts[i]['name'] - prods = random.sample(range(firstProducer, firstProducer + numProducers), numProducersToVoteFor) + prods = random.sample(range(firstProducer, firstProducer + numProducers), args.num_producers_vote) prods = ' '.join(map(lambda x: accounts[x]['name'], prods)) - retry(cleos + 'system voteproducer prods ' + voter + ' ' + prods) + retry(args.cleos + 'system voteproducer prods ' + voter + ' ' + prods) def claimRewards(): - table = getJsonOutput(cleos + 'get table eosio eosio producers -l 100') + table = getJsonOutput(args.cleos + 'get table eosio eosio producers -l 100') times = [] for row in table['rows']: if row['unpaid_blocks'] and not row['last_claim_time']: - times.append(getJsonOutput(cleos + 'system claimrewards -j ' + row['owner'])['processed']['elapsed']) + times.append(getJsonOutput(args.cleos + 'system claimrewards -j ' + row['owner'])['processed']['elapsed']) print('Elapsed time for claimrewards:', times) def vote(b, e): for i in range(b, e): voter = accounts[i]['name'] - prods = random.sample(range(firstProducer, firstProducer + numProducers), numProducersToVoteFor) + prods = random.sample(range(firstProducer, firstProducer + numProducers), args.num_producers_vote) prods = ' '.join(map(lambda x: accounts[x]['name'], prods)) - retry(cleos + 'system voteproducer prods ' + voter + ' ' + prods) + retry(args.cleos + 'system voteproducer prods ' + voter + ' ' + prods) def proxyVotes(b, e): vote(firstProducer, firstProducer + 1) proxy = accounts[firstProducer]['name'] - retry(cleos + 'system regproxy ' + proxy) + retry(args.cleos + 'system regproxy ' + proxy) sleep(1.0) for i in range(b, e): voter = accounts[i]['name'] - retry(cleos + 'system voteproducer proxy ' + voter + ' ' + proxy) + retry(args.cleos + 'system voteproducer proxy ' + voter + ' ' + proxy) def updateAuth(account, permission, parent, controller): - run(cleos + 'push action eosio updateauth' + jsonArg({ + run(args.cleos + 'push action eosio updateauth' + jsonArg({ 'account': account, 'permission': permission, 'parent': parent, @@ -242,12 +214,12 @@ def resign(account, controller): updateAuth(account, 'owner', '', controller) updateAuth(account, 'active', 'owner', controller) sleep(1) - run(cleos + 'get account ' + account) + run(args.cleos + 'get account ' + account) def sendUnstakedFunds(b, e): for i in range(b, e): a = accounts[i] - run(cleos + 'transfer eosio ' + a['name'] + ' "10.0000 ' + symbol + '"') + run(args.cleos + 'transfer eosio ' + a['name'] + ' "10.0000 ' + args.symbol + '"') def randomTransfer(b, e): for j in range(20): @@ -255,7 +227,7 @@ def randomTransfer(b, e): dest = src while dest == src: dest = accounts[random.randint(b, e - 1)]['name'] - run(cleos + 'transfer -f ' + src + ' ' + dest + ' "0.0001 ' + symbol + '"' + ' || true') + run(args.cleos + 'transfer -f ' + src + ' ' + dest + ' "0.0001 ' + args.symbol + '"' + ' || true') def msigProposeReplaceSystem(proposer, proposalName): requestedPermissions = [] @@ -264,20 +236,20 @@ def msigProposeReplaceSystem(proposer, proposalName): trxPermissions = [{'actor': 'eosio', 'permission': 'active'}] with open(fastUnstakeSystem, mode='rb') as f: setcode = {'account': 'eosio', 'vmtype': 0, 'vmversion': 0, 'code': f.read().hex()} - run(cleos + 'multisig propose ' + proposalName + jsonArg(requestedPermissions) + + run(args.cleos + 'multisig propose ' + proposalName + jsonArg(requestedPermissions) + jsonArg(trxPermissions) + 'eosio setcode' + jsonArg(setcode) + ' -p ' + proposer) def msigApproveReplaceSystem(proposer, proposalName): for i in range(firstProducer, firstProducer + numProducers): - run(cleos + 'multisig approve ' + proposer + ' ' + proposalName + + run(args.cleos + 'multisig approve ' + proposer + ' ' + proposalName + jsonArg({'actor': accounts[i]['name'], 'permission': 'active'}) + '-p ' + accounts[i]['name']) def msigExecReplaceSystem(proposer, proposalName): - retry(cleos + 'multisig exec ' + proposer + ' ' + proposalName + ' -p ' + proposer) + retry(args.cleos + 'multisig exec ' + proposer + ' ' + proposalName + ' -p ' + proposer) def msigReplaceSystem(): - run(cleos + 'push action eosio buyrambytes' + jsonArg(['eosio', accounts[0]['name'], 200000]) + '-p eosio') + run(args.cleos + 'push action eosio buyrambytes' + jsonArg(['eosio', accounts[0]['name'], 200000]) + '-p eosio') sleep(1) msigProposeReplaceSystem(accounts[0]['name'], 'fast.unstake') sleep(1) @@ -287,7 +259,7 @@ def msigReplaceSystem(): def produceNewAccounts(): with open('newusers', 'w') as f: for i in range(0, 3000): - x = getOutput(cleos + 'create key') + x = getOutput(args.cleos + 'create key') r = re.match('Private key: *([^ \n]*)\nPublic key: *([^ \n]*)', x, re.DOTALL | re.MULTILINE) name = 'user' for j in range(7, -1, -1): @@ -295,7 +267,6 @@ def produceNewAccounts(): print(i, name) f.write(' {"name":"%s", "pvt":"%s", "pub":"%s"},\n' % (name, r[1], r[2])) -logFile.write('\n\n' + '*' * 80 + '\n\n\n') def stepKillAll(): run('killall keosd nodeos || true') @@ -304,20 +275,20 @@ def stepStartWallet(): startWallet() importKeys() def stepStartBoot(): - startNode(0, {'name': 'eosio', 'pvt': eosioPvt, 'pub': eosioPub}) + startNode(0, {'name': 'eosio', 'pvt': args.private_key, 'pub': args.public_key}) sleep(1.5) def stepInstallSystemContracts(): - run(cleos + 'set contract eosio.token ' + contractsDir + 'eosio.token/') - run(cleos + 'set contract eosio.msig ' + contractsDir + 'eosio.msig/') + run(args.cleos + 'set contract eosio.token ' + args.contracts_dir + 'eosio.token/') + run(args.cleos + 'set contract eosio.msig ' + args.contracts_dir + 'eosio.msig/') def stepCreateTokens(): - run(cleos + 'push action eosio.token create \'["eosio", "10000000000.0000 %s"]\' -p eosio.token' % (symbol)) + run(args.cleos + 'push action eosio.token create \'["eosio", "10000000000.0000 %s"]\' -p eosio.token' % (args.symbol)) totalAllocation = fillStake(0, len(accounts)) - run(cleos + 'push action eosio.token issue \'["eosio", "%s", "memo"]\' -p eosio' % intToCurrency(totalAllocation)) + run(args.cleos + 'push action eosio.token issue \'["eosio", "%s", "memo"]\' -p eosio' % intToCurrency(totalAllocation)) sleep(1) def stepSetSystemContract(): - retry(cleos + 'set contract eosio ' + contractsDir + 'eosio.system/') + retry(args.cleos + 'set contract eosio ' + args.contracts_dir + 'eosio.system/') sleep(1) - run(cleos + 'push action eosio setpriv' + jsonArg(['eosio.msig', 1]) + '-p eosio@active') + run(args.cleos + 'push action eosio setpriv' + jsonArg(['eosio.msig', 1]) + '-p eosio@active') def stepCreateStakedAccounts(): createStakedAccounts(0, len(accounts)) def stepRegProducers(): @@ -326,26 +297,30 @@ def stepRegProducers(): listProducers() def stepStartProducers(): startProducers(firstProducer, firstProducer + numProducers) - sleep(producerSyncDelay) + sleep(args.producer_sync_delay) def stepVote(): - vote(0, 0 + numVoters) + vote(0, 0 + args.num_voters) sleep(1) listProducers() sleep(5) def stepProxyVotes(): - proxyVotes(0, 0 + numVoters) + proxyVotes(0, 0 + args.num_voters) def stepResign(): resign('eosio', 'eosio.prods') for a in systemAccounts: resign(a, 'eosio') def stepIssueUnstaked(): - run(cleos + 'push action eosio.token issue \'["eosio", "%d.0000 %s", "memo"]\' -p eosio' % ((len(accounts)) * 10, symbol)) - sendUnstakedFunds(0, numSenders) + run(args.cleos + 'push action eosio.token issue \'["eosio", "%d.0000 %s", "memo"]\' -p eosio' % ((len(accounts)) * 10, args.symbol)) + sendUnstakedFunds(0, args.num_senders) def stepTransfer(): while True: - randomTransfer(0, numSenders) + randomTransfer(0, args.num_senders) def stepLog(): - run('tail -n 60 ' + nodesDir + '00-eosio/stderr') + run('tail -n 60 ' + args.nodes_dir + '00-eosio/stderr') + +# Command Line Arguments + +parser = argparse.ArgumentParser() commands = [ ('k', 'kill', stepKillAll, True, "Kill all nodeos and keosd processes"), @@ -368,9 +343,30 @@ commands = [ ('l', 'log', stepLog, True, "Show tail of node's log"), ] -parser = argparse.ArgumentParser() + +parser.add_argument('--public-key', metavar='', help="EOSIO Public Key", default='EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvr', dest="public_key") +parser.add_argument('--private-Key', metavar='', help="EOSIO Private Key", default='5K463ynhZoCDDa4RDcr63cUwWLTnKqmdcoTKTHBjqoKfv4u5V7p', dest="private_key") +parser.add_argument('--cleos', metavar='', help="Cleos command", default='../../build/programs/cleos/cleos --wallet-url http://localhost:6666 ') +parser.add_argument('--nodeos', metavar='', help="Path to nodeos binary", default='../../build/programs/nodeos/nodeos') +parser.add_argument('--keosd', metavar='', help="Path to keosd binary", default='../../build/programs/keosd/keosd') +parser.add_argument('--contracts-dir', metavar='', help="Path to contracts directory", default='../../build/contracts/') +parser.add_argument('--nodes-dir', metavar='', help="Path to nodes directory", default='./nodes/') +parser.add_argument('--genesis', metavar='', help="Path to genesis.json", default="./genesis.json") +parser.add_argument('--wallet-dir', metavar='', help="Path to wallet directory", default='./wallet/') +parser.add_argument('--log-path', metavar='', help="Path to log file", default='./output.log') +parser.add_argument('--symbol', metavar='', help="The eosio.system symbol", default='SYS') +parser.add_argument('--user-limit', metavar='', help="Max number of users. (0 = no limit)", type=int, default=0) +parser.add_argument('--max-user-keys', metavar='', help="Maximum user keys to import into wallet", type=int, default=10) +parser.add_argument('--extra-issue', metavar='', help="Extra amount to issue to cover buying ram", type=float, default=10.0000) +parser.add_argument('--producer-limit', metavar='', help="Maximum number of producers. (0 = no limit)", type=int, default=0) +parser.add_argument('--min-producer-stake', metavar='', help="Minimum producer CPU and BW stake", type=float, default=200.0000) +parser.add_argument('--num-producers-vote', metavar='', help="Number of producers for which each user votes", type=int, default=20) +parser.add_argument('--num-voters', metavar='', help="Number of voters", type=int, default=10) +parser.add_argument('--num-senders', metavar='', help="Number of users to transfer funds randomly", type=int, default=10) +parser.add_argument('--producer-sync-delay', metavar='', help="Time (s) to sleep to allow producers to sync", type=int, default=80) parser.add_argument('-a', '--all', action='store_true', help="Do everything marked with (*)") -parser.add_argument('-H', '--http-port', type=int, default=8000, help='Http port for cleos') +parser.add_argument('-H', '--http-port', type=int, default=8000, metavar='', help='HTTP port for cleos') + for (flag, command, function, inAll, help) in commands: prefix = '' if inAll: prefix += '*' @@ -379,9 +375,26 @@ for (flag, command, function, inAll, help) in commands: parser.add_argument('-' + flag, '--' + command, action='store_true', help=help, dest=command) else: parser.add_argument('--' + command, action='store_true', help=help, dest=command) + args = parser.parse_args() -cleos += '--url http://localhost:%d ' % args.http_port +args.cleos += '--url http://localhost:%d ' % args.http_port + +logFile = open(args.log_path, 'a') + +logFile.write('\n\n' + '*' * 80 + '\n\n\n') + +with open('accounts.json') as f: + a = json.load(f) + if args.user_limit: + del a['users'][args.user_limit:] + if args.producer_limit: + del a['producers'][args.producer_limit:] + firstProducer = len(a['users']) + numProducers = len(a['producers']) + accounts = a['users'] + a['producers'] + +maxClients = numProducers + 10 haveCommand = False for (flag, command, function, inAll, help) in commands: -- GitLab