コード例 #1
0
ファイル: test_rlpxsession.py プロジェクト: zilm13/pydevp2p
def test_body_length():
    initiator, responder = test_session()
    msg_frame = sha3('test') + 'notpadded'
    msg_frame_padded = rzpad16(msg_frame)
    frame_size = len(msg_frame)
    msg_header = struct.pack('>I', frame_size)[1:] + sha3('x')[:16 - 3]
    msg_ct = initiator.encrypt(msg_header, msg_frame_padded)
    r = responder.decrypt(msg_ct)
    assert r['header'] == msg_header
    assert r['frame'] == msg_frame

    # test excess data
    msg_ct2 = initiator.encrypt(msg_header, msg_frame_padded)
    r = responder.decrypt(msg_ct2 + 'excess data')
    assert r['header'] == msg_header
    assert r['frame'] == msg_frame
    assert r['bytes_read'] == len(msg_ct)

    # test data underflow
    data = initiator.encrypt(msg_header, msg_frame_padded)
    header = responder.decrypt_header(data[:32])
    body_size = struct.unpack('>I', '\x00' + header[:3])[0]
    exception_raised = False
    try:
        responder.decrypt_body(data[32:-1], body_size)
    except FormatError:
        exception_raised = True
    assert exception_raised
コード例 #2
0
 def unpack(self, message):
     """
     macSize  = 256 / 8 = 32
     sigSize  = 520 / 8 = 65
     headSize = macSize + sigSize = 97
     hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
     shouldhash := crypto.Sha3(buf[macSize:])
     """
     mdc = message[:32]
     if mdc != crypto.sha3(message[32:]):
         log.warn('packet with wrong mcd')
         raise WrongMAC()
     signature = message[32:97]
     assert len(signature) == 65
     signed_data = crypto.sha3(message[97:])
     remote_pubkey = crypto.ecdsa_recover(signed_data, signature)
     assert len(remote_pubkey) == 512 / 8
     if not crypto.verify(remote_pubkey, signature, signed_data):
         raise InvalidSignature()
     cmd_id = self.decoders['cmd_id'](message[97])
     assert cmd_id in self.cmd_id_map.values()
     payload = rlp.decode(message[98:])
     assert isinstance(payload, list)
     expiration = self.decoders['expiration'](payload.pop())
     if time.time() > expiration:
         raise PacketExpired()
     return remote_pubkey, cmd_id, payload, mdc
コード例 #3
0
 def unpack(self, message):
     """
     macSize  = 256 / 8 = 32
     sigSize  = 520 / 8 = 65
     headSize = macSize + sigSize = 97
     hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
     shouldhash := crypto.Sha3(buf[macSize:])
     """
     mdc = message[:32]
     if mdc != crypto.sha3(message[32:]):
         log.warn('packet with wrong mcd')
         raise WrongMAC()
     signature = message[32:97]
     assert len(signature) == 65
     signed_data = crypto.sha3(message[97:])
     remote_pubkey = crypto.ecdsa_recover(signed_data, signature)
     assert len(remote_pubkey) == 512 / 8
     # if not crypto.verify(remote_pubkey, signature, signed_data):
     #     raise InvalidSignature()
     cmd_id = self.decoders['cmd_id'](message[97])
     cmd = self.rev_cmd_id_map[cmd_id]
     payload = rlp.decode(message[98:], strict=False)
     assert isinstance(payload, list)
     # ignore excessive list elements as required by EIP-8.
     payload = payload[:self.cmd_elem_count_map.get(cmd, len(payload))]
     return remote_pubkey, cmd_id, payload, mdc
コード例 #4
0
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
コード例 #5
0
def test_body_length():
    initiator, responder = test_session()
    msg_frame = sha3('test') + 'notpadded'
    msg_frame_padded = rzpad16(msg_frame)
    frame_size = len(msg_frame)
    msg_header = struct.pack('>I', frame_size)[1:] + sha3('x')[:16 - 3]
    msg_ct = initiator.encrypt(msg_header, msg_frame_padded)
    r = responder.decrypt(msg_ct)
    assert r['header'] == msg_header
    assert r['frame'] == msg_frame

    # test excess data
    msg_ct2 = initiator.encrypt(msg_header, msg_frame_padded)
    r = responder.decrypt(msg_ct2 + 'excess data')
    assert r['header'] == msg_header
    assert r['frame'] == msg_frame
    assert r['bytes_read'] == len(msg_ct)

    # test data underflow
    data = initiator.encrypt(msg_header, msg_frame_padded)
    header = responder.decrypt_header(data[:32])
    body_size = struct.unpack('>I', '\x00' + header[:3])[0]
    exception_raised = False
    try:
        responder.decrypt_body(data[32:-1], body_size)
    except FormatError:
        exception_raised = True
    assert exception_raised
コード例 #6
0
ファイル: discovery.py プロジェクト: gvsurenderreddy/pydevp2p
 def unpack(self, message):
     """
     macSize  = 256 / 8 = 32
     sigSize  = 520 / 8 = 65
     headSize = macSize + sigSize = 97
     hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
     shouldhash := crypto.Sha3(buf[macSize:])
     """
     mdc = message[:32]
     assert mdc == crypto.sha3(message[32:])
     signature = message[32:97]
     assert len(signature) == 65
     signed_data = crypto.sha3(message[97:])
     remote_pubkey = crypto.ecdsa_recover(signed_data, signature)
     assert len(remote_pubkey) == 512 / 8
     if not crypto.verify(remote_pubkey, signature, signed_data):
         raise InvalidSignature()
     cmd_id = self.decoders['cmd_id'](message[97])
     assert cmd_id in self.cmd_id_map.values()
     payload = rlp.decode(message[98:])
     assert isinstance(payload, list)
     expiration = self.decoders['expiration'](payload.pop())
     if time.time() > expiration:
         raise PacketExpired()
     return remote_pubkey, cmd_id, payload, mdc
