예제 #1
0
 async def _find_by_lookup(self, pubkey, community):
     identity = self._identities(community)[pubkey]
     lookup_tries = 0
     while lookup_tries < 3:
         try:
             data = await community.bma_access.simple_request(bma.wot.Lookup,
                                                         req_args={'search': pubkey})
             timestamp = BlockUID.empty()
             for result in data['results']:
                 if result["pubkey"] == identity.pubkey:
                     uids = result['uids']
                     for uid_data in uids:
                         if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                             identity.sigdate = BlockUID.from_str(uid_data["meta"]["timestamp"])
                             identity.uid = uid_data["uid"]
                             identity.blockchain_state = BlockchainState.BUFFERED
                             identity.local_state = LocalState.PARTIAL
                             timestamp = identity.sigdate
             return identity
         except errors.DuniterError as e:
             lookup_tries += 1
         except asyncio.TimeoutError:
             lookup_tries += 1
         except ClientError:
             lookup_tries += 1
         except NoPeerAvailable:
             return identity
     return identity
예제 #2
0
def test_add_get_multiple_node(meta_repo):
    nodes_repo = NodesRepo(meta_repo.conn)
    nodes_repo.insert(Node("testcurrency",
                           "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                           """BASIC_MERKLED_API test-net.duniter.fr 13.222.11.22 9201
BASIC_MERKLED_API testnet.duniter.org 80
UNKNOWNAPI some useless information""",
                           BlockUID.empty(),
                           "doe",
                           "15-76543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                           12376543345,
                           "14-AEFFCB00E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                           0,
                           "duniter",
                           "0.30.17"))
    nodes_repo.insert(Node("testcurrency",
                           "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn",
                           "BASIC_MERKLED_API test-net.duniter.org 22.22.22.22 9201",
                           BlockUID.empty(),
                           "doe",
                           "18-76543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                           12376543345,
                           "12-AEFFCB00E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                           0,
                           "duniter",
                           "0.30.2a5"))
    nodes = nodes_repo.get_all(currency="testcurrency")
    assert "testcurrency" in  [t.currency for t in nodes]
    assert "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ" in  [n.pubkey for n in nodes]
    assert "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn" in  [n.pubkey for n in nodes]
예제 #3
0
파일: node.py 프로젝트: pierreloicq/sakia
 async def refresh_uid(self):
     """
     Refresh the node UID
     """
     conn_handler = self.endpoint.conn_handler()
     try:
         data = await bma.wot.Lookup(conn_handler, self.pubkey).get(self._session)
         self.state = Node.ONLINE
         timestamp = BlockUID.empty()
         uid = ""
         for result in data['results']:
             if result["pubkey"] == self.pubkey:
                 uids = result['uids']
                 for uid in uids:
                     if BlockUID.from_str(uid["meta"]["timestamp"]) >= timestamp:
                         timestamp = uid["meta"]["timestamp"]
                         uid = uid["uid"]
         if self._uid != uid:
             self._uid = uid
             self.identity_changed.emit()
     except errors.DuniterError as e:
         if e.ucode == errors.NO_MATCHING_IDENTITY:
             logging.debug("UID not found : {0}".format(self.pubkey[:5]))
         else:
             logging.debug("error in uid reply : {0}".format(self.pubkey[:5]))
             self.state = Node.OFFLINE
             self.identity_changed.emit()
     except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e:
         logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey[:5]))
         self.state = Node.OFFLINE
     except jsonschema.ValidationError as e:
         logging.debug(str(e))
         logging.debug("Validation error : {0}".format(self.pubkey[:5]))
         self.state = Node.CORRUPTED
    def test_certification_raw(self):
        version = 2
        currency = "beta_brousouf"
        pubkey_from = "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV"
        pubkey_to = "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd"
        timestamp = BlockUID(36, "1076F10A7397715D2BEE82579861999EA1F274AC")
        signature = "SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneNYSMV3rk"
        selfcert = Identity(
            version, currency, pubkey_to, "lolcat",
            BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"),
            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci"
        )

        certification = Certification(version, currency, pubkey_from,
                                      pubkey_to, timestamp, signature)

        result = """Version: 2
Type: Certification
Currency: beta_brousouf
Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
IdtyIssuer: HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd
IdtyUniqueID: lolcat
IdtyTimestamp: 32-DB30D958EE5CB75186972286ED3F4686B8A1C2CD
IdtySignature: J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci
CertTimestamp: 36-1076F10A7397715D2BEE82579861999EA1F274AC
SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneNYSMV3rk
"""
        self.assertEqual(certification.signed_raw(selfcert), result)

        from_raw = Certification.from_signed_raw(
            certification.signed_raw(selfcert))
        self.assertEqual(from_raw.signed_raw(selfcert), result)
예제 #5
0
 async def _find_by_lookup(self, pubkey, community):
     identity = self._identities(community)[pubkey]
     lookup_tries = 0
     while lookup_tries < 3:
         try:
             data = await community.bma_access.simple_request(
                 bma.wot.Lookup, req_args={'search': pubkey})
             timestamp = BlockUID.empty()
             for result in data['results']:
                 if result["pubkey"] == identity.pubkey:
                     uids = result['uids']
                     for uid_data in uids:
                         if BlockUID.from_str(uid_data["meta"]
                                              ["timestamp"]) >= timestamp:
                             identity.sigdate = BlockUID.from_str(
                                 uid_data["meta"]["timestamp"])
                             identity.uid = uid_data["uid"]
                             identity.blockchain_state = BlockchainState.BUFFERED
                             identity.local_state = LocalState.PARTIAL
                             timestamp = identity.sigdate
             return identity
         except errors.DuniterError as e:
             lookup_tries += 1
         except asyncio.TimeoutError:
             lookup_tries += 1
         except ClientError:
             lookup_tries += 1
         except NoPeerAvailable:
             return identity
     return identity
예제 #6
0
class Identity:
    currency = attr.ib(convert=str)
    pubkey = attr.ib(convert=str)
    uid = attr.ib(convert=str, default="")
    blockstamp = attr.ib(convert=block_uid, default=BlockUID.empty())
    signature = attr.ib(convert=str, default="", cmp=False, hash=False)
    # Mediantime of the block referenced by blockstamp
    timestamp = attr.ib(convert=int, default=0, cmp=False, hash=False)
    written = attr.ib(convert=bool, default=False, cmp=False, hash=False)
    revoked_on = attr.ib(convert=int, default=0, cmp=False, hash=False)
    outdistanced = attr.ib(convert=bool, default=True, cmp=False, hash=False)
    member = attr.ib(validator=attr.validators.instance_of(bool), default=False, cmp=False, hash=False)
    membership_buid = attr.ib(convert=block_uid, default=BlockUID.empty(), cmp=False, hash=False)
    membership_timestamp = attr.ib(convert=int, default=0, cmp=False, hash=False)
    membership_type = attr.ib(convert=str, default='', validator=lambda s, a, t: t in ('', 'IN', 'OUT'), cmp=False, hash=False)
    membership_written_on = attr.ib(convert=int, default=0, cmp=False, hash=False)
    sentry = attr.ib(convert=bool, default=False, cmp=False, hash=False)

    def document(self):
        """
        Creates a self cert document for a given identity
        :param sakia.data.entities.Identity identity:
        :return: the document
        :rtype: duniterpy.documents.Identity
        """
        return IdentityDoc(10, self.currency, self.pubkey, self.uid, self.blockstamp, self.signature)

    def is_obsolete(self, sig_window, current_time):
        expired = self.timestamp + sig_window <= current_time
        return not self.written and expired
async def get_identity_document(connection, current_block, pubkey):
    """
    Get the identity document of the pubkey

    :param bma.api.ConnectionHandler connection: Connection handler
    :param dict current_block: Current block data
    :param str pubkey: UID/Public key

    :rtype: Identity
    """
    # Here we request for the path wot/lookup/pubkey
    lookup_data = await bma.wot.lookup(connection, pubkey)

    # init vars
    uid = None
    timestamp = BlockUID.empty()
    signature = None

    # parse results
    for result in lookup_data['results']:
        if result["pubkey"] == pubkey:
            uids = result['uids']
            for uid_data in uids:
                # capture data
                timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                uid = uid_data["uid"]
                signature = uid_data["self"]

            # return self-certification document
            return Identity(version=10,
                            currency=current_block['currency'],
                            pubkey=pubkey,
                            uid=uid,
                            ts=timestamp,
                            signature=signature)
예제 #8
0
def test_add_get_drop_identity(meta_repo):
    identities_repo = IdentitiesRepo(meta_repo.conn)
    identities_repo.insert(Identity("testcurrency", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                                    "john",
                                    "20-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                                    "H41/8OGV2W4CLKbE35kk5t1HJQsb3jEM0/QGLUf80CwJvGZf3HvVCcNtHPUFoUBKEDQO9mPK3KJkqOoxHpqHCw==",
                                    1473108382))
    identity = identities_repo.get_one(currency="testcurrency",
                                       pubkey="7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                                       uid="john",
                                       blockstamp=BlockUID(20,
                                                "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
                                       )
    assert identity.currency == "testcurrency"
    assert identity.pubkey == "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ"
    assert identity.uid == "john"
    assert identity.blockstamp.number == 20
    assert identity.blockstamp.sha_hash == "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"
    assert identity.timestamp == 1473108382
    assert identity.signature == "H41/8OGV2W4CLKbE35kk5t1HJQsb3jEM0/QGLUf80CwJvGZf3HvVCcNtHPUFoUBKEDQO9mPK3KJkqOoxHpqHCw=="
    assert identity.member == False
    assert identity.membership_buid == BlockUID.empty()
    assert identity.membership_timestamp == 0
    assert identity.membership_written_on == 0
    identities_repo.drop(identity)
    identity = identities_repo.get_one(currency="testcurrency",
                                       pubkey="7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                                       uid="john",
                                       blockstamp=BlockUID(20,
                                                "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
                                        )
    assert identity is None
예제 #9
0
async def get_identity_document(connection, currency, pubkey):
    """
    Get the SelfCertification document of the pubkey

    :param bma.api.ConnectionHandler connection: Connection handler
    :param str currency: Currency name
    :param str pubkey: Public key

    :rtype: SelfCertification
    """
    # Here we request for the path wot/lookup/pubkey
    lookup_data = await bma.wot.Lookup(connection, pubkey).get(AIOHTTP_SESSION)

    # init vars
    uid = None
    timestamp = BlockUID.empty()
    signature = None

    # parse results
    for result in lookup_data['results']:
        if result["pubkey"] == pubkey:
            uids = result['uids']
            for uid_data in uids:
                # capture data
                timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                uid = uid_data["uid"]
                signature = uid_data["self"]

            # return self-certification document
            return SelfCertification(version=PROTOCOL_VERSION,
                                     currency=currency,
                                     pubkey=pubkey,
                                     uid=uid,
                                     ts=timestamp,
                                     signature=signature)
예제 #10
0
    def test_send_certification(self):
        cert_signal_sent = False

        def check_certification_accepted():
            nonlocal cert_signal_sent
            cert_signal_sent = True

        account = Account("test_salt",
                          "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                          "test_account", [], [], [], self.identities_registry)
        account.certification_accepted.connect(check_certification_accepted)
        account_identity = MagicMock(autospec='sakia.core.registry.Identity')
        account_identity.selfcert = CoroutineMock(return_value=SelfCertification(
            2, "meta_brouzouf", "H8uYXvyF6GWeCr8cwFJ6V5B8tNprwRdjepFNJBqivrzr",
            "test_account",
            BlockUID(
                1000,
                "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243"
            ),
            "82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw=="
        ))

        certified = MagicMock(autospec='sakia.core.registry.Identity')
        certified.uid = "john"
        certified.pubkey = "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ"
        certified.sigdate = 1441130831
        certified.selfcert = CoroutineMock(return_value=SelfCertification(
            2, "meta_brouzouf", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
            "john",
            BlockUID(
                1200,
                "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243"
            ),
            "82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw=="
        ))

        community = MagicMock(autospec='sakia.core.Community')
        community.blockUID = CoroutineMock(return_value=BlockUID(
            3102,
            "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243")
                                           )
        self.identities_registry.future_find = CoroutineMock(side_effect=lambda pubkey, community :account_identity \
                        if pubkey == "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ" else certified)
        community.bma_access = MagicMock(
            autospec='sakia.core.net.api.bma.access.BmaAccess')
        response = Mock()
        response.json = CoroutineMock(return_value={})
        response.status = 200
        community.bma_access.broadcast = CoroutineMock(return_value=[response])

        async def exec_test():
            result = await account.certify("test_password", community, "")
            self.assertTrue(result)

        self.lp.run_until_complete(exec_test())
        self.assertTrue(cert_signal_sent)
예제 #11
0
파일: network.py 프로젝트: mmuman/sakia
 def current_blockUID(self):
     """
     Get the latest block considered valid
     It is the most frequent last block of every known nodes
     """
     blocks = [n.block for n in self.synced_nodes if n.block]
     if len(blocks) > 0:
         return BlockUID(blocks[0]['number'], blocks[0]['hash'])
     else:
         return BlockUID.empty()
예제 #12
0
파일: node.py 프로젝트: florck/sakia
    async def refresh_block(self, block_data):
        """
        Refresh the blocks of this node
        :param dict block_data: The block data in json format
        """
        if not self.node.current_buid or self.node.current_buid.sha_hash != block_data[
                'hash']:
            for endpoint in [
                    e for e in self.node.endpoints
                    if isinstance(e, BMAEndpoint)
            ]:
                conn_handler = next(
                    endpoint.conn_handler(self.session,
                                          proxy=self._user_parameters.proxy()))
                self._logger.debug("Requesting {0}".format(conn_handler))
                try:
                    previous_block = await self.safe_request(
                        endpoint,
                        bma.blockchain.block,
                        proxy=self._user_parameters.proxy(),
                        req_args={'number': self.node.current_buid.number})
                    if not previous_block:
                        continue
                    self.node.previous_buid = BlockUID(
                        previous_block['number'], previous_block['hash'])
                    break  # Do not try any more endpoint
                except errors.DuniterError as e:
                    if e.ucode == errors.BLOCK_NOT_FOUND:
                        self.node.previous_buid = BlockUID.empty()
                        # we don't change state here
                        break
                    else:
                        self.change_state_and_emit(Node.CORRUPTED)
                        break

                    self._logger.debug(
                        "Error in previous block reply of {0} : {1}".format(
                            self.node.pubkey[:5], str(e)))
                finally:
                    if self.node.current_buid != BlockUID(
                            block_data['number'], block_data['hash']):
                        self.node.current_buid = BlockUID(
                            block_data['number'], block_data['hash'])
                        self.node.current_ts = block_data['medianTime']
                        self._logger.debug("Changed block {0} -> {1}".format(
                            self.node.current_buid.number,
                            block_data['number']))
                        self.changed.emit()
            else:
                self._logger.debug(
                    "Could not connect to any BMA endpoint : {0}".format(
                        self.node.pubkey[:5]))
                self.change_state_and_emit(Node.OFFLINE)
        else:
            self.change_state_and_emit(Node.ONLINE)
예제 #13
0
 def _parse_uid_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     for result in data['results']:
         if result["pubkey"] == self.pubkey:
             uids = result['uids']
             for uid_data in uids:
                 if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                     timestamp = uid_data["meta"]["timestamp"]
                     found_uid = uid_data["uid"]
     return self.name == found_uid, self.name, found_uid
예제 #14
0
 def _parse_uid_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     for result in data['results']:
         if result["pubkey"] == self.pubkey:
             uids = result['uids']
             for uid_data in uids:
                 if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                     timestamp = uid_data["meta"]["timestamp"]
                     found_uid = uid_data["uid"]
     return self.name == found_uid, self.name, found_uid
예제 #15
0
파일: identities.py 프로젝트: duniter/sakia
 def _parse_uid_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     for result in data['results']:
         if result["pubkey"] == identity.pubkey:
             uids = result['uids']
             for uid_data in uids:
                 if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                     timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                     found_identity.blockstamp = timestamp
                     found_uid = uid_data["uid"]
                     found_identity.signature = uid_data["self"]
     return identity.uid == found_uid, identity.uid, found_uid
예제 #16
0
 def _refresh_uid(self, uids):
     """
     Refresh UID from uids list, got from a successful lookup request
     :param list uids: UIDs got from a lookup request
     """
     timestamp = BlockUID.empty()
     if self.local_state == LocalState.NOT_FOUND:
         for uid_data in uids:
             if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                 timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                 identity_uid = uid_data["uid"]
                 self.uid = identity_uid
                 self.blockchain_state = BlockchainState.BUFFERED
                 self.local_state = LocalState.PARTIAL
예제 #17
0
 def _parse_uid_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     for result in data['results']:
         if result["pubkey"] == identity.pubkey:
             uids = result['uids']
             for uid_data in uids:
                 if BlockUID.from_str(
                         uid_data["meta"]["timestamp"]) >= timestamp:
                     timestamp = BlockUID.from_str(
                         uid_data["meta"]["timestamp"])
                     found_identity.blockstamp = timestamp
                     found_uid = uid_data["uid"]
                     found_identity.signature = uid_data["self"]
     return identity.uid == found_uid, identity.uid, found_uid
예제 #18
0
 def _parse_pubkey_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     found_result = ["", ""]
     for result in data['results']:
         uids = result['uids']
         for uid_data in uids:
             if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                 timestamp = uid_data["meta"]["timestamp"]
                 found_uid = uid_data["uid"]
         if found_uid == self.name:
             found_result = result['pubkey'], found_uid
     if found_result[1] == self.name:
         return self.pubkey == found_result[0], self.pubkey, found_result[0]
     else:
         return False, self.pubkey, None
예제 #19
0
    def test_identity_membership(self):
        def bma_access(request, *args):
            if request is bma.blockchain.Membership:
                return nice_blockchain.bma_membership_john

        identity = Identity(
            "john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
            BlockUID(
                20,
                "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"
            ), LocalState.COMPLETED, BlockchainState.VALIDATED)

        self.community.bma_access.future_request = CoroutineMock(
            side_effect=bma_access)

        async def exec_test():
            ms = await identity.membership(self.community)
            self.assertEqual(ms["blockNumber"], 0)
            self.assertEqual(
                ms["blockHash"],
                "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"
            )
            self.assertEqual(ms["membership"], "IN")
            self.assertEqual(ms["currency"], "test_currency")
            self.assertEqual(ms["written"], 10000)

        self.lp.run_until_complete(exec_test())
예제 #20
0
 def peer_doc(self):
     peer = Peer(2, self.forge.currency, self.forge.key.pubkey,
                 BlockUID.empty(),
                 [BMAEndpoint(None, "127.0.0.1", None, self.http.port)],
                 None)
     peer.sign([self.forge.key])
     return peer
예제 #21
0
    def test_document_message(self):
        # prepare message
        document_message = DocumentMessage()
        # prepare document
        identity_document = Identity(
            10,
            "beta_brousouf",
            "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd",
            "lolcat",
            BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"),
            "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci",
        )
        # get json string message
        json_document_message = document_message.get_json(
            DocumentMessage.IDENTITY_TYPE_ID, identity_document.inline())
        # convert to dict to verify
        dict_document_message = json.loads(json_document_message)

        # verify
        self.assertIn("body", dict_document_message)
        self.assertIn("name", dict_document_message["body"])
        self.assertIn("identity", dict_document_message["body"])
        self.assertEqual(4, dict_document_message["body"]["name"])
        expected = """HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd\
:J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci:32\
-DB30D958EE5CB75186972286ED3F4686B8A1C2CD:lolcat"""
        self.assertEqual(expected, dict_document_message["body"]["identity"])
예제 #22
0
    def current_buid(self, currency):
        c = self._conn.execute(
            """SELECT COUNT(`uid`)
        FROM `nodes`
        WHERE member == 1 AND currency == ?
        LIMIT 1;""", (currency, ))
        data = c.fetchone()
        if data and data[0] > 3:
            c = self._conn.execute(
                """SELECT `current_buid`,
                 COUNT(`current_buid`) AS `value_occurrence`
        FROM     `nodes`
        WHERE member == 1 AND currency == ?
        GROUP BY `current_buid`
        ORDER BY `value_occurrence` DESC
        LIMIT    1;""", (currency, ))
            data = c.fetchone()
            if data:
                return block_uid(data[0])
        else:
            c = self._conn.execute(
                """SELECT `current_buid`,
             COUNT(`current_buid`) AS `value_occurrence`
    FROM     `nodes`
    WHERE currency == ?
    GROUP BY `current_buid`
    ORDER BY `value_occurrence` DESC
    LIMIT    1;""", (currency, ))
            data = c.fetchone()
            if data:
                return block_uid(data[0])

        return BlockUID.empty()
예제 #23
0
def test_add_get_drop_node(meta_repo):
    nodes_repo = NodesRepo(meta_repo.conn)
    inserted = Node(currency="testcurrency",
                    pubkey="7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                    endpoints="""BASIC_MERKLED_API test-net.duniter.fr 13.222.11.22 9201
BASIC_MERKLED_API testnet.duniter.org 80
UNKNOWNAPI some useless information""",
                     peer_blockstamp=BlockUID.empty(),
                     uid="doe",
                     current_buid="15-76543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                     current_ts=12376543345,
                     previous_buid="14-AEFFCB00E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                     state=0,
                     software="duniter",
                     version="0.30.17")
    nodes_repo.insert(inserted)
    node = nodes_repo.get_one(currency="testcurrency",
                              pubkey="7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
    assert node.currency == "testcurrency"
    assert node.pubkey == "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ"
    assert node.endpoints[0] == BMAEndpoint("test-net.duniter.fr", "13.222.11.22", None, 9201)
    assert node.endpoints[1] == BMAEndpoint("testnet.duniter.org", None, None, 80)
    assert node.endpoints[2] == UnknownEndpoint("UNKNOWNAPI", ["some", "useless", "information"])
    assert node.previous_buid == block_uid("14-AEFFCB00E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
    assert node.current_buid == block_uid("15-76543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
    assert node.state == 0
    assert node.software == "duniter"
    assert node.version == "0.30.17"
    assert node.merkle_peers_root == Node.MERKLE_EMPTY_ROOT
    assert node.merkle_peers_leaves == tuple()

    nodes_repo.drop(node)
    node = nodes_repo.get_one(pubkey="7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
    assert node is None
예제 #24
0
 async def check_destruction(self, pubkey, block_number, unit_base):
     amount = self._sources_processor.amount(self.currency, pubkey)
     if amount < 100 * 10 ** unit_base:
         if self._sources_processor.available(self.currency, pubkey):
             self._sources_processor.drop_all_of(self.currency, pubkey)
             timestamp = await self._blockchain_processor.timestamp(self.currency, block_number)
             next_txid = self._transactions_processor.next_txid(self.currency, block_number)
             sha_identifier = hashlib.sha256("Destruction{0}{1}{2}".format(block_number, pubkey, amount).encode("ascii")).hexdigest().upper()
             destruction = Transaction(currency=self.currency,
                                       pubkey=pubkey,
                                       sha_hash=sha_identifier,
                                       written_block=block_number,
                                       blockstamp=BlockUID.empty(),
                                       timestamp=timestamp,
                                       signatures=[],
                                       issuers=[pubkey],
                                       receivers=[],
                                       amount=amount,
                                       amount_base=0,
                                       comment="Too low balance",
                                       txid=next_txid,
                                       state=Transaction.VALIDATED,
                                       local=True,
                                       raw="")
             self._transactions_processor.commit(destruction)
             return destruction
예제 #25
0
    async def _async_execute_search_text(self, checked):
        cancel_once_task(self, self._async_search_direct_connections)

        self.ui.busy.show()
        text = self.ui.edit_textsearch.text()
        if len(text) < 2:
            return
        try:
            response = await self.community.bma_access.future_request(bma.wot.Lookup, {'search': text})
            identities = []
            for identity_data in response['results']:
                for uid_data in identity_data['uids']:
                    identity = Identity.from_handled_data(uid_data['uid'],
                                                         identity_data['pubkey'],
                                                         BlockUID.from_str(uid_data['meta']['timestamp']),
                                                         BlockchainState.BUFFERED)
                    identities.append(identity)

            self.ui.edit_textsearch.clear()
            self.ui.edit_textsearch.setPlaceholderText(text)
            await self.refresh_identities(identities)
        except errors.DuniterError as e:
            if e.ucode == errors.BLOCK_NOT_FOUND:
                logging.debug(str(e))
        except NoPeerAvailable as e:
            logging.debug(str(e))
        finally:
            self.ui.busy.hide()
예제 #26
0
파일: nodes.py 프로젝트: duniter/sakia
    def current_buid(self, currency):
        c = self._conn.execute("""SELECT COUNT(`uid`)
        FROM `nodes`
        WHERE member == 1 AND currency == ?
        LIMIT 1;""", (currency,))
        data = c.fetchone()
        if data and data[0] > 3:
            c = self._conn.execute("""SELECT `current_buid`,
                 COUNT(`current_buid`) AS `value_occurrence`
        FROM     `nodes`
        WHERE member == 1 AND currency == ?
        GROUP BY `current_buid`
        ORDER BY `value_occurrence` DESC
        LIMIT    1;""", (currency,))
            data = c.fetchone()
            if data:
                return block_uid(data[0])
        else:
            c = self._conn.execute("""SELECT `current_buid`,
             COUNT(`current_buid`) AS `value_occurrence`
    FROM     `nodes`
    WHERE currency == ?
    GROUP BY `current_buid`
    ORDER BY `value_occurrence` DESC
    LIMIT    1;""", (currency,))
            data = c.fetchone()
            if data:
                return block_uid(data[0])

        return BlockUID.empty()
예제 #27
0
def get_membership_document(mtype, current_block, identity, salt, password):
    """
    Get a Membership document

    :param str mtype: "IN" to ask for membership or "OUT" to cancel membership
    :param dict current_block: Current block data
    :param Identity identity: Identity document
    :param str salt: Passphrase of the account
    :param str password: Password of the account

    :rtype: Membership
    """

    # get current block BlockStamp
    timestamp = BlockUID(current_block['number'], current_block['hash'])

    # create keys from credentials
    key = SigningKey(salt, password, ScryptParams(4096, 16, 1))

    # create identity document
    membership = Membership(version=10,
                            currency=current_block['currency'],
                            issuer=key.pubkey,
                            membership_ts=timestamp,
                            membership_type=mtype,
                            uid=identity.uid,
                            identity_ts=identity.timestamp,
                            signature=None)

    # sign document
    membership.sign([key])

    return membership
def get_identity_document(current_block, uid, salt, password):
    """
    Get an Identity document

    :param dict current_block: Current block data
    :param str uid: Unique Identifier
    :param str salt: Passphrase of the account
    :param str password: Password of the account

    :rtype: SelfCertification
    """

    # get current block BlockStamp
    timestamp = BlockUID(current_block['number'], current_block['hash'])

    # create keys from credentials
    key = SigningKey(salt, password)

    # create identity document
    identity = SelfCertification(version=2,
                                 currency=current_block['currency'],
                                 pubkey=key.pubkey,
                                 uid=uid,
                                 ts=timestamp,
                                 signature=None)

    # sign document
    identity.sign([key])

    return identity
def get_identity_document(current_block: dict, uid: str, salt: str,
                          password: str) -> Identity:
    """
    Get an Identity document

    :param current_block: Current block data
    :param uid: Unique IDentifier
    :param salt: Passphrase of the account
    :param password: Password of the account

    :rtype: Identity
    """

    # get current block BlockStamp
    timestamp = BlockUID(current_block['number'], current_block['hash'])

    # create keys from credentials
    key = SigningKey.from_credentials(salt, password)

    # create identity document
    identity = Identity(version=10,
                        currency=current_block['currency'],
                        pubkey=key.pubkey,
                        uid=uid,
                        ts=timestamp,
                        signature=None)

    # sign document
    identity.sign([key])

    return identity
예제 #30
0
파일: identity.py 프로젝트: mmuman/sakia
 def _refresh_uid(self, uids):
     """
     Refresh UID from uids list, got from a successful lookup request
     :param list uids: UIDs got from a lookup request
     """
     timestamp = BlockUID.empty()
     if self.local_state == LocalState.NOT_FOUND:
         for uid_data in uids:
             if BlockUID.from_str(
                     uid_data["meta"]["timestamp"]) >= timestamp:
                 timestamp = BlockUID.from_str(
                     uid_data["meta"]["timestamp"])
                 identity_uid = uid_data["uid"]
                 self.uid = identity_uid
                 self.blockchain_state = BlockchainState.BUFFERED
                 self.local_state = LocalState.PARTIAL
예제 #31
0
    async def future_find(self, pubkey, community):
        """

        :param pubkey: The pubkey we look for
        :param community: The community where we look for the identity
        :return: The identity found
        :rtype: sakia.core.registry.Identity
        """
        if pubkey in self._identities(community):
            identity = self._identities(community)[pubkey]
        else:
            identity = Identity.empty(pubkey)
            self._identities(community)[pubkey] = identity
            tries = 0
            while tries < 3 and identity.local_state == LocalState.NOT_FOUND:
                try:
                    data = await community.bma_access.simple_request(bma.blockchain.Membership,
                                                                          req_args={'search': pubkey})
                    identity.uid = data['uid']
                    identity.sigdate = BlockUID.from_str(data['sigDate'])
                    identity.local_state = LocalState.PARTIAL
                    identity.blockchain_state = BlockchainState.VALIDATED
                except errors.DuniterError as e:
                    if errors.NO_MEMBER_MATCHING_PUB_OR_UID:
                        identity = await self._find_by_lookup(pubkey, community)
                        return identity
                    else:
                        tries += 1
                except asyncio.TimeoutError:
                    tries += 1
                except ClientError:
                    tries += 1
                except NoPeerAvailable:
                    return identity
        return identity
예제 #32
0
 async def request_current_block(self):
     """
     Request a node on the HTTP GET interface
     If an error occurs, the node is considered offline
     """
     for endpoint in [
             e for e in self.node.endpoints if isinstance(e, BMAEndpoint)
     ]:
         try:
             block_data = await self.safe_request(
                 endpoint,
                 bma.blockchain.current,
                 proxy=self._user_parameters.proxy())
             if not block_data:
                 continue
             await self.refresh_block(block_data)
             return  # Do not try any more endpoint
         except errors.DuniterError as e:
             if e.ucode == errors.BLOCK_NOT_FOUND:
                 self.node.previous_buid = BlockUID.empty()
                 self.change_state_and_emit(Node.ONLINE)
             else:
                 self.change_state_and_emit(Node.CORRUPTED)
                 self._logger.debug("Error in block reply :  {0}".format(
                     str(e)))
     else:
         self._logger.debug("Could not connect to any BMA endpoint")
         self.change_state_and_emit(Node.OFFLINE)
def get_identity_document(
    current_block: dict,
    uid: str,
    key: SigningKey,
) -> Identity:
    """
    Get an Identity document

    :param current_block: Current block data
    :param uid: Unique IDentifier
    :param key: cryptographic key to sign documents

    :rtype: Identity
    """

    # get current block BlockStamp
    timestamp = BlockUID(current_block["number"], current_block["hash"])

    # create identity document
    identity = Identity(
        version=10,
        currency=current_block["currency"],
        pubkey=key.pubkey,
        uid=uid,
        ts=timestamp,
        signature=None,
    )

    # sign document
    identity.sign([key])

    return identity
예제 #34
0
class Connection:
    """
    A connection represents a connection to a currency's network
    It is defined by the currency name, and the key informations
    used to connect to it. If the user is using an identity, it is defined here too.
    """
    currency = attr.ib(convert=str)
    pubkey = attr.ib(convert=str)
    uid = attr.ib(convert=str, default="", cmp=False, hash=False)
    scrypt_N = attr.ib(convert=int, default=4096, cmp=False, hash=False)
    scrypt_r = attr.ib(convert=int, default=16, cmp=False, hash=False)
    scrypt_p = attr.ib(convert=int, default=1, cmp=False, hash=False)
    blockstamp = attr.ib(convert=block_uid,
                         default=BlockUID.empty(),
                         cmp=False,
                         hash=False)
    salt = attr.ib(convert=str, init=False, cmp=False, hash=False)
    password = attr.ib(init=False,
                       convert=str,
                       default="",
                       cmp=False,
                       hash=False)

    def is_identity(self):
        return self.uid is not ""

    def is_wallet(self):
        return self.uid is ""

    def title(self):
        return "@".join([self.uid, self.pubkey[:11]])

    @property
    def scrypt_params(self):
        return ScryptParams(self.scrypt_N, self.scrypt_r, self.scrypt_p)
def get_certification_document(current_block, self_cert_document, from_pubkey,
                               salt, password):
    """
    Create and return a Certification document

    :param dict current_block: Current block data
    :param Identity self_cert_document: Identity document
    :param str from_pubkey: Pubkey of the certifier
    :param str salt: Secret salt (DO NOT SHOW IT ANYWHERE, IT IS SECRET !!!)
    :param str password: Secret password (DO NOT SHOW IT ANYWHERE, IT IS SECRET !!!)

    :rtype: Certification
    """
    # construct Certification Document
    certification = Certification(version=10,
                                  currency=current_block['currency'],
                                  pubkey_from=from_pubkey,
                                  pubkey_to=self_cert_document.pubkey,
                                  timestamp=BlockUID(current_block['number'],
                                                     current_block['hash']),
                                  signature="")
    # sign document
    key = SigningKey(salt, password, ScryptParams(4096, 16, 1))
    certification.sign(self_cert_document, [key])

    return certification
예제 #36
0
 def _parse_pubkey_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     found_result = ["", ""]
     for result in data['results']:
         uids = result['uids']
         for uid_data in uids:
             if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                 timestamp = uid_data["meta"]["timestamp"]
                 found_uid = uid_data["uid"]
         if found_uid == self.name:
             found_result = result['pubkey'], found_uid
     if found_result[1] == self.name:
         return self.pubkey == found_result[0], self.pubkey, found_result[0]
     else:
         return False, self.pubkey, None
예제 #37
0
class Blockchain:
    # Parameters in block 0
    parameters = attr.ib(default=BlockchainParameters(), cmp=False, hash=False)
    # block number and hash
    current_buid = attr.ib(convert=block_uid, default=BlockUID.empty())
    # Number of members
    current_members_count = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Current monetary mass in units
    current_mass = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Median time in seconds
    median_time = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Last members count
    last_mass = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Last members count
    last_members_count = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Last UD amount in units (multiply by 10^base)
    last_ud = attr.ib(convert=int, default=1, cmp=False, hash=False)
    # Last UD base
    last_ud_base = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Last UD base
    last_ud_time = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Previous monetary mass in units
    previous_mass = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Previous members count
    previous_members_count = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Previous UD amount in units (multiply by 10^base)
    previous_ud = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Previous UD base
    previous_ud_base = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Previous UD base
    previous_ud_time = attr.ib(convert=int, default=0, cmp=False, hash=False)
    # Currency name
    currency = attr.ib(convert=str, default="", cmp=False, hash=False)
예제 #38
0
def application_with_two_connections(application_with_one_connection,
                                     big_blockchain_forge, bob, john):
    connection = Connection(currency="test_currency",
                            pubkey=john.key.pubkey,
                            uid="",
                            scrypt_N=mirage.User.SCRYPT_PARAMS.N,
                            scrypt_r=mirage.User.SCRYPT_PARAMS.r,
                            scrypt_p=mirage.User.SCRYPT_PARAMS.p,
                            blockstamp=str(BlockUID.empty()))
    application_with_one_connection.db.connections_repo.insert(connection)

    for s in big_blockchain_forge.user_identities[bob.key.pubkey].sources:
        try:
            application_with_one_connection.db.sources_repo.insert(
                Source(currency=big_blockchain_forge.currency,
                       pubkey=bob.key.pubkey,
                       identifier=s.origin_id,
                       noffset=s.index,
                       type=s.source,
                       amount=s.amount,
                       base=s.base))
        except sqlite3.IntegrityError:
            pass

    return application_with_one_connection
async def test_new_block_with_idty(application_with_one_connection, john,
                                   fake_server_with_blockchain):
    john_identity = Identity(
        currency=fake_server_with_blockchain.forge.currency,
        pubkey=john.key.pubkey,
        uid=john.uid,
        blockstamp=john.blockstamp,
        signature=john.identity().signatures[0])
    john_connection = Connection(currency="test_currency",
                                 pubkey=john.key.pubkey,
                                 uid=john.uid,
                                 scrypt_N=4096,
                                 scrypt_r=4,
                                 scrypt_p=2,
                                 blockstamp=john.blockstamp)
    application_with_one_connection.db.connections_repo.insert(john_connection)
    application_with_one_connection.db.identities_repo.insert(john_identity)
    application_with_one_connection.instanciate_services()

    john_found = application_with_one_connection.db.identities_repo.get_one(
        pubkey=john_identity.pubkey)
    assert john_found.written is False
    fake_server_with_blockchain.forge.forge_block()
    fake_server_with_blockchain.forge.push(john.identity())
    fake_server_with_blockchain.forge.push(john.join(BlockUID.empty()))
    fake_server_with_blockchain.forge.forge_block()
    fake_server_with_blockchain.forge.forge_block()
    new_blocks = fake_server_with_blockchain.forge.blocks[-3:]
    await application_with_one_connection.identities_service.handle_new_blocks(
        new_blocks)
    john_found = application_with_one_connection.db.identities_repo.get_one(
        pubkey=john_identity.pubkey)
    assert john_found.written is True
    await fake_server_with_blockchain.close()
예제 #40
0
    def from_json(cls, json_data, version):
        """
        Create a person from json data

        :param dict json_data: The person as a dict in json format
        :return: A new person if pubkey wasn't known, else a new person instance.
        """
        pubkey = json_data['pubkey']
        uid = json_data['uid']
        local_state = LocalState[json_data['local_state']]
        blockchain_state = BlockchainState[json_data['blockchain_state']]
        if version >= parse_version("0.20.0dev0") and json_data['sigdate']:
            sigdate = BlockUID.from_str(json_data['sigdate'])
        else:
            sigdate = BlockUID.empty()

        return cls(uid, pubkey, sigdate, local_state, blockchain_state)
예제 #41
0
    async def selfcert(self, community):
        """
        Get the identity self certification.
        This request is not cached in the person object.

        :param sakia.core.community.Community community: The community target to request the self certification
        :return: A SelfCertification duniterpy object
        :rtype: duniterpy.documents.certification.SelfCertification
        """
        try:
            timestamp = BlockUID.empty()
            lookup_data = await community.bma_access.future_request(bma.wot.Lookup,
                                                                         req_args={'search': self.pubkey})

            for result in lookup_data['results']:
                if result["pubkey"] == self.pubkey:
                    uids = result['uids']
                    for uid_data in uids:
                        # If the sigDate was written in the blockchain
                        if self._sigdate and BlockUID.from_str(uid_data["meta"]["timestamp"]) == self._sigdate:
                            timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                            uid = uid_data["uid"]
                            signature = uid_data["self"]
                        # Else we choose the latest one found
                        elif BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                            timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                            uid = uid_data["uid"]
                            signature = uid_data["self"]

                    if not self.sigdate:
                        self.sigdate = timestamp

                    return SelfCertification(PROTOCOL_VERSION,
                                             community.currency,
                                             self.pubkey,
                                             uid,
                                             timestamp,
                                             signature)
        except errors.DuniterError as e:
            if e.ucode == errors.NO_MATCHING_IDENTITY:
                raise LookupFailureError(self.pubkey, community)
        except MalformedDocumentError:
            raise LookupFailureError(self.pubkey, community)
        except NoPeerAvailable:
            logging.debug("No peer available")
예제 #42
0
파일: nodes.py 프로젝트: duniter/sakia
 def initialize_root_nodes(self, currency):
     if not self.nodes(currency):
         for pubkey in ROOT_SERVERS[currency]["nodes"]:
             node = Node(currency=currency,
                         pubkey=pubkey,
                         endpoints=ROOT_SERVERS[currency]["nodes"][pubkey],
                         peer_blockstamp=BlockUID.empty(),
                         state=0)
             self._repo.insert(node)
예제 #43
0
파일: identities.py 프로젝트: duniter/sakia
 def _parse_pubkey_lookup(data):
     timestamp = BlockUID.empty()
     found_uid = ""
     found_result = ["", ""]
     for result in data['results']:
         uids = result['uids']
         for uid_data in uids:
             if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                 timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                 found_identity.blockstamp = timestamp
                 found_uid = uid_data["uid"]
                 found_identity.signature = uid_data["self"]
         if found_uid == identity.uid:
             found_result = result['pubkey'], found_uid
     if found_result[1] == identity.uid:
         return identity.pubkey == found_result[0], identity.pubkey, found_result[0]
     else:
         return False, identity.pubkey, None
예제 #44
0
 def current_blockUID(self):
     """
     Get the latest block considered valid
     It is the most frequent last block of every known nodes
     """
     blocks = [n.block for n in self.synced_nodes if n.block]
     if len(blocks) > 0:
         return BlockUID(blocks[0]['number'], blocks[0]['hash'])
     else:
         return BlockUID.empty()
예제 #45
0
파일: nodes.py 프로젝트: duniter/sakia
 def current_buid(self, currency):
     """
     Get the latest block considered valid
     It is the most frequent last block of every known nodes
     """
     blocks_uids = [n.current_buid for n in self.synced_nodes(currency)]
     if len(blocks_uids) > 0:
         return blocks_uids[0]
     else:
         return BlockUID.empty()
예제 #46
0
 def load(cls, data):
     """
     Create a new transfer from a dict in json format.
     :param dict data: The loaded data
     :return: A new transfer
     :rtype: Transfer
     """
     return cls(data['hash'],
                TransferState[data['state']],
                BlockUID.from_str(data['blockUID']) if data['blockUID'] else None,
                data['metadata'], data['local'])
예제 #47
0
파일: conftest.py 프로젝트: duniter/sakia
def simple_blockchain_forge(simple_forge, alice, bob):
    simple_forge.push(alice.identity())
    simple_forge.push(bob.identity())
    simple_forge.push(alice.join(BlockUID.empty()))
    simple_forge.push(bob.join(BlockUID.empty()))
    simple_forge.push(alice.certify(bob, BlockUID.empty()))
    simple_forge.push(bob.certify(alice, BlockUID.empty()))
    simple_forge.forge_block()
    simple_forge.set_member(alice.key.pubkey, True)
    simple_forge.set_member(bob.key.pubkey, True)
    for i in range(0, 10):
        new_user = mirage.User.create("test_currency", "user{0}".format(i),
                                       "salt{0}".format(i), "password{0}".format(i),
                                      simple_forge.blocks[-1].blockUID)
        simple_forge.push(new_user.identity())
        simple_forge.push(new_user.join(simple_forge.blocks[-1].blockUID))
        simple_forge.forge_block()
        simple_forge.set_member(new_user.key.pubkey, True)
        simple_forge.generate_dividend()
        simple_forge.forge_block()
    return simple_forge
예제 #48
0
    async def published_uid(self, community):
        try:
            data = await community.bma_access.future_request(bma.wot.Lookup,
                                 req_args={'search': self.pubkey})
            timestamp = BlockUID.empty()

            for result in data['results']:
                if result["pubkey"] == self.pubkey:
                    uids = result['uids']
                    person_uid = ""
                    for uid_data in uids:
                        if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp:
                            timestamp = uid_data["meta"]["timestamp"]
                            person_uid = uid_data["uid"]
                        if person_uid == self.uid:
                            return True
        except errors.DuniterError as e:
            logging.debug("Lookup error : {0}".format(str(e)))
        except NoPeerAvailable as e:
            logging.debug(str(e))
        return False
예제 #49
0
    async def certified_by(self, identities_registry, community):
        """
        Get the list of persons certified by this person
        :param sakia.core.registry.IdentitiesRegistry identities_registry: The registry
        :param sakia.core.community.Community community: The community target
        :return: The list of the certified persons of this community in BMA json format
        :rtype: list
        """
        certified_list = list()
        try:
            data = await community.bma_access.future_request(bma.wot.CertifiedBy, {'search': self.pubkey})
            for certified_data in data['certifications']:
                certified = {}
                certified['identity'] = identities_registry.from_handled_data(certified_data['uid'],
                                                                              certified_data['pubkey'],
                                                                              None,
                                                                              BlockchainState.VALIDATED,
                                                                              community)
                certified['cert_time'] = certified_data['cert_time']['medianTime']
                if certified_data['written']:
                    certified['block_number'] = certified_data['written']['number']
                else:
                    certified['block_number'] = None
                certified_list.append(certified)
        except errors.DuniterError as e:
            if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
                logging.debug("Certified by error : {0}".format(str(e)))
        except NoPeerAvailable as e:
            logging.debug(str(e))

        try:
            data = await community.bma_access.future_request(bma.wot.Lookup, {'search': self.pubkey})
            for result in data['results']:
                if result["pubkey"] == self.pubkey:
                    self._refresh_uid(result['uids'])
                    for certified_data in result['signed']:
                        certified = {}
                        certified['identity'] = identities_registry.from_handled_data(certified_data['uid'],
                                                                          certified_data['pubkey'],
                                                                          None,
                                                                          BlockchainState.BUFFERED,
                                                                          community)
                        timestamp = BlockUID.from_str(certified_data['meta']['timestamp'])
                        certified['cert_time'] = await community.time(timestamp.number)
                        certified['block_number'] = None
                        certified_list.append(certified)
        except errors.DuniterError as e:
            if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
                logging.debug("Lookup error : {0}".format(str(e)))
        except NoPeerAvailable as e:
            logging.debug(str(e))
        return certified_list
async def get_identity_document(client: Client, currency: str, pubkey: str) -> Identity:
    """
    Get the Identity document of the pubkey

    :param client: Client to connect to the api
    :param currency: Currency name
    :param pubkey: Public key

    :rtype: Identity
    """
    # Here we request for the path wot/lookup/pubkey
    lookup_data = await client(bma.wot.lookup, pubkey)

    # init vars
    uid = None
    timestamp = BlockUID.empty()
    signature = None

    # parse results
    for result in lookup_data['results']:
        if result["pubkey"] == pubkey:
            uids = result['uids']
            for uid_data in uids:
                # capture data
                timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"])
                uid = uid_data["uid"]
                signature = uid_data["self"]

            # return self-certification document
            return Identity(
                version=PROTOCOL_VERSION,
                currency=currency,
                pubkey=pubkey,
                uid=uid,
                ts=timestamp,
                signature=signature
            )
예제 #51
0
파일: conftest.py 프로젝트: duniter/sakia
def fake_server(application, event_loop):
    server = event_loop.run_until_complete(mirage.Node.start(None, "test_currency", "12356", "123456", event_loop))

    application.db.nodes_repo.insert(Node(currency=server.forge.currency,
                                          pubkey=server.forge.key.pubkey,
                                          endpoints=server.peer_doc().endpoints,
                                          peer_blockstamp=server.peer_doc().blockUID,
                                          uid="",
                                          current_buid=BlockUID.empty(),
                                          current_ts=0,
                                          state=0,
                                          software="duniter",
                                          version="0.40.2"))
    application.instanciate_services()
    return server
예제 #52
0
 async def requirements(self, community):
     """
     Get the current requirements data.
     :param sakia.core.Community community: the community
     :return: the requirements
     :rtype: dict
     """
     try:
         requirements = await community.bma_access.future_request(bma.wot.Requirements,
                                                                  {'search': self.pubkey})
         for req in requirements['identities']:
             if req['pubkey'] == self.pubkey and req['uid'] == self.uid and \
                     self._sigdate and \
                             BlockUID.from_str(req['meta']['timestamp']) == self._sigdate:
                 return req
     except errors.DuniterError as e:
         logging.debug(str(e))
     return None
예제 #53
0
def build_stopline(currency, pubkey, block_number, mediantime):
    """
    Used to insert a line of ignored tx in the history
    """
    transaction = Transaction(currency=currency,
                              pubkey=pubkey,
                              sha_hash=STOPLINE_HASH,
                              written_block=block_number,
                              blockstamp=BlockUID(block_number, BlockUID.empty().sha_hash),
                              timestamp=mediantime,
                              signatures="",
                              issuers="",
                              receivers="",
                              amount=0,
                              amount_base=0,
                              comment="",
                              txid=0,
                              state=Transaction.VALIDATED,
                              raw="")
    return transaction
예제 #54
0
def test_add_update_node(meta_repo):
    nodes_repo = NodesRepo(meta_repo.conn)
    node = Node("testcurrency",
                "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
                """BASIC_MERKLED_API test-net.duniter.fr 13.222.11.22 9201
BASIC_MERKLED_API testnet.duniter.org 80
UNKNOWNAPI some useless information""",
                BlockUID.empty(),
                "doe",
                "15-76543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                12376543345,
                "14-AEFFCB00E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
                0,
                "duniter")
    nodes_repo.insert(node)
    node.previous_buid = node.current_buid
    node.current_buid = "16-77543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"
    nodes_repo.update(node)
    node2 = nodes_repo.get_one(pubkey="7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
    assert node2.current_buid == block_uid("16-77543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
    assert node2.previous_buid == block_uid("15-76543400E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
예제 #55
0
파일: conftest.py 프로젝트: duniter/sakia
def application_with_two_connections(application_with_one_connection, big_blockchain_forge, bob, john):
    connection = Connection(currency="test_currency",
                      pubkey=john.key.pubkey, uid="",
                      scrypt_N=mirage.User.SCRYPT_PARAMS.N,
                      scrypt_r=mirage.User.SCRYPT_PARAMS.r,
                      scrypt_p=mirage.User.SCRYPT_PARAMS.p,
                      blockstamp=str(BlockUID.empty()))
    application_with_one_connection.db.connections_repo.insert(connection)

    for s in big_blockchain_forge.user_identities[bob.key.pubkey].sources:
        try:
            application_with_one_connection.db.sources_repo.insert(Source(currency=big_blockchain_forge.currency,
                                                  pubkey=bob.key.pubkey,
                                                  identifier=s.origin_id,
                                                  noffset=s.index,
                                                  type=s.source,
                                                  amount=s.amount,
                                                  base=s.base))
        except sqlite3.IntegrityError:
            pass

    return application_with_one_connection
예제 #56
0
    async def send_selfcert(self, password, community):
        """
        Send our self certification to a target community

        :param str password: The account SigningKey password
        :param community: The community target of the self certification
        """
        try:
            block_data = await community.bma_access.simple_request(bma.blockchain.Current)
            signed_raw = "{0}{1}\n".format(block_data['raw'], block_data['signature'])
            block_uid = Block.from_signed_raw(signed_raw).blockUID
        except errors.DuniterError as e:
            if e.ucode == errors.NO_CURRENT_BLOCK:
                block_uid = BlockUID.empty()
            else:
                raise
        selfcert = SelfCertification(PROTOCOL_VERSION,
                                     community.currency,
                                     self.pubkey,
                                     self.name,
                                     block_uid,
                                     None)
        key = SigningKey(self.salt, password)
        selfcert.sign([key])
        logging.debug("Key publish : {0}".format(selfcert.signed_raw()))

        responses = await community.bma_access.broadcast(bma.wot.Add, {}, {'identity': selfcert.signed_raw()})
        result = (False, "")
        for r in responses:
            if r.status == 200:
                result = (True, (await r.json()))
            elif not result[0]:
                result = (False, (await r.text()))
            else:
                await r.release()
        if result[0]:
            (await self.identity(community)).sigdate = block_uid
        return result