def test_handshake(): tv = test_values from devp2p.crypto import privtopub from devp2p.encryption import RemoteNode, Peer, Transport, LocalNode, RLPxSession initiator_pubkey = privtopub(tv['initiator_private_key']) initiator = LocalNode(tv['initiator_private_key']) initiator_session = RLPxSession(None) initiator_session.node = initiator.ecc responder_pubkey = privtopub(tv['receiver_private_key']) responder = LocalNode(tv['receiver_private_key']) responder_session = RLPxSession(None) responder_session.node = responder.ecc # test encryption _enc = initiator_session.encrypt_auth_message(tv['auth_plaintext'], responder_pubkey) assert len(_enc) == len(tv['auth_ciphertext']) assert len(tv['auth_ciphertext']) == 113 + len(tv['auth_plaintext']) # len # test auth_msg plain auth_msg = initiator_session.create_auth_message( remote_pubkey=responder_pubkey, token=None, ephemeral_privkey=tv['initiator_ephemeral_private_key'], nonce=tv['initiator_nonce']) # test auth_msg plain assert len(auth_msg) == len(tv['auth_plaintext']) == 194 assert auth_msg[65:] == tv['auth_plaintext'][ 65:] # starts with non deterministic k _auth_msg_cipher = initiator_session.encrypt_auth_message( auth_msg, responder_pubkey) # test shared responder_session.node.get_ecdh_key(initiator_pubkey) == \ initiator_session.node.get_ecdh_key(responder_pubkey) # test decrypt assert auth_msg == responder_session.node.ecies_decrypt(_auth_msg_cipher) # check receive responder_ephemeral_pubkey = privtopub( tv['receiver_ephemeral_private_key']) auth_msg_cipher = tv['auth_ciphertext'] auth_msg = responder_session.node.ecies_decrypt(auth_msg_cipher) assert auth_msg[65:] == tv['auth_plaintext'][ 65:] # starts with non deterministic k res = responder_session.receive_authentication(auth_msg_cipher) auth_ack_msg = responder_session.create_auth_ack_message( responder_ephemeral_pubkey, tv['receiver_nonce'], res['token_found']) assert auth_ack_msg == tv['authresp_plaintext'] auth_ack_msg_cipher = responder_session.encrypt_auth_ack_message( auth_ack_msg, res['remote_pubkey'])
def test_go_sig(): """ go client started with: ethereum -port="40404" -loglevel=5 -nodekeyhex="9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658" -bootnodes="enode://2da47499d52d9161a778e4c711e22e8651cb90350ec066452f9516d1d11eb465d1ec42bb27ec6cd4488b8b6a1a411cb5ef83c16cbb8bee194624bb65fef0f7fd@127.0.0.1:30303" """ r_pubkey = "ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba171".decode( 'hex') d = { 'signed_data': 'a061e5b799b5bb3a3a68a7eab6ee11207d90672e796510ac455e985bd206e240', 'cmd': 'find_node', 'body': '03f847b840ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba1718454e869b1', 'signature': '0de032c62e30f4a9f9f07f25ac5377c5a531116147617a6c08f946c97991f351577e53ae138210bdb7447bab53f3398d746d42c64a9ce67a6248e59353f1bc6e01' } priv_seed = 'test' priv_key = mk_privkey(priv_seed) assert priv_key == "9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658".decode( 'hex') my_pubkey = privtopub(priv_key) assert my_pubkey == r_pubkey, (my_pubkey, r_pubkey) go_body = d['body'].decode('hex') # cmd_id, rlp.encoded import rlp target_node_id, expiry = rlp.decode(go_body[1:]) assert target_node_id == r_pubkey # lookup for itself go_signed_data = d['signed_data'].decode('hex') go_signature = d['signature'].decode('hex') b_signature = bitcoin.ecdsa_sign(go_signed_data, priv_key) # base64 encoded! # https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/main.py#L500 my_signature = ecdsa_sign(go_signed_data, priv_key) assert my_signature == ecdsa_sign(go_signed_data, priv_key) # deterministic k assert len(go_signed_data) == 32 # sha3() assert len(go_signature) == 65 assert len(my_signature) == 65 # length is okay try: assert my_signature == go_signature failed = False except: "expected fail, go signatures are not generated with deterministic k" failed = True pass assert failed # decoding works when we signed it assert my_pubkey == ecdsa_recover(go_signed_data, my_signature) # problem we can not decode the pubkey from the go signature # and go can not decode ours ecdsa_recover(go_signed_data, go_signature)
def get_connected_apps(): a_config = dict(p2p=dict(listen_host='127.0.0.1', listen_port=3000), node=dict(privkey_hex=crypto.sha3('a').encode('hex'))) b_config = copy.deepcopy(a_config) b_config['p2p']['listen_port'] = 3001 b_config['node']['privkey_hex'] = crypto.sha3('b').encode('hex') a_app = BaseApp(a_config) peermanager.PeerManager.register_with_app(a_app) a_app.start() b_app = BaseApp(b_config) peermanager.PeerManager.register_with_app(b_app) b_app.start() a_peermgr = a_app.services.peermanager b_peermgr = b_app.services.peermanager # connect host = b_config['p2p']['listen_host'] port = b_config['p2p']['listen_port'] pubkey = crypto.privtopub(b_config['node']['privkey_hex'].decode('hex')) a_peermgr.connect((host, port), remote_pubkey=pubkey) return a_app, b_app
def get_connected_apps(): a_config = dict(p2p=dict(listen_host='127.0.0.1', listen_port=3005), node=dict(privkey_hex=encode_hex(crypto.sha3(b'a')))) b_config = copy.deepcopy(a_config) b_config['p2p']['listen_port'] = 3006 b_config['node']['privkey_hex'] = encode_hex(crypto.sha3(b'b')) a_app = BaseApp(a_config) peermanager.PeerManager.register_with_app(a_app) a_app.start() b_app = BaseApp(b_config) peermanager.PeerManager.register_with_app(b_app) b_app.start() a_peermgr = a_app.services.peermanager b_peermgr = b_app.services.peermanager # connect host = b_config['p2p']['listen_host'] port = b_config['p2p']['listen_port'] pubkey = crypto.privtopub(decode_hex(b_config['node']['privkey_hex'])) a_peermgr.connect((host, port), remote_pubkey=pubkey) return a_app, b_app
class Faucet(object): PRIVKEY = "{:32}".format("Golem Faucet") assert len(PRIVKEY) == 32 PUBKEY = privtopub(PRIVKEY) ADDR = privtoaddr(PRIVKEY) @staticmethod def gimme_money(ethnode, addr, value): nonce = ethnode.get_transaction_count(Faucet.ADDR.encode('hex')) addr = normalize_address(addr) tx = Transaction(nonce, 1, 21000, addr, value, '') tx.sign(Faucet.PRIVKEY) h = ethnode.send(tx) log.info("Faucet --({} ETH)--> {} ({})".format(float(value) / 10**18, addr.encode('hex'), h)) h = h[2:].decode('hex') assert h == tx.hash return h @staticmethod def deploy_contract(ethnode, init_code): nonce = ethnode.get_transaction_count(Faucet.ADDR.encode('hex')) tx = Transaction(nonce, 0, 3141592, to='', value=0, data=init_code) tx.sign(Faucet.PRIVKEY) ethnode.send(tx) return tx.creates
def start(self, rpc, mining=False, nodekey=None, port=None): if self.__ps: return assert not self.rpcport program = find_program('geth') assert program # TODO: Replace with a nice exception # Data dir must be set the class user to allow multiple nodes running basedir = path.dirname(__file__) genesis_file = path.join(basedir, 'genesis_golem.json') if not port: port = find_free_net_port() self.port = port args = [ program, '--datadir', self.datadir, '--networkid', '9', '--port', str(self.port), '--genesis', genesis_file, '--nodiscover', '--ipcdisable', # Disable IPC transport - conflicts on Windows. '--gasprice', '0', '--verbosity', '3', ] if rpc: self.rpcport = find_free_net_port() args += [ '--rpc', '--rpcport', str(self.rpcport) ] if nodekey: self.pubkey = privtopub(nodekey) args += [ '--nodekeyhex', nodekey.encode('hex'), ] if mining: mining_script = path.join(basedir, 'mine_pending_transactions.js') args += [ '--etherbase', Faucet.ADDR.encode('hex'), 'js', mining_script, ] self.__ps = psutil.Popen(args) atexit.register(lambda: self.stop()) WAIT_PERIOD = 0.01 wait_time = 0 while True: # FIXME: Add timeout limit, we don't want to loop here forever. time.sleep(WAIT_PERIOD) wait_time += WAIT_PERIOD if not self.rpcport: break if self.rpcport in set(c.laddr[1] for c in self.__ps.connections('tcp')): break log.info("Node started in {} s: `{}`".format(wait_time, " ".join(args)))
def __init__(self, app, transport): self.app = app self.transport = transport self.privkey = app.config['p2p']['privkey_hex'].decode('hex') self.pubkey = crypto.privtopub(self.privkey) self.nodes = dict() # nodeid->Node, fixme should be loaded this_node = Node(self.pubkey, self.transport.address) self.kademlia = KademliaProtocolAdapter(this_node, wire=self)
def test_pyelliptic_sig(): priv_seed = 'test' priv_key = mk_privkey(priv_seed) my_pubkey = privtopub(priv_key) e = ECCx(my_pubkey, priv_key) msg = 'a' s = pyelliptic.ECC.sign(e, msg) assert s == pyelliptic.ECC.sign(e, msg) # deterministic
def test_privtopub(): kenc = fromHex( "0x472413e97f1fd58d84e28a559479e6b6902d2e8a0cee672ef38a3a35d263886b") penc = fromHex( "0x7a2aa2951282279dc1171549a7112b07c38c0d97c0fe2c0ae6c4588ba15be74a04efc4f7da443f6d61f68a9279bc82b73e0cc8d090048e9f87e838ae65dd8d4c" ) assert (penc == crypto.privtopub(kenc)) return kenc, penc
def test_pyelliptic_sig(): priv_seed = 'test' priv_key = mk_privkey(priv_seed) my_pubkey = privtopub(priv_key) e = ECCx(raw_privkey=priv_key) msg = 'a' s = pyelliptic.ECC.sign(e, msg) s2 = pyelliptic.ECC.sign(e, msg) assert s != s2 # non deterministic
def __init__(self, app, transport): self.app = app self.transport = transport self.privkey = app.config['node']['privkey_hex'].decode('hex') self.pubkey = crypto.privtopub(self.privkey) self.nodes = dict() # nodeid->Node, fixme should be loaded self.this_node = Node(self.pubkey, self.transport.address) self.kademlia = KademliaProtocolAdapter(self.this_node, wire=self) uri = utils.host_port_pubkey_to_uri(self.app.config['discovery']['listen_host'], self.app.config['discovery']['listen_port'], self.pubkey) log.info('starting discovery proto', enode=uri) # FIXME external ip
def __init__(self, app, transport): self.app = app self.transport = transport self.privkey = app.config['node']['privkey_hex'].decode('hex') self.pubkey = crypto.privtopub(self.privkey) self.nodes = dict() # nodeid->Node, fixme should be loaded self.this_node = Node(self.pubkey, self.transport.address) self.kademlia = KademliaProtocolAdapter(self.this_node, wire=self) this_enode = utils.host_port_pubkey_to_uri( self.app.config['discovery']['listen_host'], self.app.config['discovery']['listen_port'], self.pubkey) log.info('starting discovery proto', this_enode=this_enode)
def __init__(self, app): log.info('PeerManager init') WiredService.__init__(self, app) self.peers = [] self.errors = PeerErrors() if self.config['log_disconnects'] else PeerErrorsBase() # setup nodeid based on privkey if 'id' not in self.config['p2p']: self.config['node']['id'] = crypto.privtopub( decode_hex(self.config['node']['privkey_hex'])) self.listen_addr = (self.config['p2p']['listen_host'], self.config['p2p']['listen_port']) self.server = StreamServer(self.listen_addr, handle=self._on_new_connection)
def test_go_sig(): """ go client started with: ethereum -port="40404" -loglevel=5 -nodekeyhex="9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658" -bootnodes="enode://2da47499d52d9161a778e4c711e22e8651cb90350ec066452f9516d1d11eb465d1ec42bb27ec6cd4488b8b6a1a411cb5ef83c16cbb8bee194624bb65fef0f7fd@127.0.0.1:30303" """ r_pubkey = "ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba171".decode( 'hex') d = {'signed_data': 'a061e5b799b5bb3a3a68a7eab6ee11207d90672e796510ac455e985bd206e240', 'cmd': 'find_node', 'body': '03f847b840ab16b8c7fc1febb74ceedf1349944ffd4a04d11802451d02e808f08cb3b0c1c1a9c4e1efb7d309a762baa4c9c8da08890b3b712d1666b5b630d6c6a09cbba1718454e869b1', 'signature': '0de032c62e30f4a9f9f07f25ac5377c5a531116147617a6c08f946c97991f351577e53ae138210bdb7447bab53f3398d746d42c64a9ce67a6248e59353f1bc6e01'} priv_seed = 'test' priv_key = mk_privkey(priv_seed) assert priv_key == "9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658".decode( 'hex') my_pubkey = privtopub(priv_key) assert my_pubkey == r_pubkey, (my_pubkey, r_pubkey) go_body = d['body'].decode('hex') # cmd_id, rlp.encoded import rlp target_node_id, expiry = rlp.decode(go_body[1:]) assert target_node_id == r_pubkey # lookup for itself go_signed_data = d['signed_data'].decode('hex') go_signature = d['signature'].decode('hex') my_signature = ecdsa_sign(go_signed_data, priv_key) assert my_signature == ecdsa_sign(go_signed_data, priv_key) # deterministic k assert len(go_signed_data) == 32 # sha3() assert len(go_signature) == 65 assert len(my_signature) == 65 # length is okay try: assert my_signature == go_signature failed = False except: "expected fail, go signatures are not generated with deterministic k" failed = True pass assert failed # decoding works when we signed it assert my_pubkey == ecdsa_recover(go_signed_data, my_signature) # problem we can not decode the pubkey from the go signature # and go can not decode ours ecdsa_recover(go_signed_data, go_signature)
class BaseApp(object): client_name = 'pyethcrawler' client_version = '0.1/%s/%s' % (sys.platform, 'py%d.%d.%d' % sys.version_info[:3]) client_version_string = '%s/v%s' % (client_name, client_version) start_console = False default_config = {} default_config['client_version_string'] = client_version_string default_config['result_dir'] = '' default_config['prev_routing_table'] = '/results/routing-table_170109-084715.csv' default_config['prev_peers'] = '' # default_config['p2p'] = dict(bootstrap_nodes=[],listen_port=30304,listen_host='0.0.0.0') privkey_hex = 'b3b9736ba5e4b9d0f85231291316c7fd82bde4ae80bb7ca98175cf6d11c0c4eb' pubkey = crypto.privtopub(privkey_hex.decode('hex')) default_config['node'] = dict(privkey_hex=privkey_hex, id=crypto.sha3(pubkey)) def __init__(self, config=default_config): self.config = utils.update_config_with_defaults(config, self.default_config) self.services = IterableUserDict() def register_service(self, service): """ registeres protocol with app, which will be accessible as app.services.<protocol.name> (e.g. app.services.p2p or app.services.eth) """ assert isinstance(service, BaseService) assert service.name not in self.services log.info('registering service', service=service.name) self.services[service.name] = service setattr(self.services, service.name, service) def deregister_service(self, service): assert isinstance(service, BaseService) self.services.remove(service) delattr(self.services, service.name) def start(self): for service in self.services.values(): service.start() def stop(self): for service in self.services.values(): service.stop() def join(self): for service in self.services.values(): service.join()
class MockPeerManager(peermanager.PeerManager): privkey = crypto.sha3(b'a') pubkey = crypto.privtopub(privkey) wired_services = services config = { 'client_version_string': b'mock', 'p2p': { 'listen_port': 3006 }, 'node': { 'privkey_hex': encode_hex(privkey), 'id': encode_hex(pubkey), } } def __init__(self): pass
def _discovery_loop(self): log.info('waiting for bootstrap') gevent.sleep(self.discovery_delay) while not self.is_stopped: try: num_peers, min_peers = self.num_peers( ), self.config['p2p']['min_peers'] kademlia_proto = self.app.services.discovery.protocol.kademlia if num_peers < min_peers: log.debug('missing peers', num_peers=num_peers, min_peers=min_peers, known=len(kademlia_proto.routing)) nodeid = kademlia.random_nodeid() kademlia_proto.find_node(nodeid) # fixme, should be a task gevent.sleep(self.discovery_delay) # wait for results neighbours = kademlia_proto.routing.neighbours(nodeid, 2) if not neighbours: gevent.sleep(self.connect_loop_delay) continue node = random.choice(neighbours) if node.pubkey in self.remote_pubkeys(): gevent.sleep(self.discovery_delay) continue log.debug('connecting random', node=node) local_pubkey = crypto.privtopub( decode_hex(self.config['node']['privkey_hex'])) if node.pubkey == local_pubkey: continue if node.pubkey in [p.remote_pubkey for p in self.peers]: continue self.connect((node.address.ip, node.address.tcp_port), node.pubkey) except AttributeError: # TODO: Is this the correct thing to do here? log.error("Discovery service not available.") break except Exception as e: log.error("discovery failed", error=e, num_peers=num_peers, min_peers=min_peers) gevent.sleep(self.connect_loop_delay) evt = gevent.event.Event() evt.wait()
def __init__(self, app): log.info('PeerManager init') WiredService.__init__(self, app) self.peers = [] self.errors = PeerErrors( ) if self.config['log_disconnects'] else PeerErrorsBase() self.result_dir = self.config["result_dir"] if self.config[ "result_dir"] != "" else self.result_dir self.prev_routing_table = self.config[ "prev_routing_table"] if self.config[ "prev_routing_table"] != "" else self.prev_routing_table self.prev_peers = self.config["prev_peers"] if self.config[ "prev_peers"] != "" else self.prev_peers # setup nodeid based on privkey print self.config if 'id' not in self.config['p2p']: self.config['node']['id'] = crypto.privtopub( self.config['node']['privkey_hex'].decode('hex')) self.listen_addr = (self.config['p2p']['listen_host'], self.config['p2p']['listen_port'])
def geth_create_blockchain(private_keys, geth_private_keys, p2p_base_port, base_datadir, verbosity): # pylint: disable=too-many-locals,too-many-statements # TODO: handle better the errors cases: # - cant bind, port in use start_rpcport = 4000 account_addresses = [ privatekey_to_address(key) for key in set(private_keys) ] alloc = { address_encoder(address): { 'balance': DEFAULT_BALANCE_BIN, } for address in account_addresses } genesis = { 'config': { 'homesteadBlock': 0, }, 'nonce': '0x0000000000000042', 'mixhash': '0x0000000000000000000000000000000000000000000000000000000000000000', 'difficulty': '0x40', 'coinbase': '0x0000000000000000000000000000000000000000', 'timestamp': '0x00', 'parentHash': '0x0000000000000000000000000000000000000000000000000000000000000000', 'extraData': 'raiden', 'gasLimit': GAS_LIMIT_HEX, 'alloc': alloc, } nodes_configuration = [] for pos, key in enumerate(geth_private_keys): config = dict() # make the first node miner if pos == 0: config['minerthreads'] = 1 # conservative config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = privatekey_to_address(key) config['port'] = p2p_base_port + pos config['rpcport'] = start_rpcport + pos config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) nodes_configuration.append(config) cmds = [] for i, config in enumerate(nodes_configuration): nodedir = os.path.join(base_datadir, config['nodekeyhex']) os.makedirs(nodedir) geth_init_datadir(genesis, nodedir) if 'minerthreads' in config: geth_create_account(nodedir, private_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) processes_list = [] for cmd in cmds: if '--unlock' in cmd: process = subprocess.Popen(cmd, universal_newlines=True, stdin=subprocess.PIPE) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen(cmd) processes_list.append(process) assert process.returncode is None geth_wait_and_check(private_keys) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
def test_privtopub(): priv = crypto.mk_privkey('test') pub = crypto.privtopub(priv) pub2 = crypto.ECCx(raw_privkey=priv).raw_pubkey assert pub == pub2
def test_privtopub(): priv = crypto.mk_privkey(b'test') pub = crypto.privtopub(priv) pub2 = crypto.ECCx(raw_privkey=priv).raw_pubkey assert pub == pub2
def test_handshake(): tv = test_values initiator = RLPxSession(ECCx(raw_privkey=tv['initiator_private_key']), is_initiator=True, ephemeral_privkey=tv['initiator_ephemeral_private_key']) initiator_pubkey = initiator.ecc.raw_pubkey responder = RLPxSession(ECCx(raw_privkey=tv['receiver_private_key']), ephemeral_privkey=tv['receiver_ephemeral_private_key']) responder_pubkey = responder.ecc.raw_pubkey # test encryption _enc = initiator.encrypt_auth_message(tv['auth_plaintext'], responder_pubkey) assert len(_enc) == len(tv['auth_ciphertext']) assert len(tv['auth_ciphertext']) == 113 + len(tv['auth_plaintext']) # len # test auth_msg plain auth_msg = initiator.create_auth_message(remote_pubkey=responder_pubkey, ephemeral_privkey=tv[ 'initiator_ephemeral_private_key'], nonce=tv['initiator_nonce']) # test auth_msg plain assert len(auth_msg) == len(tv['auth_plaintext']) == 194 assert auth_msg[65:] == tv['auth_plaintext'][65:] # starts with non deterministic k _auth_msg_cipher = initiator.encrypt_auth_message(auth_msg, responder_pubkey) # test shared responder.ecc.get_ecdh_key(initiator_pubkey) == \ initiator.ecc.get_ecdh_key(responder_pubkey) # test decrypt assert auth_msg == responder.ecc.ecies_decrypt(_auth_msg_cipher) # check receive responder_ephemeral_pubkey = privtopub(tv['receiver_ephemeral_private_key']) auth_msg_cipher = tv['auth_ciphertext'] auth_msg = responder.ecc.ecies_decrypt(auth_msg_cipher) assert auth_msg[65:] == tv['auth_plaintext'][65:] # starts with non deterministic k responder.decode_authentication(auth_msg_cipher) auth_ack_msg = responder.create_auth_ack_message(responder_ephemeral_pubkey, tv['receiver_nonce'], responder.remote_token_found ) assert auth_ack_msg == tv['authresp_plaintext'] auth_ack_msg_cipher = responder.encrypt_auth_ack_message(auth_ack_msg, responder.remote_pubkey) # set auth ack msg cipher (needed later for mac calculation) responder.auth_ack = tv['authresp_ciphertext'] responder.setup_cipher() assert responder.ecdhe_shared_secret == tv['ecdhe_shared_secret'] assert len(responder.token) == len(tv['token']) assert responder.token == tv['token'] assert responder.aes_secret == tv['aes_secret'] assert responder.mac_secret == tv['mac_secret'] assert responder.initiator_nonce == tv['initiator_nonce'] assert responder.responder_nonce == tv['receiver_nonce'] assert responder.auth_init == tv['auth_ciphertext'] assert responder.auth_ack == tv['authresp_ciphertext'] # test values are from initiator perspective? assert responder.ingress_mac.digest() == tv['initial_egress_MAC'] assert responder.ingress_mac.digest() == tv['initial_egress_MAC'] assert responder.egress_mac.digest() == tv['initial_ingress_MAC'] assert responder.egress_mac.digest() == tv['initial_ingress_MAC'] r = responder.decrypt(tv['initiator_hello_packet']) # unpack hello packet import struct import rlp import rlp.sedes as sedes from rlp.codec import consume_item header = r['header'] frame_length = struct.unpack('>I', '\x00' + header[:3])[0] header_sedes = sedes.List([sedes.big_endian_int, sedes.big_endian_int]) header_data = rlp.decode(header[3:], strict=False, sedes=header_sedes) print 'header', repr(header_data) # frame frame = r['frame'] # normal: rlp(packet-type) [|| rlp(packet-data)] || padding packet_type, end = consume_item(frame, start=0) packet_type = rlp.decode(frame, sedes=sedes.big_endian_int, strict=False) print 'packet_type', repr(packet_type) # decode hello body _sedes_capabilites_tuple = sedes.List([sedes.binary, sedes.big_endian_int]) structure = [ ('version', sedes.big_endian_int), ('client_version', sedes.big_endian_int), ('capabilities', sedes.CountableList(_sedes_capabilites_tuple)), ('listen_port', sedes.big_endian_int), ('nodeid', sedes.binary) ] hello_sedes = sedes.List([x[1] for x in structure]) frame_data = rlp.decode(frame[end:], sedes=hello_sedes) frame_data = dict((structure[i][0], x) for i, x in enumerate(frame_data)) print 'frame', frame_data
def test_privtopub(): kenc = fromHex("0x472413e97f1fd58d84e28a559479e6b6902d2e8a0cee672ef38a3a35d263886b") penc = fromHex( "0x7a2aa2951282279dc1171549a7112b07c38c0d97c0fe2c0ae6c4588ba15be74a04efc4f7da443f6d61f68a9279bc82b73e0cc8d090048e9f87e838ae65dd8d4c") assert(penc == crypto.privtopub(kenc)) return kenc, penc
def geth_create_blockchain(deploy_key, private_keys, blockchain_private_keys, rpc_ports, p2p_ports, base_datadir, verbosity, genesis_path=None, logdirectory=None): # pylint: disable=too-many-locals,too-many-statements,too-many-arguments # the smallest DAG, the one for the first epoch should be a bit over 1GB, # since the DAG is used during proof of work and the file is mmaped from # disk, there must be more than 1GB of memory freely available to avoid # memory paging, otherwise the proof-of-work will be extremely slow # increasing the flakiness of the tests. memory = psutil.virtual_memory() if memory.available < DAGSIZE * 1.5: raise RuntimeError('To properly run the tests with a geth miner ' 'at least 1.5 GB of available memory is required.') nodes_configuration = [] key_p2p_rpc = zip(blockchain_private_keys, p2p_ports, rpc_ports) for pos, (key, p2p_port, rpc_port) in enumerate(key_p2p_rpc): config = dict() # make the first node miner if pos == 0: config['minerthreads'] = 1 # conservative config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = privatekey_to_address(key) config['port'] = p2p_port config['rpcport'] = rpc_port config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) nodes_configuration.append(config) for config in nodes_configuration: config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) all_keys = list(private_keys) all_keys.append( deploy_key) # needs to be at the end because of the minerthreads keys cmds = [] for i, config in enumerate(nodes_configuration): # HACK: Use only the first 8 characters to avoid golang's issue # https://github.com/golang/go/issues/6895 (IPC bind fails with path # longer than 108 characters). nodekey_part = config['nodekeyhex'][:8] nodedir = os.path.join(base_datadir, nodekey_part) node_genesis_path = os.path.join(nodedir, 'custom_genesis.json') assert len(nodedir + '/geth.ipc') < 108, 'geth data path is too large' os.makedirs(nodedir) if genesis_path is None: geth_bare_genesis(node_genesis_path, all_keys) else: shutil.copy(genesis_path, node_genesis_path) geth_init_datadir(nodedir, node_genesis_path) if 'minerthreads' in config: geth_create_account(nodedir, private_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) stdout = None stderr = None processes_list = [] for pos, cmd in enumerate(cmds): if logdirectory: log_path = os.path.join(logdirectory, str(pos)) logfile = open(log_path, 'w') stdout = logfile stderr = logfile if '--unlock' in cmd: process = subprocess.Popen( cmd, universal_newlines=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, ) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen( cmd, universal_newlines=True, stdout=stdout, stderr=stderr, ) processes_list.append(process) assert process.returncode is None geth_wait_and_check(private_keys, rpc_ports) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
def create_geth_cluster(private_keys, geth_private_keys, p2p_base_port, base_datadir): # pylint: disable=too-many-locals,too-many-statements # TODO: handle better the errors cases: # - cant bind, port in use start_rpcport = 4000 account_addresses = [ privtoaddr(key) for key in set(private_keys) ] alloc = { address_encoder(address): { 'balance': DEFAULT_BALANCE, } for address in account_addresses } genesis = { 'config': { 'homesteadBlock': 0, }, 'nonce': '0x0000000000000042', 'mixhash': '0x0000000000000000000000000000000000000000000000000000000000000000', 'difficulty': '0x40', 'coinbase': '0x0000000000000000000000000000000000000000', 'timestamp': '0x00', 'parentHash': '0x0000000000000000000000000000000000000000000000000000000000000000', 'extraData': 'raiden', 'gasLimit': GAS_LIMIT_HEX, 'alloc': alloc, } nodes_configuration = [] for pos, key in enumerate(geth_private_keys): config = dict() # make the first node miner if pos == 0: config['minerthreads'] = 1 # conservative config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = privtoaddr(key) config['port'] = p2p_base_port + pos config['rpcport'] = start_rpcport + pos config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) nodes_configuration.append(config) cmds = [] for i, config in enumerate(nodes_configuration): nodedir = os.path.join(base_datadir, config['nodekeyhex']) os.makedirs(nodedir) geth_init_datadir(genesis, nodedir) if 'minerthreads' in config: geth_create_account(nodedir, private_keys[i]) cmds.append(geth_to_cmd(config, nodedir)) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) processes_list = [] for cmd in cmds: if '--unlock' in cmd: process = subprocess.Popen(cmd, universal_newlines=True, stdin=subprocess.PIPE) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen(cmd) processes_list.append(process) assert process.returncode is None geth_wait_and_check(private_keys) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
def test_handshake(): tv = test_values initiator = RLPxSession(ECCx(raw_privkey=tv['initiator_private_key']), is_initiator=True, ephemeral_privkey=tv['initiator_ephemeral_private_key']) initiator_pubkey = initiator.ecc.raw_pubkey responder = RLPxSession(ECCx(raw_privkey=tv['receiver_private_key']), ephemeral_privkey=tv['receiver_ephemeral_private_key']) responder_pubkey = responder.ecc.raw_pubkey # test encryption _enc = initiator.encrypt_auth_message(tv['auth_plaintext'], responder_pubkey) assert len(_enc) == len(tv['auth_ciphertext']) assert len(tv['auth_ciphertext']) == 113 + len(tv['auth_plaintext']) # len # test auth_msg plain auth_msg = initiator.create_auth_message(remote_pubkey=responder_pubkey, ephemeral_privkey=tv['initiator_ephemeral_private_key'], nonce=tv['initiator_nonce']) # test auth_msg plain assert len(auth_msg) == len(tv['auth_plaintext']) == 194 assert auth_msg[65:] == tv['auth_plaintext'][65:] # starts with non deterministic k _auth_msg_cipher = initiator.encrypt_auth_message(auth_msg, responder_pubkey) # test shared responder.ecc.get_ecdh_key(initiator_pubkey) == \ initiator.ecc.get_ecdh_key(responder_pubkey) # test decrypt assert auth_msg == responder.ecc.ecies_decrypt(_auth_msg_cipher) # check receive responder_ephemeral_pubkey = privtopub(tv['receiver_ephemeral_private_key']) auth_msg_cipher = tv['auth_ciphertext'] auth_msg = responder.ecc.ecies_decrypt(auth_msg_cipher) assert auth_msg[65:] == tv['auth_plaintext'][65:] # starts with non deterministic k responder.decode_authentication(auth_msg_cipher) auth_ack_msg = responder.create_auth_ack_message(responder_ephemeral_pubkey, nonce=tv['receiver_nonce']) assert auth_ack_msg == tv['authresp_plaintext'] auth_ack_msg_cipher = responder.encrypt_auth_ack_message(auth_ack_msg, remote_pubkey=responder.remote_pubkey) # set auth ack msg cipher (needed later for mac calculation) responder.auth_ack = tv['authresp_ciphertext'] responder.setup_cipher() assert responder.ecdhe_shared_secret == tv['ecdhe_shared_secret'] assert len(responder.token) == len(tv['token']) assert responder.token == tv['token'] assert responder.aes_secret == tv['aes_secret'] assert responder.mac_secret == tv['mac_secret'] assert responder.initiator_nonce == tv['initiator_nonce'] assert responder.responder_nonce == tv['receiver_nonce'] assert responder.auth_init == tv['auth_ciphertext'] assert responder.auth_ack == tv['authresp_ciphertext'] # test values are from initiator perspective? assert responder.ingress_mac.digest() == tv['initial_egress_MAC'] assert responder.ingress_mac.digest() == tv['initial_egress_MAC'] assert responder.egress_mac.digest() == tv['initial_ingress_MAC'] assert responder.egress_mac.digest() == tv['initial_ingress_MAC'] r = responder.decrypt(tv['initiator_hello_packet']) # unpack hello packet import struct import rlp import rlp.sedes as sedes from rlp.codec import consume_item header = r['header'] frame_length = struct.unpack(b'>I', b'\x00' + header[:3])[0] header_sedes = sedes.List([sedes.big_endian_int, sedes.big_endian_int]) header_data = rlp.decode(header[3:], strict=False, sedes=header_sedes) print('header', repr(header_data)) # frame frame = r['frame'] # normal: rlp(packet-type) [|| rlp(packet-data)] || padding packet_type, end = consume_item(frame, start=0) packet_type = rlp.decode(frame, sedes=sedes.big_endian_int, strict=False) print('packet_type', repr(packet_type)) # decode hello body _sedes_capabilites_tuple = sedes.List([sedes.binary, sedes.big_endian_int]) structure = [ ('version', sedes.big_endian_int), ('client_version_string', sedes.big_endian_int), ('capabilities', sedes.CountableList(_sedes_capabilites_tuple)), ('listen_port', sedes.big_endian_int), ('remote_pubkey', sedes.binary) ] hello_sedes = sedes.List([x[1] for x in structure]) frame_data = rlp.decode(frame[end:], sedes=hello_sedes) frame_data = dict((structure[i][0], x) for i, x in enumerate(frame_data)) print('frame', frame_data)
def test_session(): proto = P2PProtocol(peer=PeerMock(), service=WiredService(BaseApp())) hello_packet = proto.create_hello() responder_privkey = mk_privkey('secret1') responder = MultiplexedSession(responder_privkey, hello_packet=hello_packet, token_by_pubkey=dict()) p0 = 0 responder.add_protocol(p0) initiator_privkey = mk_privkey('secret2') initiator = MultiplexedSession(initiator_privkey, hello_packet=hello_packet, remote_pubkey=privtopub(responder_privkey)) initiator.add_protocol(p0) # send auth msg = initiator.message_queue.get_nowait() assert msg # auth_init assert len(msg) == RLPxSession.auth_message_ct_length assert initiator.packet_queue.empty() assert not responder.is_initiator # receive auth responder.add_message(msg) assert responder.packet_queue.empty() assert responder.is_ready # send auth ack and hello ack_msg = responder.message_queue.get_nowait() assert len(msg) >= RLPxSession.auth_ack_message_ct_length # + hello hello_msg = responder.message_queue.get_nowait() assert hello_msg # receive auth ack & hello initiator.add_message(ack_msg + hello_msg) assert initiator.is_ready hello_packet = initiator.packet_queue.get_nowait() assert isinstance(hello_packet, Packet) # initiator sends hello hello_msg = initiator.message_queue.get_nowait() assert hello_msg # hello received by responder responder.add_message(hello_msg) hello_packet = responder.packet_queue.get_nowait() assert isinstance(hello_packet, Packet) # assert we received an actual hello packet data = proto.hello.decode_payload(hello_packet.payload) assert data['version'] # test normal operation ping = proto.create_ping() initiator.add_packet(ping) msg = initiator.message_queue.get_nowait() # receive ping responder.add_message(msg) ping_packet = responder.packet_queue.get_nowait() assert isinstance(ping_packet, Packet) data = proto.ping.decode_payload(ping_packet.payload) # reply with pong pong = proto.create_ping() responder.add_packet(pong) msg = responder.message_queue.get_nowait() # receive pong initiator.add_message(msg) pong_packet = initiator.packet_queue.get_nowait() assert isinstance(pong_packet, Packet) data = proto.pong.decode_payload(pong_packet.payload)
def geth_create_blockchain( deploy_key, private_keys, geth_private_keys, rpc_ports, p2p_ports, base_datadir, verbosity, genesis_path=None ): # pylint: disable=too-many-locals,too-many-statements,too-many-arguments nodes_configuration = [] for pos, (key, p2p_port, rpc_port) in enumerate(zip(geth_private_keys, p2p_ports, rpc_ports)): config = dict() # make the first node miner if pos == 0: config["minerthreads"] = 1 # conservative config["unlock"] = 0 config["nodekey"] = key config["nodekeyhex"] = encode_hex(key) config["pub"] = encode_hex(privtopub(key)) config["address"] = privatekey_to_address(key) config["port"] = p2p_port config["rpcport"] = rpc_port config["enode"] = "enode://{pub}@127.0.0.1:{port}".format(pub=config["pub"], port=config["port"]) config["bootnodes"] = ",".join(node["enode"] for node in nodes_configuration) nodes_configuration.append(config) all_keys = list(private_keys) all_keys.append(deploy_key) # needs to be at the end because of the minerthreads keys cmds = [] for i, config in enumerate(nodes_configuration): nodedir = os.path.join(base_datadir, config["nodekeyhex"]) os.makedirs(nodedir) node_genesis_path = os.path.join(nodedir, "custom_genesis.json") if genesis_path is None: geth_bare_genesis(node_genesis_path, all_keys) else: shutil.copy(genesis_path, node_genesis_path) geth_init_datadir(nodedir, node_genesis_path) if "minerthreads" in config: geth_create_account(nodedir, private_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) processes_list = [] for cmd in cmds: if "--unlock" in cmd: process = subprocess.Popen(cmd, universal_newlines=True, stdin=subprocess.PIPE) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen(cmd) processes_list.append(process) assert process.returncode is None geth_wait_and_check(private_keys, rpc_ports) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
def geth_create_blockchain(deploy_key, deploy_client, private_keys, blockchain_private_keys, rpc_ports, p2p_ports, base_datadir, verbosity, random_marker, genesis_path=None, logdirectory=None): # pylint: disable=too-many-locals,too-many-statements,too-many-arguments,too-many-branches nodes_configuration = [] key_p2p_rpc = zip(blockchain_private_keys, p2p_ports, rpc_ports) for pos, (key, p2p_port, rpc_port) in enumerate(key_p2p_rpc): config = dict() address = privatekey_to_address(key) # make the first node miner if pos == 0: config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = address config['port'] = p2p_port config['rpcport'] = rpc_port config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) nodes_configuration.append(config) for config in nodes_configuration: config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) all_keys = set(private_keys) all_keys.add(deploy_key) all_keys = sorted(all_keys) cmds = [] for i, config in enumerate(nodes_configuration): # HACK: Use only the first 8 characters to avoid golang's issue # https://github.com/golang/go/issues/6895 (IPC bind fails with path # longer than 108 characters). nodekey_part = config['nodekeyhex'][:8] nodedir = os.path.join(base_datadir, nodekey_part) node_genesis_path = os.path.join(nodedir, 'custom_genesis.json') assert len(nodedir + '/geth.ipc') < 108, 'geth data path is too large' os.makedirs(nodedir) if genesis_path is None: geth_bare_genesis(node_genesis_path, all_keys, random_marker) else: shutil.copy(genesis_path, node_genesis_path) geth_init_datadir(nodedir, node_genesis_path) if 'unlock' in config: geth_create_account(nodedir, all_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) stdout = None stderr = None processes_list = [] for pos, cmd in enumerate(cmds): if logdirectory: log_path = os.path.join(logdirectory, str(pos)) logfile = open(log_path, 'w') stdout = logfile stderr = logfile if '--unlock' in cmd: cmd.append('--mine') process = subprocess.Popen( cmd, universal_newlines=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, ) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen( cmd, universal_newlines=True, stdout=stdout, stderr=stderr, ) processes_list.append(process) geth_wait_and_check(deploy_client, private_keys, random_marker) patch_send_transaction(deploy_client) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) for process in processes_list: process.poll() if process.returncode is not None: raise ValueError('geth failed to start') return processes_list
def main(): # config import yaml import io import sys import signal import gevent from .peermanager import PeerManager from .discovery import NodeDiscovery from devp2p import slogging log = slogging.get_logger('app') # read config sample_config = b""" discovery: bootstrap_nodes: # local bootstrap - enode://6ed2fecb28ff17dec8647f08aa4368b57790000e0e9b33a7b91f32c41b6ca9ba21600e9a8c44248ce63a71544388c6745fa291f88f8b81e109ba3da11f7b41b9@127.0.0.1:30303 # go_bootstrap #- enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303 # cpp_bootstrap #- enode://4a44599974518ea5b0f14c31c4463692ac0329cb84851f3435e6d1b18ee4eae4aa495f846a0fa1219bd58035671881d44423876e57db2abd57254d0197da0ebe@5.1.83.226:30303 p2p: num_peers: 10 listen_host: 0.0.0.0 listen_port: 30303 node: privkey_hex: 65462b0520ef7d3df61b9992ed3bea0c56ead753be7c8b3614e0ce01e4cac41b """ if len(sys.argv) == 1: config = yaml.load(io.BytesIO(sample_config)) pubkey = crypto.privtopub(decode_hex(config['node']['privkey_hex'])) config['node']['id'] = crypto.sha3(pubkey) else: fn = sys.argv[1] log.info('loading config from', fn=fn) config = yaml.load(open(fn)) # stop on every unhandled exception! gevent.get_hub( ).SYSTEM_ERROR = BaseException # (KeyboardInterrupt, SystemExit, SystemError) print(config) # create app app = BaseApp(config) # register services NodeDiscovery.register_with_app(app) PeerManager.register_with_app(app) # start app app.start() # wait for interupt evt = gevent.event.Event() # gevent.signal(signal.SIGQUIT, gevent.kill) ## killall pattern gevent.signal(signal.SIGQUIT, evt.set) gevent.signal(signal.SIGTERM, evt.set) gevent.signal(signal.SIGINT, evt.set) evt.wait() # finally stop app.stop()
def run(self): while True: block_head_p = self.test_p.services.chain.chain.head log.info(block_head_p.header) time.sleep(5) peers = self.test_p.services.peermanager.peers print(peers) if __name__ == "__main__": from ethereum import utils from devp2p.crypto import privtopub privkeys = utils.sha3(str(2)) public = utils.encode_hex(privtopub(privkeys)) print utils.encode_hex(privkeys) print public import time # Test pyethapp by using console_service lib. # Generate Temp file if necessary. local directory is ~/py-eth-test-net/test.txt tmpdir = os.path.dirname(__file__) # enum (Accounts) Andy = 0 Choi = 1 Joseph = 2 # Make init eth instance & make genesis block & make 3 accounts named Andy, Choi, Joseph
def geth_create_blockchain(deploy_key, private_keys, blockchain_private_keys, rpc_ports, p2p_ports, base_datadir, verbosity, genesis_path=None, logdirectory=None): # pylint: disable=too-many-locals,too-many-statements,too-many-arguments nodes_configuration = [] key_p2p_rpc = zip(blockchain_private_keys, p2p_ports, rpc_ports) for pos, (key, p2p_port, rpc_port) in enumerate(key_p2p_rpc): config = dict() # make the first node miner if pos == 0: config['minerthreads'] = 1 # conservative config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = privatekey_to_address(key) config['port'] = p2p_port config['rpcport'] = rpc_port config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) nodes_configuration.append(config) all_keys = list(private_keys) all_keys.append( deploy_key) # needs to be at the end because of the minerthreads keys cmds = [] for i, config in enumerate(nodes_configuration): nodedir = os.path.join(base_datadir, config['nodekeyhex']) os.makedirs(nodedir) node_genesis_path = os.path.join(nodedir, 'custom_genesis.json') if genesis_path is None: geth_bare_genesis(node_genesis_path, all_keys) else: shutil.copy(genesis_path, node_genesis_path) geth_init_datadir(nodedir, node_genesis_path) if 'minerthreads' in config: geth_create_account(nodedir, private_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance(sys.stdin, file): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) stdout = None stderr = None processes_list = [] for pos, cmd in enumerate(cmds): if logdirectory: log_path = os.path.join(logdirectory, str(pos)) logfile = open(log_path, 'w') stdout = logfile stderr = logfile if '--unlock' in cmd: process = subprocess.Popen( cmd, universal_newlines=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, ) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen( cmd, universal_newlines=True, stdout=stdout, stderr=stderr, ) processes_list.append(process) assert process.returncode is None geth_wait_and_check(private_keys, rpc_ports) # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, file): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
def privkey_to_uri(private_key): host = b'0.0.0.0' pubkey = privtopub(private_key) return host_port_pubkey_to_uri(host, p2p_base_port, pubkey)
def test_session(): proto = P2PProtocol(peer=PeerMock(), service=WiredService(BaseApp())) hello_packet = proto.create_hello() responder_privkey = mk_privkey('secret1') responder = MultiplexedSession(responder_privkey, hello_packet=hello_packet) p0 = 0 responder.add_protocol(p0) initiator_privkey = mk_privkey('secret2') initiator = MultiplexedSession(initiator_privkey, hello_packet=hello_packet, remote_pubkey=privtopub(responder_privkey)) initiator.add_protocol(p0) # send auth msg = initiator.message_queue.get_nowait() assert msg # auth_init assert initiator.packet_queue.empty() assert not responder.is_initiator # receive auth responder.add_message(msg) assert responder.packet_queue.empty() assert responder.is_ready # send auth ack and hello ack_msg = responder.message_queue.get_nowait() hello_msg = responder.message_queue.get_nowait() assert hello_msg # receive auth ack & hello initiator.add_message(ack_msg + hello_msg) assert initiator.is_ready hello_packet = initiator.packet_queue.get_nowait() assert isinstance(hello_packet, Packet) # initiator sends hello hello_msg = initiator.message_queue.get_nowait() assert hello_msg # hello received by responder responder.add_message(hello_msg) hello_packet = responder.packet_queue.get_nowait() assert isinstance(hello_packet, Packet) # assert we received an actual hello packet data = proto.hello.decode_payload(hello_packet.payload) assert data['version'] # test normal operation ping = proto.create_ping() initiator.add_packet(ping) msg = initiator.message_queue.get_nowait() # receive ping responder.add_message(msg) ping_packet = responder.packet_queue.get_nowait() assert isinstance(ping_packet, Packet) data = proto.ping.decode_payload(ping_packet.payload) # reply with pong pong = proto.create_ping() responder.add_packet(pong) msg = responder.message_queue.get_nowait() # receive pong initiator.add_message(msg) pong_packet = initiator.packet_queue.get_nowait() assert isinstance(pong_packet, Packet) data = proto.pong.decode_payload(pong_packet.payload)
def generate_data_dirs(num_participants, prefix='v'): privkeys = [ utils.sha3(utils.to_string(i)) for i in range(num_participants) ] addrs = [utils.privtoaddr(k) for k in privkeys] genesis = generate_genesis(None, num_participants) for i in range(num_participants): privkey = privkeys[i] addr = addrs[i] port = 40000 + i jsonrpc_port = 4000 + i deposit_size = 500 + 500 * i bootstrap_nodes = list(range(num_participants)) bootstrap_nodes.remove(i) bootstrap_nodes = [ "enode://%[email protected]:%d" % (utils.encode_hex(privtopub(privkeys[n])), 40000 + n) for n in bootstrap_nodes ] dir = prefix + utils.to_string(i) try: os.stat(dir) except: os.mkdir(dir) genesis_path = dir + '/genesis.json' config_path = dir + '/config.yaml' config = { "node": { "privkey_hex": utils.encode_hex(privkey) }, "validator": { "privkey_hex": utils.encode_hex(privkey), "deposit_size": deposit_size }, "eth": { "genesis": genesis_path, "network_id": 42 }, "p2p": { "num_peers": num_participants - 1, "listen_host": '0.0.0.0', "listen_port": port }, "discovery": { "listen_host": '0.0.0.0', "listen_port": port, "bootstrap_nodes": bootstrap_nodes }, "jsonrpc": { "listen_host": '0.0.0.0', "listen_port": jsonrpc_port } } with open(genesis_path, 'w') as f: json.dump(genesis, f, sort_keys=False, indent=4, separators=(',', ': ')) print("genesis for validator %d generated" % i) with open(config_path, 'w') as f: yaml.dump(config, f, default_flow_style=False, indent=4) print("config for validator %d generated" % i)