コード例 #7
0
ファイル: test_peer.py プロジェクト: RomanZacharia/pydevp2p
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
コード例 #8
0
    def setup_cipher(self):
        # https://github.com/ethereum/cpp-ethereum/blob/develop/libp2p/RLPxFrameIO.cpp#L34
        assert self.responder_nonce
        assert self.initiator_nonce
        assert self.auth_init
        assert self.auth_ack
        assert self.remote_ephemeral_pubkey
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')

        # derive base secrets from ephemeral key agreement
        # ecdhe-shared-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk)
        ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key(
            self.remote_ephemeral_pubkey)

        # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || initiator-nonce))
        shared_secret = sha3(ecdhe_shared_secret +
                             sha3(self.responder_nonce + self.initiator_nonce))

        self.ecdhe_shared_secret = ecdhe_shared_secret  # FIXME DEBUG
        self.shared_secret = shared_secret  # FIXME DEBUG

        # token = sha3(shared-secret)
        self.token = sha3(shared_secret)
        self.token_by_pubkey[self.remote_pubkey] = self.token

        # aes-secret = sha3(ecdhe-shared-secret || shared-secret)
        self.aes_secret = sha3(ecdhe_shared_secret + shared_secret)

        # mac-secret = sha3(ecdhe-shared-secret || aes-secret)
        self.mac_secret = sha3(ecdhe_shared_secret + self.aes_secret)

        # setup sha3 instances for the MACs
        # egress-mac = sha3.update(mac-secret ^ recipient-nonce || auth-sent-init)
        mac1 = sha3_256(
            sxor(self.mac_secret, self.responder_nonce) + self.auth_init)
        # ingress-mac = sha3.update(mac-secret ^ initiator-nonce || auth-recvd-ack)
        mac2 = sha3_256(
            sxor(self.mac_secret, self.initiator_nonce) + self.auth_ack)

        if self.is_initiator:
            self.egress_mac, self.ingress_mac = mac1, mac2
        else:
            self.egress_mac, self.ingress_mac = mac2, mac1

        ciphername = 'aes-256-ctr'
        iv = "\x00" * 16
        assert len(iv) == 16
        self.aes_enc = pyelliptic.Cipher(self.aes_secret,
                                         iv,
                                         1,
                                         ciphername=ciphername)
        self.aes_dec = pyelliptic.Cipher(self.aes_secret,
                                         iv,
                                         0,
                                         ciphername=ciphername)
        self.mac_enc = AES.AESCipher(self.mac_secret, AES.MODE_ECB).encrypt

        self.is_ready = True
コード例 #9
0
    def create_auth_message(self,
                            remote_pubkey,
                            ephemeral_privkey=None,
                            nonce=None):
        """
        1. initiator generates ecdhe-random and nonce and creates auth
        2. initiator connects to remote and sends auth

        New:
        E(remote-pubk,
            S(ephemeral-privk, ecdh-shared-secret ^ nonce) ||
            H(ephemeral-pubk) || pubk || nonce || 0x0
        )
        Known:
        E(remote-pubk,
            S(ephemeral-privk, token ^ nonce) || H(ephemeral-pubk) || pubk || nonce || 0x1)
        """
        assert self.is_initiator
        if not self.ecc.is_valid_key(remote_pubkey):
            raise InvalidKeyError('invalid remote pubkey')
        self.remote_pubkey = remote_pubkey

        token = self.token_by_pubkey.get(remote_pubkey)
        if not token:  # new
            ecdh_shared_secret = self.ecc.get_ecdh_key(remote_pubkey)
            token = ecdh_shared_secret
            flag = 0x0
        else:
            flag = 0x1

        self.initiator_nonce = nonce or sha3(
            ienc(random.randint(0, 2**256 - 1)))
        assert len(self.initiator_nonce) == 32

        token_xor_nonce = sxor(token, self.initiator_nonce)
        assert len(token_xor_nonce) == 32

        ephemeral_pubkey = self.ephemeral_ecc.raw_pubkey
        assert len(ephemeral_pubkey) == 512 / 8
        if not self.ecc.is_valid_key(ephemeral_pubkey):
            raise InvalidKeyError('invalid ephemeral pubkey')

        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        S = self.ephemeral_ecc.sign(token_xor_nonce)
        assert len(S) == 65

        # S || H(ephemeral-pubk) || pubk || nonce || 0x0
        auth_message = S + sha3(ephemeral_pubkey) + self.ecc.raw_pubkey + \
            self.initiator_nonce + chr(flag)
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        return auth_message
コード例 #10
0
    def setup_cipher(self):
        # https://github.com/ethereum/cpp-ethereum/blob/develop/libp2p/RLPxFrameIO.cpp#L34
        assert self.responder_nonce
        assert self.initiator_nonce
        assert self.auth_init
        assert self.auth_ack
        assert self.remote_ephemeral_pubkey
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')

        # derive base secrets from ephemeral key agreement
        # ecdhe-shared-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk)
        ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key(self.remote_ephemeral_pubkey)

        # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || initiator-nonce))
        shared_secret = sha3(
            ecdhe_shared_secret + sha3(self.responder_nonce + self.initiator_nonce))

        self.ecdhe_shared_secret = ecdhe_shared_secret  # FIXME DEBUG
        self.shared_secret = shared_secret   # FIXME DEBUG

        # token = sha3(shared-secret)
        self.token = sha3(shared_secret)
        self.token_by_pubkey[self.remote_pubkey] = self.token

        # aes-secret = sha3(ecdhe-shared-secret || shared-secret)
        self.aes_secret = sha3(ecdhe_shared_secret + shared_secret)

        # mac-secret = sha3(ecdhe-shared-secret || aes-secret)
        self.mac_secret = sha3(ecdhe_shared_secret + self.aes_secret)

        # setup sha3 instances for the MACs
        # egress-mac = sha3.update(mac-secret ^ recipient-nonce || auth-sent-init)
        mac1 = sha3_256(sxor(self.mac_secret, self.responder_nonce) + self.auth_init)
        # ingress-mac = sha3.update(mac-secret ^ initiator-nonce || auth-recvd-ack)
        mac2 = sha3_256(sxor(self.mac_secret, self.initiator_nonce) + self.auth_ack)

        if self.is_initiator:
            self.egress_mac, self.ingress_mac = mac1, mac2
        else:
            self.egress_mac, self.ingress_mac = mac2, mac1

        ciphername = 'aes-256-ctr'
        iv = "\x00" * 16
        assert len(iv) == 16
        self.aes_enc = pyelliptic.Cipher(self.aes_secret, iv, 1, ciphername=ciphername)
        self.aes_dec = pyelliptic.Cipher(self.aes_secret, iv, 0, ciphername=ciphername)
        self.mac_enc = AES.AESCipher(self.mac_secret, AES.MODE_ECB).encrypt

        self.is_ready = True
