Esempio n. 1
0
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'])
Esempio n. 2
0
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)
Esempio n. 3
0
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
Esempio n. 5
0
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
Esempio n. 6
0
    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)))
Esempio n. 7
0
 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)
Esempio n. 8
0
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
Esempio n. 9
0
def test_privtopub():
    kenc = fromHex(
        "0x472413e97f1fd58d84e28a559479e6b6902d2e8a0cee672ef38a3a35d263886b")
    penc = fromHex(
        "0x7a2aa2951282279dc1171549a7112b07c38c0d97c0fe2c0ae6c4588ba15be74a04efc4f7da443f6d61f68a9279bc82b73e0cc8d090048e9f87e838ae65dd8d4c"
    )
    assert (penc == crypto.privtopub(kenc))
    return kenc, penc
Esempio n. 10
0
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
Esempio n. 11
0
 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
Esempio n. 12
0
 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)
Esempio n. 13
0
    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)
Esempio n. 14
0
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)
Esempio n. 15
0
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
Esempio n. 17
0
    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'])
Esempio n. 19
0
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
Esempio n. 20
0
def test_privtopub():
    priv = crypto.mk_privkey('test')
    pub = crypto.privtopub(priv)
    pub2 = crypto.ECCx(raw_privkey=priv).raw_pubkey
    assert pub == pub2
Esempio n. 21
0
def test_privtopub():
    priv = crypto.mk_privkey(b'test')
    pub = crypto.privtopub(priv)
    pub2 = crypto.ECCx(raw_privkey=priv).raw_pubkey
    assert pub == pub2
Esempio n. 22
0
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
Esempio n. 23
0
def test_privtopub():
    kenc = fromHex("0x472413e97f1fd58d84e28a559479e6b6902d2e8a0cee672ef38a3a35d263886b")
    penc = fromHex(
        "0x7a2aa2951282279dc1171549a7112b07c38c0d97c0fe2c0ae6c4588ba15be74a04efc4f7da443f6d61f68a9279bc82b73e0cc8d090048e9f87e838ae65dd8d4c")
    assert(penc == crypto.privtopub(kenc))
    return kenc, penc
Esempio n. 24
0
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
Esempio n. 25
0
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)
Esempio n. 27
0
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)
Esempio n. 28
0
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
Esempio n. 29
0
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
Esempio n. 30
0
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()
Esempio n. 31
0
    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
Esempio n. 32
0
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
Esempio n. 33
0
 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)
Esempio n. 34
0
 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)
Esempio n. 35
0
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)
Esempio n. 36
0
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)