Permalink
Browse files

major overhaul of project locations

  • Loading branch information...
jmunsch
jmunsch committed Sep 11, 2017
1 parent c38c3a2 commit 4235cd632fb5f8aa62808fd282122fa571650dac
Showing with 111 additions and 98 deletions.
  1. +1 −1 .travis.yml
  2. +12 −0 clear.sh
  3. +12 −13 saffron/cli.py
  4. +2 −5 saffron/contracts.py
  5. +2 −18 saffron/genesis.py
  6. +23 −2 saffron/settings.py
  7. +50 −58 saffron/utils.py
  8. +7 −0 tests/pytest.ini
  9. +2 −1 tests/test_accounts.py
View
@@ -7,7 +7,7 @@ before_install:
- sudo apt-get update
- sudo apt-get install -y ethereum solc
install: "python setup.py develop"
script: pytest tests
script: LAMDEN_FOLDER_PATH=. pytest tests
notifications:
webhooks:
- https://lamden-discord-travisci.herokuapp.com/webhook/
View
@@ -0,0 +1,12 @@
#! /bin/bash
saffron stop
rm -rf ~/.lamden/*
unset LAMDEN_HOME
unset LAMDEN_FOLDER_PATH
unset LAMDEN_DB_FILE
saffron init newCoin
source ~/.lamden/newCoin/newCoin.source
saffron start newCoin
cp -R ./saffron/contracts ~/.lamden/newCoin
saffron deploy
View
@@ -30,11 +30,7 @@ def init(chain_name):
# lamden_home
'/Users/jmunsch/.lamden'
'''
src_string = '''#! /bin/bash
export LAMDEN_HOME='{LAMDEN_HOME}'
export LAMDEN_FOLDER_PATH='{LAMDEN_FOLDER_PATH}'
export LAMDEN_DB_FILE='{LAMDEN_DB_FILE}'
'''.format
new_path = os.path.join(settings.lamden_home, chain_name)
try:
os.makedirs(new_path)
@@ -45,11 +41,13 @@ def init(chain_name):
db_filename = os.path.join(chain_name, '{}.sqlite3'.format(chain_name))
settings.lamden_folder_path = new_path
settings.lamden_db_file = settings.lamden_db_file.replace('lamden-default/lamden-default.sqlite3', db_filename)
env = os.path.join(settings.lamden_folder_path, '{}.source'.format(chain_name))
s = src_string(LAMDEN_HOME=settings.lamden_home,
env = settings.env_source(chain_name)
s = settings.src_string(LAMDEN_HOME=settings.lamden_home,
LAMDEN_FOLDER_PATH=settings.lamden_folder_path,
LAMDEN_DB_FILE=settings.lamden_db_file)
with open(env,'wb') as f:
LAMDEN_DB_FILE=settings.lamden_db_file,
NODE_INFO_JSON=settings.node_info_json(chain_name),
PROJECT_GENESIS=settings.project_genesis(chain_name))
with open(env, 'wb') as f:
f.write(s.encode('utf-8'))
print('\n############### project dir ###########\n')
print('New Source File : {}\n'.format(os.path.expanduser('~/.lamden/{c}/{c}.source'.format(c=chain_name))))
@@ -58,22 +56,23 @@ def init(chain_name):
print('###########\n')
utils.run_generator(chain_name)
@cli.command('start', short_help='starts a chain from cwd genesis.json')
def start():
@cli.command('start', short_help='starts a chain based on ENV for genesis location')
@click.argument('chain_name', required=True)
def start(chain_name):
'''Starts a chain given the folder path.
see: cat ~/.lamden/project-name/project-name.source
'''
genesis_payload = None
try:
genesis_payload = open(settings.project_genesis, 'r').read()
genesis_payload = open(settings.project_genesis(chain_name), 'r').read()
except:
raise Exception('Could not start chain. No genesis.json in this directory. Change directories or initialize a new chain.')
print('Starting chain...')
chain = Chain()
proc = chain.start()
print(proc.pid)
with open(os.path.join(settings.lamden_folder_path,'chain.pid'), 'w') as f:
with open(settings.chain_pid, 'w') as f:
f.write(str(proc.pid))
@cli.command('stop', short_help='stop the chain')
View
@@ -84,10 +84,7 @@ def __init__(self, name, sol_file_path):
# set in deploy
self.address = None
self.instance = None
# TODO : account creation on saffron init
self.defaulAccount = '0xabaa886e5c11c54e76d250efd70143fe0f959530'
# TODO : unlock ^
# self.web3.personal.unlockAccount(self.defaulAccount, 'password');
self.defaulAccount = None
def __str__(self):
return 'Contract {}, {}'.format(self.address if self.address else 'None', self.name if self.name else 'None')
@@ -109,7 +106,7 @@ def deploy(self, cwd=False):
self.defaultAccount = okay.listAccounts[int(input(options))]
result = okay.unlockAccount(self.defaultAccount, getpass.getpass('\nPassword:'), 5000)
if result:
self.address = self.web3.eth.sendTransaction(transaction={'data' : '0x' + self.bytecode, 'from': self.defaulAccount, 'gaslimit': 30000})
self.address = self.web3.eth.sendTransaction(transaction={'data' : '0x' + self.bytecode, 'from': self.defaultAccount, 'gaslimit': 30000})
self.instance = self.web3.eth.contract(self.address)
else:
raise Exepction('unable to unlock account')
View
@@ -5,35 +5,19 @@
import web3
from saffron import database
from saffron.settings import lamden_home
from saffron.settings import lamden_home, project_genesis
import subprocess
from saffron.utils import create_genesis_block, initialize_chain, create_account, GENESIS_BLOCK_TEMPLATE, generate_process_string
class MemoizedChain:
class __Chain:
def __init__(self, project_dir=None, genesis_block_payload=None, genesis_block_path='genesis.json', cwd=True):
database.connection = sqlite3.connect(os.path.join(os.getcwd(), 'directory.db')) if cwd else sqlite3.connect(lamden_db_file)
database.cursor = database.connection.cursor()
def __init__(self, project_dir=None, genesis_block_payload=None, genesis_block_path=project_genesis, cwd=True):
self.genesis_block_path = genesis_block_path
self.database = database
# initialize chain if it doesn't exist already
try:
open(os.path.join(os.environ['LAMDEN_FOLDER_PATH'], genesis_block_path), 'r')
except:
assert genesis_block_payload, 'No payload given'
# if genesis_block_payload == None:
# genesis_block_payload = GENESIS_BLOCK_TEMPLATE
create_genesis_block(genesis_block_payload)
initialize_chain(self.project_dir, genesis_block_path)
create_account('password')
def start(self):
GETH = subprocess.check_output(['which','geth'])
#pid = os.spawnlp(os.P_NOWAITO, GETH.strip(), 'geth','--datadir',self.project_dir, '--etherbase','0', '&')
geth_string = generate_process_string()
print(geth_string)
proc = subprocess.Popen(['nohup', GETH.strip()] + geth_string.split())
View
@@ -1,5 +1,7 @@
import os, configparser
from os.path import join
import subprocess
run_location, filename = os.path.split(os.path.abspath(__file__))
config = configparser.ConfigParser()
@@ -10,8 +12,27 @@
PASSWORD_FILE_NAME = '.pass'
PROCESS_FILE_NAME = '.pid'
GENESIS_FILE_NAME = 'genesis.json'
project_genesis = os.path.join(lamden_folder_path, 'genesis.json')
genesis_fn = 'genesis.json'
node_fn = 'node.info'
node_info_json = lambda project_name: os.path.join(os.path.join(lamden_home, project_name), node_fn)
project_genesis = lambda project_name: os.path.join(os.path.join(lamden_home, project_name), genesis_fn)
env_source = lambda project_name: os.path.join(os.path.join(lamden_home, project_name), '{}.source'.format(project_name))
chain_pid = os.path.join(lamden_folder_path, 'chain.pid')
BASH_BIN = subprocess.check_output(['which','bash']).decode('utf-8')
GETH_BIN = subprocess.check_output(['which','geth']).decode('utf-8')
src_string = '''#! /bin/bash
export LAMDEN_HOME='{LAMDEN_HOME}'
export LAMDEN_FOLDER_PATH='{LAMDEN_FOLDER_PATH}'
export LAMDEN_DB_FILE='{LAMDEN_DB_FILE}'
export PROJECT_GENESIS='{PROJECT_GENESIS}'
export NODE_INFO_JSON='{NODE_INFO_JSON}'
'''.format
try:
os.makedirs(lamden_folder_path)
View
@@ -6,7 +6,13 @@
import time
from threading import Thread
import re
from saffron import settings
from saffron.settings import (lamden_home,
lamden_folder_path,
lamden_db_file,
project_genesis,
GETH_BIN,
genesis_fn,
node_info_json)
#from saffron.genesis import Chain
import getpass
import configparser
@@ -21,9 +27,9 @@
},
'alloc' : {},
'coinbase' : '0x0000000000000000000000000000000000000000',
'difficulty' : '0x0',
'difficulty' : '2100000',
'extraData' : '',
'gasLimit' : '0x0',
'gasLimit' : '0x8000000',
'nonce' : '0x0000000000000000',
'mixhash' : '0x0000000000000000000000000000000000000000000000000000000000000000',
'parentHash' : '0x0000000000000000000000000000000000000000000000000000000000000000',
@@ -68,7 +74,9 @@ def generate_hex_string(length):
string += hex(random.randint(0, 16))[-1]
return string
def create_genesis_block(genesisBlockPayload):
def create_genesis_block(genesisBlockPayload=None):
''' places genesis json into os.environ['LAMDEN_FOLDER_PATH']
'''
assert all(x in \
['config',
'alloc',
@@ -88,11 +96,12 @@ def create_genesis_block(genesisBlockPayload):
'eip155Block',
'eip158Block'] \
for x in list(genesisBlockPayload['config'].keys()))
with open(os.path.join(settings.lamden_folder_path, 'genesis.json'), 'w') as fp:
with open(os.path.join(os.environ['LAMDEN_FOLDER_PATH'], 'genesis.json'), 'w') as fp:
json.dump(genesisBlockPayload, fp)
def create_node_info(nodeInfoPayload):
def create_node_info(nodeInfoPayload=None):
''' places node info json into os.environ['LAMDEN_FOLDER_PATH']
'''
assert all(x in \
['identity',
'rpc',
@@ -105,15 +114,19 @@ def create_node_info(nodeInfoPayload):
'autodag',
'networkid'] \
for x in list(nodeInfoPayload.keys()))
with open(os.path.join(settings.lamden_folder_path, 'node.info'), 'w') as fp:
with open(os.path.join(os.environ['LAMDEN_FOLDER_PATH'], 'node.info'), 'w') as fp:
json.dump(nodeInfoPayload, fp)
def initialize_chain(project_dir, genesisBlockFp):
#Chain(project_dir=settings.lamden_folder_path, genesis_block_path=os.path.join(settings.lamden_folder_path, genesisBlockFp))
subprocess.Popen(['nohup', 'geth --datadir ' + settings.lamden_folder_path + ' init ' + os.path.join(settings.lamden_folder_path, genesisBlockFp)], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
cmd = '{} --datadir {} init {}'.format(GETH_BIN, os.environ['LAMDEN_FOLDER_PATH'], os.environ['PROJECT_GENESIS'])
print(cmd)
result = subprocess.check_output(cmd.split())
print(result)
def run_generator(chain_name):
os.environ['LAMDEN_FOLDER_PATH'] = os.path.join(lamden_home, chain_name)
os.environ['PROJECT_GENESIS'] = project_genesis(chain_name)
os.environ['NODE_INFO_JSON'] = node_info_json(chain_name)
if not check_if_in_project():
# create a new chain!
# print('=== config {} ==='.format(chain_name))
@@ -156,23 +169,23 @@ def run_generator(chain_name):
genesis['config']['chainId'] = formatting(user_input)
print('Chain ID set to {}'.format(genesis['config']['chainId']))
user_input = input('Difficulty: ')
user_input = formatting(user_input)
# user_input = input('Difficulty: ')
# user_input = formatting(user_input)
if user_input > INT16:
user_input = INT16
# if user_input > INT16:
# user_input = INT16
genesis['difficulty'] = hex(user_input)
print('Difficulty set to {}'.format(genesis['difficulty']))
# genesis['difficulty'] = hex(user_input)
# print('Difficulty set to {}'.format(genesis['difficulty']))
user_input = input('Gas Limit: ')
user_input = formatting(user_input)
# user_input = input('Gas Limit: ')
# user_input = formatting(user_input)
if user_input > INT16:
user_input = INT16
# if user_input > INT16:
# user_input = INT16
genesis['gasLimit'] = hex(user_input)
print('Gas Limit set to {}'.format(genesis['gasLimit']))
# genesis['gasLimit'] = hex(user_input)
# print('Gas Limit set to {}'.format(genesis['gasLimit']))
print('\n=== Hashing Variables ===')
genesis['nonce'] = generate_hex_string(16)
@@ -194,26 +207,21 @@ def run_generator(chain_name):
user_input = input('Enter password for default account: ')
try:
print(settings.lamden_folder_path)
import pdb;pdb.set_trace()
new_chain(home_path=settings.lamden_folder_path, node_info=node_info, genesis_block=genesis, etherbase_pass=user_input)
new_chain(node_info=node_info, genesis_block=genesis, etherbase_pass=user_input)
except Exception as e:
print(e)
pass
print('Blockchain generated!')
print(generate_process_string())
# print(generate_process_string())
else:
print('Already in a project directory...')
#geth.attach(stdout=PIPE, stdin=PIPE)
# this should be added to the account class in some capacity
def create_account(password):
print(settings.lamden_folder_path)
with open(os.path.join(settings.lamden_folder_path, 'pass.temp'), 'w') as fp:
with open(os.path.join(os.environ['LAMDEN_FOLDER_PATH'], 'pass.temp'), 'w') as fp:
fp.write(password)
proc = subprocess.Popen('geth --datadir {} --password {} account new'.format(settings.lamden_folder_path, os.path.join(settings.lamden_folder_path, 'pass.temp')), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc = subprocess.Popen('geth --datadir {} --password {} account new'.format(os.environ['LAMDEN_FOLDER_PATH'], os.path.join(os.environ['LAMDEN_FOLDER_PATH'], 'pass.temp')), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
account_string = proc.stdout.read().decode('utf-8')
# return the regex account
try:
@@ -226,52 +234,36 @@ def create_account(password):
#os.remove('pass.temp')
def generate_process_string():
assert open(os.path.join(settings.lamden_folder_path, 'genesis.json')) and open(os.path.join(settings.lamden_folder_path, 'node.info')), 'Genesis and Node info are not in this directory.'
node_info = json.loads(open(os.path.join(settings.lamden_folder_path, 'node.info')).read())
#"C:\Program Files\Geth\geth.exe" --rpc --rpcaddr "0.0.0.0" --rpcport "8545" --rpccorsdomain "http://localhost:1010" --rpcapi "web3,eth --networkid 1001201 --datadir ~/ --gasprice 0 console
assert open(os.environ.get('PROJECT_GENESIS', None)), 'PROJECT_GENESIS not found in ENV'
assert open(os.environ.get('NODE_INFO_JSON', None)), 'NODE_INFO_JSON not found in ENV'
node_info = json.loads(open(os.environ['NODE_INFO_JSON']).read())
process_string = ''
process_string += ' --rpc --rpcaddr 0.0.0.0 --rpcport {} --rpccorsdomain "*"'.format(node_info['rpcport']) if node_info['rpc'] else ''
process_string += ' --datadir {}'.format(settings.lamden_folder_path)
process_string += ' --datadir {}'.format(os.environ['LAMDEN_FOLDER_PATH'])
process_string += ' --port {}'.format(node_info['port'])
process_string += ' --nodiscover' if node_info['nodiscover'] == True else ''
process_string += ' --rpcapi "{}"'.format(node_info['rpcapi'])
process_string += ' --networkid {}'.format(node_info['networkid'])
process_string += ' --gasprice 0 --mine'
return process_string
def change_home_path(home_path=None):
assert home_path != None, 'Provide a new home path.'
run_location, filename = os.path.split(os.path.abspath(__file__))
config = configparser.ConfigParser()
config.read(os.path.join(run_location, 'config/default.conf'))
settings.lamden_home = os.environ.get('LAMDEN_HOME', None) if os.environ.get('LAMDEN_HOME', None) else os.getcwd()
settings.lamden_folder_path = os.environ.get('LAMDEN_FOLDER_PATH', None) if os.environ.get('LAMDEN_FOLDER_PATH', None) else join(settings.lamden_home, home_path)
settings.lamden_db_file = os.environ.get('LAMDEN_DB_FILE', None) if os.environ.get('LAMDEN_DB_FILE', None) else join(settings.lamden_folder_path, config.defaults()['lamden_db_file'])
def new_chain(home_path=None, node_info=None, genesis_block=None, etherbase_pass=None):
def new_chain(node_info=None, genesis_block=None, etherbase_pass=None):
assert etherbase_pass != None, 'Password for Etherbase account must be provided.'
if home_path != None:
change_home_path(home_path=home_path)
if node_info == None:
node_info = NODE_INFO_TEMPLATE
if genesis_block == None:
genesis_block = GENESIS_BLOCK_TEMPLATE
try:
os.makedirs(settings.lamden_folder_path)
except:
pass
try:
os.makedirs(join(settings.lamden_folder_path, 'contracts'))
os.makedirs(join(os.environ['LAMDEN_FOLDER_PATH'], 'contracts'))
except:
pass
try:
create_genesis_block(genesis_block)
create_node_info(node_info)
initialize_chain(settings.lamden_folder_path, 'genesis.json')
create_genesis_block(genesisBlockPayload=genesis_block)
initialize_chain(os.environ['LAMDEN_FOLDER_PATH'], os.environ['PROJECT_GENESIS'])
create_account(etherbase_pass)
except Exception as e:
import traceback
print(traceback.format_exc())
raise e
View
@@ -0,0 +1,7 @@
[pytest]
env =
LAMDEN_HOME='/Users/jmunsch/.lamden'
LAMDEN_FOLDER_PATH='/Users/jmunsch/.lamden/newCoin'
LAMDEN_DB_FILE='/Users/jmunsch/.lamden/newCoin/newCoin.sqlite3'
PROJECT_GENESIS='/Users/jmunsch/.lamden/newCoin/genesis.json'
NODE_INFO_JSON='/Users/jmunsch/.lamden/newCoin/node.info'
Oops, something went wrong.

0 comments on commit 4235cd6

Please sign in to comment.