コード例 #11
0
ファイル: encryption.py プロジェクト: jnnk/pydevp2p
    def create_auth_message(self,
                            remote_pubkey,
                            token=None,
                            ephemeral_privkey=None,
                            nonce=None):
        """
        1. initiator generates ecdhe-random and nonce and creates auth
        2. initiator connects to remote and sends auth

        New:
        E(remote-pubk,
            S(ephemeral-privk, ecdh-shared-secret ^ nonce) ||
            H(ephemeral-pubk) || pubk || nonce || 0x0
        )
        Known:
        E(remote-pubk,
            S(ephemeral-privk, token ^ nonce) || H(ephemeral-pubk) || pubk || nonce || 0x1)
        """

        if not token:  # new
            ecdh_shared_secret = self.node.get_ecdh_key(remote_pubkey)
            token = ecdh_shared_secret
            flag = 0x0
        else:
            flag = 0x1

        nonce = nonce or ienc(random.randint(0, 2**256 - 1))
        assert len(nonce) == 32

        token_xor_nonce = sxor(token, nonce)
        assert len(token_xor_nonce) == 32

        # generate session ephemeral key
        if not ephemeral_privkey:
            ephemeral_privkey = sha3(ienc(random.randint(0, 2**256 - 1)))

        self.ephemeral_ecc = ECCx(raw_privkey=ephemeral_privkey)
        ephemeral_pubkey = self.ephemeral_ecc.raw_pubkey

        assert len(ephemeral_pubkey) == 512 / 8
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        S = self.ephemeral_ecc.sign(token_xor_nonce)
        assert len(S) == 65

        # S || H(ephemeral-pubk) || pubk || nonce || 0x0
        auth_message = S + sha3(
            ephemeral_pubkey) + self.node.raw_pubkey + nonce + chr(flag)
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        return auth_message
コード例 #12
0
def test_signature():
    bob = get_ecc(b'secret2')

    # sign
    message = crypto.sha3(b"Hello Alice")
    signature = bob.sign(message)

    # verify signature
    assert crypto.verify(bob.raw_pubkey, signature, message) is True
    assert crypto.ECCx(raw_pubkey=bob.raw_pubkey).verify(signature, message) is True

    # wrong signature
    message = crypto.sha3(b"Hello Alicf")
    assert crypto.ECCx(raw_pubkey=bob.raw_pubkey).verify(signature, message) is False
    assert crypto.verify(bob.raw_pubkey, signature, message) is False
コード例 #13
0
ファイル: discovery.py プロジェクト: jnnk/pydevp2p
    def pack(self, cmd_id, payload):
        """
        UDP packets are structured as follows:

        hash || signature || packet-type || packet-data
        packet-type: single byte < 2**7 // valid values are [1,4]
        packet-data: RLP encoded list. Packet properties are serialized in the order in
                    which they're defined. See packet-data below.

        Offset  |
        0       | MDC       | Ensures integrity of packet,
        65      | signature | Ensures authenticity of sender, `SIGN(sender-privkey, MDC)`
        97      | type      | Single byte in range [1, 4] that determines the structure of Data
        98      | data      | RLP encoded, see section Packet Data

        The packets are signed and authenticated. The sender's Node ID is determined by
        recovering the public key from the signature.

            sender-pubkey = ECRECOVER(Signature)

        The integrity of the packet can then be verified by computing the
        expected MDC of the packet as:

            MDC = SHA3(sender-pubkey || type || data)

        As an optimization, implementations may look up the public key by
        the UDP sending address and compute MDC before recovering the sender ID.
        If the MDC values do not match, the packet can be dropped.
        """
        assert cmd_id in self.cmd_id_map.values()
        assert isinstance(payload, list)

        cmd_id = self.encoders['cmd_id'](cmd_id)
        expiration = self.encoders['expiration'](int(time.time() +
                                                     self.expiration))
        encoded_data = rlp.encode(payload + [expiration])
        # print rlp.decode(encoded_data)
        signed_data = crypto.sha3(cmd_id + encoded_data)
        signature = crypto.sign(signed_data, self.privkey)
        assert crypto.verify(self.pubkey, signature, signed_data)
        # assert self.pubkey == crypto.ecdsa_recover(signed_data, signature)
        # assert crypto.verify(self.pubkey, signature, signed_data)
        assert len(signature) == 65
        mdc = crypto.sha3(signature + cmd_id + encoded_data)
        assert len(mdc) == 32
        # print dict(mdc=mdc.encode('hex'), signature=signature.encode('hex'),
        #            data=str(cmd_id + encoded_data).encode('hex'))
        return mdc + signature + cmd_id + encoded_data
コード例 #14
0
def test_app_restart():
    host, port = '127.0.0.1', 3020

    a_config = dict(p2p=dict(listen_host=host, listen_port=port),
                    node=dict(privkey_hex=crypto.sha3('a').encode('hex')))

    a_app = BaseApp(a_config)
    peermanager.PeerManager.register_with_app(a_app)

    # Restart app 10-times: there should be no exception
    for i in xrange(0, 10):
        a_app.start()
        assert a_app.services.peermanager.server.started
        try_tcp_connect((host, port))
        assert a_app.services.peermanager.num_peers() == 0
        a_app.stop()
        assert a_app.services.peermanager.is_stopped

    # Start the app 10-times: there should be no exception like 'Bind error'
    for i in xrange(0, 10):
        a_app.start()
        assert a_app.services.peermanager.server.started
        try_tcp_connect((host, port))

    a_app.stop()
    assert a_app.services.peermanager.is_stopped
コード例 #15
0
ファイル: rlpxcipher.py プロジェクト: RomanZacharia/pydevp2p
    def create_auth_message(self, remote_pubkey, ephemeral_privkey=None, nonce=None):
        """
        1. initiator generates ecdhe-random and nonce and creates auth
        2. initiator connects to remote and sends auth

        New:
        E(remote-pubk,
            S(ephemeral-privk, ecdh-shared-secret ^ nonce) ||
            H(ephemeral-pubk) || pubk || nonce || 0x0
        )
        Known:
        E(remote-pubk,
            S(ephemeral-privk, token ^ nonce) || H(ephemeral-pubk) || pubk || nonce || 0x1)
        """
        assert self.is_initiator
        if not self.ecc.is_valid_key(remote_pubkey):
            raise InvalidKeyError('invalid remote pubkey')
        self.remote_pubkey = remote_pubkey

        token = self.token_by_pubkey.get(remote_pubkey)
        if not token:  # new
            ecdh_shared_secret = self.ecc.get_ecdh_key(remote_pubkey)
            token = ecdh_shared_secret
            flag = 0x0
        else:
            flag = 0x1

        self.initiator_nonce = nonce or sha3(ienc(random.randint(0, 2 ** 256 - 1)))
        assert len(self.initiator_nonce) == 32

        token_xor_nonce = sxor(token, self.initiator_nonce)
        assert len(token_xor_nonce) == 32

        ephemeral_pubkey = self.ephemeral_ecc.raw_pubkey
        assert len(ephemeral_pubkey) == 512 / 8
        if not self.ecc.is_valid_key(ephemeral_pubkey):
            raise InvalidKeyError('invalid ephemeral pubkey')

        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        S = self.ephemeral_ecc.sign(token_xor_nonce)
        assert len(S) == 65

        # S || H(ephemeral-pubk) || pubk || nonce || 0x0
        auth_message = S + sha3(ephemeral_pubkey) + self.ecc.raw_pubkey + \
            self.initiator_nonce + chr(flag)
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        return auth_message
コード例 #16
0
ファイル: discovery.py プロジェクト: gvsurenderreddy/pydevp2p
    def pack(self, cmd_id, payload):
        """
        UDP packets are structured as follows:

        hash || signature || packet-type || packet-data
        packet-type: single byte < 2**7 // valid values are [1,4]
        packet-data: RLP encoded list. Packet properties are serialized in the order in
                    which they're defined. See packet-data below.

        Offset  |
        0       | MDC       | Ensures integrity of packet,
        65      | signature | Ensures authenticity of sender, `SIGN(sender-privkey, MDC)`
        97      | type      | Single byte in range [1, 4] that determines the structure of Data
        98      | data      | RLP encoded, see section Packet Data

        The packets are signed and authenticated. The sender's Node ID is determined by
        recovering the public key from the signature.

            sender-pubkey = ECRECOVER(Signature)

        The integrity of the packet can then be verified by computing the
        expected MDC of the packet as:

            MDC = SHA3(sender-pubkey || type || data)

        As an optimization, implementations may look up the public key by
        the UDP sending address and compute MDC before recovering the sender ID.
        If the MDC values do not match, the packet can be dropped.
        """
        assert cmd_id in self.cmd_id_map.values()
        assert isinstance(payload, list)

        cmd_id = self.encoders['cmd_id'](cmd_id)
        expiration = self.encoders['expiration'](int(time.time() + self.expiration))
        encoded_data = rlp.encode(payload + [expiration])
        # print rlp.decode(encoded_data)
        signed_data = crypto.sha3(cmd_id + encoded_data)
        signature = crypto.sign(signed_data, self.privkey)
        # assert crypto.verify(self.pubkey, signature, signed_data)
        # assert self.pubkey == crypto.ecdsa_recover(signed_data, signature)
        # assert crypto.verify(self.pubkey, signature, signed_data)
        assert len(signature) == 65
        mdc = crypto.sha3(signature + cmd_id + encoded_data)
        assert len(mdc) == 32
        # print dict(mdc=mdc.encode('hex'), signature=signature.encode('hex'),
        #            data=str(cmd_id + encoded_data).encode('hex'))
        return mdc + signature + cmd_id + encoded_data
コード例 #17
0
def recover_1kb(times=1000):
    alice = get_ecc(b'secret1')
    message = ''.join(chr(random.randrange(0, 256)) for i in range(1024))
    message = crypto.sha3(message.encode('utf-8'))
    signature = alice.sign(message)
    for i in range(times):
        recovered_pubkey = crypto.ecdsa_recover(message, signature)
    assert recovered_pubkey == alice.raw_pubkey
コード例 #18
0
ファイル: discovery.py プロジェクト: gvsurenderreddy/pydevp2p
 def sign(self, msg):
     """
     signature: sign(privkey, sha3(packet-type || packet-data))
     signature: sign(privkey, sha3(pubkey || packet-type || packet-data))
         // implementation w/MCD
     """
     msg = crypto.sha3(msg)
     return crypto.sign(msg, self.privkey)
コード例 #19
0
 def sign(self, msg):
     """
     signature: sign(privkey, sha3(packet-type || packet-data))
     signature: sign(privkey, sha3(pubkey || packet-type || packet-data))
         // implementation w/MCD
     """
     msg = crypto.sha3(msg)
     return crypto.sign(msg, self.privkey)
コード例 #20
0
def test_recover():
    alice = get_ecc(b'secret1')
    message = crypto.sha3(b'hello bob')
    signature = alice.sign(message)
    assert len(signature) == 65
    assert crypto.verify(alice.raw_pubkey, signature, message) is True
    recovered_pubkey = crypto.ecdsa_recover(message, signature)
    assert len(recovered_pubkey) == 64
    assert alice.raw_pubkey == recovered_pubkey
コード例 #21
0
def test_encryption():
    initiator, responder = test_session()
    for i in range(5):
        msg_frame = sha3(str(i) + 'f') * i + 'notpadded'
        msg_frame_padded = rzpad16(msg_frame)
        frame_size = len(msg_frame)
        msg_header = struct.pack('>I', frame_size)[1:] + sha3(str(i))[:16 - 3]
        msg_ct = initiator.encrypt(msg_header, msg_frame_padded)
        r = responder.decrypt(msg_ct)
        assert r['header'] == msg_header
        assert r['frame'] == msg_frame

    for i in range(5):
        msg_frame = sha3(str(i) + 'f')
        msg_header = struct.pack('>I', len(msg_frame))[1:] + sha3(str(i))[:16 - 3]
        msg_ct = responder.encrypt(msg_header, msg_frame)
        r = initiator.decrypt(msg_ct)
        assert r['header'] == msg_header
        assert r['frame'] == msg_frame
コード例 #22
0
def get_app(port, seed):
    config = dict(discovery=dict(), node=dict(privkey_hex=crypto.sha3(seed).encode('hex')))
    config_discovery = config['discovery']
    config_discovery['listen_host'] = '127.0.0.1'
    config_discovery['listen_port'] = port
    config_discovery['bootstrap_nodes'] = []
    # create app
    app = BaseApp(config)
    discovery.NodeDiscovery.register_with_app(app)
    return app
コード例 #23
0
def get_app(port, seed):
    config = ConfigParser.ConfigParser()
    config.add_section('p2p')
    config.set('p2p', 'listen_host', '127.0.0.1')
    config.set('p2p', 'listen_port', str(port))
    config.set('p2p', 'privkey_hex', crypto.sha3(seed).encode('hex'))
    # create app
    app = BaseApp(config)
    discovery.NodeDiscovery.register_with_app(app)
    return app
コード例 #24
0
    def __init__(self, host, port, seed):
        self.address = discovery.Address(host, port)

        config = dict(discovery=dict(), node=dict(privkey_hex=crypto.sha3(seed).encode('hex')))
        config_discovery = config['discovery']
        config_discovery['listen_host'] = host
        config_discovery['listen_port'] = port

        app = AppMock()
        app.config = config
        self.protocol = discovery.DiscoveryProtocol(app=app, transport=self)
コード例 #25
0
ファイル: test_rlpxsession.py プロジェクト: zilm13/pydevp2p
def test_encryption():
    initiator, responder = test_session()
    for i in range(5):
        msg_frame = sha3(str(i) + 'f') * i + 'notpadded'
        msg_frame_padded = rzpad16(msg_frame)
        frame_size = len(msg_frame)
        msg_header = struct.pack('>I', frame_size)[1:] + sha3(str(i))[:16 - 3]
        msg_ct = initiator.encrypt(msg_header, msg_frame_padded)
        r = responder.decrypt(msg_ct)
        assert r['header'] == msg_header
        assert r['frame'] == msg_frame

    for i in range(5):
        msg_frame = sha3(str(i) + 'f')
        msg_header = struct.pack('>I', len(msg_frame))[1:] + sha3(
            str(i))[:16 - 3]
        msg_ct = responder.encrypt(msg_header, msg_frame)
        r = initiator.decrypt(msg_ct)
        assert r['header'] == msg_header
        assert r['frame'] == msg_frame
コード例 #26
0
def get_app(port, seed):
    config = dict(discovery=dict(),
                  node=dict(privkey_hex=crypto.sha3(seed).encode('hex')))
    config_discovery = config['discovery']
    config_discovery['listen_host'] = '127.0.0.1'
    config_discovery['listen_port'] = port
    config_discovery['bootstrap_nodes'] = []
    # create app
    app = BaseApp(config)
    discovery.NodeDiscovery.register_with_app(app)
    return app
コード例 #27
0
ファイル: test_discovery.py プロジェクト: jnnk/pydevp2p
def get_app(port, seed):
    config = dict(p2p=dict())
    config_p2p = config['p2p']
    config_p2p['listen_host'] = '127.0.0.1'
    config_p2p['listen_port'] = port
    config_p2p['privkey_hex'] = crypto.sha3(seed).encode('hex')

    # create app
    app = BaseApp(config)
    discovery.NodeDiscovery.register_with_app(app)
    return app
コード例 #28
0
    def decode_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        assert not self.is_initiator

        self.auth_init = ciphertext
        try:
            auth_message = self.ecc.ecies_decrypt(ciphertext)
        except RuntimeError as e:
            raise AuthenticationError(e)

        # S || H(ephemeral-pubk) || pubk || nonce || 0x[0|1]
        assert len(
            auth_message
        ) == 65 + 32 + 64 + 32 + 1 == 194 == self.auth_message_length
        signature = auth_message[:65]
        H_initiator_ephemeral_pubkey = auth_message[65:65 + 32]
        initiator_pubkey = auth_message[65 + 32:65 + 32 + 64]
        if not self.ecc.is_valid_key(initiator_pubkey):
            raise InvalidKeyError('invalid initiator pubkey')
        self.remote_pubkey = initiator_pubkey
        self.initiator_nonce = auth_message[65 + 32 + 64:65 + 32 + 64 + 32]
        known_flag = bool(ord(auth_message[65 + 32 + 64 + 32:]))

        # token or new ecdh_shared_secret
        if known_flag:
            self.remote_token_found = True
            # what todo if remote has token, but local forgot it.
            #   reply with token not found. FIXME!!!
            token = self.token_by_pubkey.get(initiator_pubkey)
            assert token  # FIXME continue session with ecdh_key and send flag in auth_ack
        else:
            token = self.ecc.get_ecdh_key(initiator_pubkey)

        # verify auth
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        signed = sxor(token, self.initiator_nonce)

        # recover initiator ephemeral pubkey
        self.remote_ephemeral_pubkey = ecdsa_recover(signed, signature)
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')
        if not ecdsa_verify(self.remote_ephemeral_pubkey, signature, signed):
            raise AuthenticationError('could not verify signature')

        # checks that recovery of signature == H(ephemeral-pubk)
        assert H_initiator_ephemeral_pubkey == sha3(
            self.remote_ephemeral_pubkey)
コード例 #29
0
    def __init__(self, host, port, seed):
        self.address = discovery.Address(host, port)

        config = ConfigParser.ConfigParser()
        config.add_section('p2p')
        config.set('p2p', 'listen_host', host)
        config.set('p2p', 'listen_port', str(port))
        config.set('p2p', 'privkey_hex', crypto.sha3(seed).encode('hex'))

        app = AppMock()
        app.config = config
        self.protocol = discovery.DiscoveryProtocol(app=app, transport=self)
コード例 #30
0
def parse_additional_bootstraps(bootstraps):
    retv = []
    if not bootstraps:
        return retv
    for p in bootstraps.split(","):
        ip, port = p.split(":")
        seed = 0
        privkey = sha3("{}:udp:{}:{}".format(seed, ip, port).encode("utf-8"))
        pubkey = privtopub_raw(privkey)
        enode = host_port_pubkey_to_uri(ip, port, pubkey)
        retv.append(enode)
    return retv
コード例 #31
0
    def __init__(self, host, port, seed):
        self.address = discovery.Address(host, port)

        config = dict(discovery=dict(),
                      node=dict(privkey_hex=crypto.sha3(seed).encode('hex')))
        config_discovery = config['discovery']
        config_discovery['listen_host'] = host
        config_discovery['listen_port'] = port

        app = AppMock()
        app.config = config
        self.protocol = discovery.DiscoveryProtocol(app=app, transport=self)
コード例 #32
0
ファイル: rlpxcipher.py プロジェクト: RomanZacharia/pydevp2p
    def decode_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        assert not self.is_initiator

        self.auth_init = ciphertext
        try:
            auth_message = self.ecc.ecies_decrypt(ciphertext)
        except RuntimeError as e:
            raise AuthenticationError(e)

        # S || H(ephemeral-pubk) || pubk || nonce || 0x[0|1]
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194 == self.auth_message_length
        signature = auth_message[:65]
        H_initiator_ephemeral_pubkey = auth_message[65:65 + 32]
        initiator_pubkey = auth_message[65 + 32:65 + 32 + 64]
        if not self.ecc.is_valid_key(initiator_pubkey):
            raise InvalidKeyError('invalid initiator pubkey')
        self.remote_pubkey = initiator_pubkey
        self.initiator_nonce = auth_message[65 + 32 + 64:65 + 32 + 64 + 32]
        known_flag = bool(ord(auth_message[65 + 32 + 64 + 32:]))

        # token or new ecdh_shared_secret
        if known_flag:
            self.remote_token_found = True
            # what todo if remote has token, but local forgot it.
            #   reply with token not found. FIXME!!!
            token = self.token_by_pubkey.get(initiator_pubkey)
            assert token  # FIXME continue session with ecdh_key and send flag in auth_ack
        else:
            token = self.ecc.get_ecdh_key(initiator_pubkey)

        # verify auth
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        signed = sxor(token, self.initiator_nonce)

        # recover initiator ephemeral pubkey
        self.remote_ephemeral_pubkey = ecdsa_recover(signed, signature)
        if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey):
            raise InvalidKeyError('invalid remote ephemeral pubkey')
        if not ecdsa_verify(self.remote_ephemeral_pubkey, signature, signed):
            raise AuthenticationError('could not verify signature')

        # checks that recovery of signature == H(ephemeral-pubk)
        assert H_initiator_ephemeral_pubkey == sha3(self.remote_ephemeral_pubkey)
コード例 #33
0
ファイル: rlpxcipher.py プロジェクト: RomanZacharia/pydevp2p
    def create_auth_ack_message(self, ephemeral_pubkey=None, nonce=None, token_found=False):
        """
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x1) // token found
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x0) // token not found

        nonce and empehemeral-pubk are local!
        """
        assert not self.is_initiator
        ephemeral_pubkey = ephemeral_pubkey or self.ephemeral_ecc.raw_pubkey
        self.responder_nonce = nonce or sha3(ienc(random.randint(0, 2 ** 256 - 1)))

        flag = chr(1 if token_found else 0)
        msg = ephemeral_pubkey + self.responder_nonce + flag
        assert len(msg) == 64 + 32 + 1 == 97 == self.auth_ack_message_length
        return msg
コード例 #34
0
ファイル: encryption.py プロジェクト: jnnk/pydevp2p
    def receive_authentication(self, ciphertext):
        """
        3. optionally, remote decrypts and verifies auth
            (checks that recovery of signature == H(ephemeral-pubk))
        4. remote generates authAck from remote-ephemeral-pubk and nonce
            (authAck = authRecipient handshake)

        optional: remote derives secrets and preemptively sends protocol-handshake (steps 9,11,8,10)
        """
        auth_message = self.node.ecies_decrypt(ciphertext)
        # S || H(ephemeral-pubk) || pubk || nonce || 0x[0|1]
        assert len(auth_message) == 65 + 32 + 64 + 32 + 1 == 194
        signature = auth_message[:65]
        H_remote_ephemeral_pubkey = auth_message[65:65 + 32]
        remote_pubkey = auth_message[65 + 32:65 + 32 + 64]
        nonce = auth_message[65 + 32 + 64:65 + 32 + 64 + 32]
        known_flag = auth_message[65 + 32 + 64 + 32:]

        # token or new ecdh_shared_secret
        token_database = dict()  # FIXME
        token_found = False
        if known_flag == 1:
            token = token_database.get(remote_pubkey)
            if token:
                token_found = True
        else:
            token = ecdh_shared_secret = self.node.get_ecdh_key(remote_pubkey)

        # verify auth
        # S(ephemeral-privk, ecdh-shared-secret ^ nonce)
        ecdh_shared_secret = self.node.get_ecdh_key(remote_pubkey)
        signed = sxor(ecdh_shared_secret, nonce)

        # recover remote ephemeral pubkey
        remote_ephemeral_pubkey = ecdsa_recover(signed, signature)

        assert ecdsa_verify(remote_ephemeral_pubkey, signature, signed)

        # checks that recovery of signature == H(ephemeral-pubk)
        assert H_remote_ephemeral_pubkey == sha3(remote_ephemeral_pubkey)

        return dict(remote_ephemeral_pubkey=remote_ephemeral_pubkey,
                    token=token,
                    token_found=token_found,
                    ecdh_shared_secret=ecdh_shared_secret,
                    remote_pubkey=remote_pubkey,
                    nonce=nonce,
                    known_flag=known_flag)
コード例 #35
0
ファイル: test_peer.py プロジェクト: zilm13/pydevp2p
def connect_go():
    a_config = dict(p2p=dict(listen_host='127.0.0.1', listen_port=3000),
                    node=dict(privkey_hex=crypto.sha3('a').encode('hex')))

    a_app = BaseApp(a_config)
    peermanager.PeerManager.register_with_app(a_app)
    a_app.start()

    a_peermgr = a_app.services.peermanager

    # connect
    pubkey = "6ed2fecb28ff17dec8647f08aa4368b57790000e0e9b33a7b91f32c41b6ca9ba21600e9a8c44248ce63a71544388c6745fa291f88f8b81e109ba3da11f7b41b9".decode(
        'hex')
    a_peermgr.connect(('127.0.0.1', 30303), remote_pubkey=pubkey)
    gevent.sleep(50)
    a_app.stop()
コード例 #36
0
ファイル: test_peer.py プロジェクト: RomanZacharia/pydevp2p
def connect_go():
    a_config = dict(p2p=dict(listen_host='127.0.0.1', listen_port=3000),
                    node=dict(privkey_hex=crypto.sha3('a').encode('hex')))

    a_app = BaseApp(a_config)
    peermanager.PeerManager.register_with_app(a_app)
    a_app.start()

    a_peermgr = a_app.services.peermanager

    # connect
    pubkey = "6ed2fecb28ff17dec8647f08aa4368b57790000e0e9b33a7b91f32c41b6ca9ba21600e9a8c44248ce63a71544388c6745fa291f88f8b81e109ba3da11f7b41b9".decode(
        'hex')
    a_peermgr.connect(('127.0.0.1', 30303), remote_pubkey=pubkey)
    gevent.sleep(50)
    a_app.stop()
コード例 #37
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()
コード例 #38
0
    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
コード例 #39
0
    def create_auth_ack_message(self,
                                ephemeral_pubkey=None,
                                nonce=None,
                                token_found=False):
        """
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x1) // token found
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x0) // token not found

        nonce and empehemeral-pubk are local!
        """
        assert not self.is_initiator
        ephemeral_pubkey = ephemeral_pubkey or self.ephemeral_ecc.raw_pubkey
        self.responder_nonce = nonce or sha3(
            ienc(random.randint(0, 2**256 - 1)))

        flag = chr(1 if token_found else 0)
        msg = ephemeral_pubkey + self.responder_nonce + flag
        assert len(msg) == 64 + 32 + 1 == 97 == self.auth_ack_message_length
        return msg
コード例 #40
0
ファイル: encryption.py プロジェクト: jnnk/pydevp2p
    def something():
        ##################

        # send authentication if not yet
        if not self._authentication_sent:
            remote_node = RemoteNode(remote_pubkey)  # FIXME LOOKUP
            self.send_authentication(remote_node)

            # - success -> AcknowledgeAuthentication
            self.acknowledge_authentication(other, remote_pubkey,
                                            remote_ecdhe_pubkey)

        # ecdhe_shared_secret = ecdh.agree(ecdhe-random, ecdhe-random-public)
        # Compute public key with the local private key and return a 512bits shared key
        ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key(remote_pubkey)
        ecdhe_pubkey = self.ephemeral_ecc.get_pubkey()
        # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || remote-nonce))
        shared_secret = sha3(ecdhe_shared_secret +
                             sha3(ienc(self.nonce) + ienc(remote_nonce)))

        self.aes_secret = sha3(ecdhe_shared_secret + shared_secret)
        self.mac_secret = sha3(ecdhe_shared_secret + self.aes_secret)
        # egress-mac = sha3(mac-secret^nonce || auth)
        self.egress_mac = sha3(sxor(self.mac_secret, self.nonce) + ciphertext)
        # ingress-mac = sha3(mac-secret^remote-nonce || auth)
        self.ingress_mac = sha3(
            sxor(self.mac_secret, remote_nonce) + ciphertext)
        self.token = sha3(shared_secret)

        iv = pyelliptic.Cipher.gen_IV('aes-256-ctr')
        self.aes_enc = pyelliptic.Cipher(self.aes_secret,
                                         iv,
                                         1,
                                         ciphername='aes-256-ctr')
        self.aes_dec = pyelliptic.Cipher(self.aes_secret,
                                         iv,
                                         0,
                                         ciphername='aes-256-ctr')

        self.is_ready = True
コード例 #41
0
ファイル: rlpxcipher.py プロジェクト: jamesqiuhaorna/hgfrr
    def create_auth_ack_message(self,
                                version=supported_rlpx_version,
                                eip8=False,
                                ephemeral_pubkey=None,
                                nonce=None):
        """
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x1) // token found
        authRecipient = E(remote-pubk, remote-ephemeral-pubk || nonce || 0x0) // token not found

        nonce, ephemeral_pubkey, version are local!
        """
        assert not self.is_initiator
        ephemeral_pubkey = ephemeral_pubkey or self.ephemeral_ecc.raw_pubkey
        self.responder_nonce = nonce or sha3(
            ienc(random.randint(0, 2**256 - 1)))
        if eip8 or self.got_eip8_auth:
            msg = self.create_eip8_auth_ack_message(ephemeral_pubkey,
                                                    self.responder_nonce,
                                                    version)
            assert len(msg) > 97
        else:
            msg = ephemeral_pubkey + self.responder_nonce + b'\x00'
            assert len(msg) == 97
        return msg
コード例 #42
0
def devp2p_app(env, network):

    seed = 0
    gevent.get_hub().SYSTEM_ERROR = BaseException

    # get bootstrap node (node0) enode
    bootstrap_node_privkey = sha3("{}:udp:{}:{}".format(
        seed,
        env.cluster_config.P2P.BOOTSTRAP_HOST,
        env.cluster_config.P2P.BOOTSTRAP_PORT,
    ).encode("utf-8"))
    bootstrap_node_pubkey = privtopub_raw(bootstrap_node_privkey)
    enode = host_port_pubkey_to_uri(
        env.cluster_config.P2P.BOOTSTRAP_HOST,
        env.cluster_config.P2P.BOOTSTRAP_PORT,
        bootstrap_node_pubkey,
    )

    services = [NodeDiscovery, peermanager.PeerManager, Devp2pService]

    # prepare config
    base_config = dict()
    for s in services:
        update_config_with_defaults(base_config, s.default_config)

    base_config["discovery"]["bootstrap_nodes"] = [
        enode
    ] + parse_additional_bootstraps(
        env.cluster_config.P2P.ADDITIONAL_BOOTSTRAPS)
    base_config["seed"] = seed
    base_config["base_port"] = env.cluster_config.P2P.DISCOVERY_PORT
    base_config["min_peers"] = env.cluster_config.P2P.MIN_PEERS
    base_config["max_peers"] = env.cluster_config.P2P.MAX_PEERS
    min_peers = base_config["min_peers"]
    max_peers = base_config["max_peers"]

    assert min_peers <= max_peers
    config = copy.deepcopy(base_config)
    node_num = 0
    config["node_num"] = env.cluster_config.P2P.DISCOVERY_PORT

    # create this node priv_key
    config["node"]["privkey_hex"] = encode_hex(
        sha3("{}:udp:{}:{}".format(
            seed, network.ip,
            env.cluster_config.P2P.DISCOVERY_PORT).encode("utf-8")))
    # set ports based on node
    config["discovery"]["listen_port"] = env.cluster_config.P2P.DISCOVERY_PORT
    config["p2p"]["listen_port"] = env.cluster_config.P2P.DISCOVERY_PORT
    config["p2p"]["min_peers"] = min_peers
    config["p2p"]["max_peers"] = max_peers
    ip = network.ip
    config["client_version_string"] = "{}:{}".format(ip, network.port)

    app = Devp2pApp(config, network)
    Logger.info("create_app config={}".format(app.config))
    # register services
    for service in services:
        assert issubclass(service, BaseService)
        if service.name not in app.config["deactivated_services"]:
            assert service.name not in app.services
            service.register_with_app(app)
            assert hasattr(app.services, service.name)
    serve_app(app)
コード例 #43
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("--bootstrap_host", default="0.0.0.0", type=str)
    parser.add_argument("--bootstrap_port", default=29000, type=int)
    # p2p port for this node
    parser.add_argument("--node_port", default=29000, type=int)
    parser.add_argument("--node_num", default=0, type=int)
    parser.add_argument("--min_peers", default=2, type=int)
    parser.add_argument("--max_peers", default=10, type=int)
    seed = 0

    args = parser.parse_args()

    gevent.get_hub().SYSTEM_ERROR = BaseException

    # get bootstrap node (node0) enode
    bootstrap_node_privkey = sha3("{}:udp:{}".format(0, 0).encode("utf-8"))
    bootstrap_node_pubkey = privtopub_raw(bootstrap_node_privkey)
    enode = host_port_pubkey_to_uri(args.bootstrap_host, args.bootstrap_port,
                                    bootstrap_node_pubkey)

    services = [NodeDiscovery, peermanager.PeerManager, ExampleService]

    # prepare config
    base_config = dict()
    for s in services:
        update_config_with_defaults(base_config, s.default_config)

    base_config["discovery"]["bootstrap_nodes"] = [enode]
    base_config["seed"] = seed
    base_config["base_port"] = args.node_port
    base_config["min_peers"] = args.min_peers
    base_config["max_peers"] = args.max_peers
    log.info("run:", base_config=base_config)

    min_peers = base_config["min_peers"]
    max_peers = base_config["max_peers"]

    assert min_peers <= max_peers
    config = copy.deepcopy(base_config)
    config["node_num"] = args.node_num

    # create this node priv_key
    config["node"]["privkey_hex"] = encode_hex(
        sha3("{}:udp:{}".format(seed, args.node_num).encode("utf-8")))
    # set ports based on node
    config["discovery"]["listen_port"] = args.node_port
    config["p2p"]["listen_port"] = args.node_port
    config["p2p"]["min_peers"] = min(10, min_peers)
    config["p2p"]["max_peers"] = max_peers
    config["client_version_string"] = "NODE{}".format(
        args.node_num).encode('utf-8')

    app = ExampleApp(config)
    log.info("create_app", config=app.config)
    # register services
    for service in services:
        assert issubclass(service, BaseService)
        if service.name not in app.config["deactivated_services"]:
            assert service.name not in app.services
            service.register_with_app(app)
            assert hasattr(app.services, service.name)

    app_helper.serve_until_stopped([app])