def read_claim(self, claimkey, chain=None): if chain is None: try: value = self.state[claimkey.encode('utf-8')] return json.loads(value.decode('utf-8')) except KeyError: chain = self.chain try: with self.params.as_default(): value = View(chain)[claimkey.encode('utf-8')] return json.loads(value.decode('utf-8')) except (KeyError, ValueError): return None
def receive_message(self, sender, message_metadata, other_recipients=None): """ Interpret incoming additional data :param sender: Sender identifier :param message_metadata: Additional data obtained by ``send_message`` :param other_recipients: Identifiers of other known recipients of the message """ logger.debug('%s <- %s', self.email, sender) if other_recipients is None: other_recipients = set() with self.params.as_default(): # Merge stores temporarily. merged_store = ObjectStore(self.gossip_store) for key, obj in message_metadata.store.items(): merged_store[key] = obj sender_head = message_metadata.head sender_latest_block = merged_store[sender_head] self.gossip_store[sender_head] = \ sender_latest_block self.expected_views[sender] = View( Chain(self.gossip_store, root_hash=sender_head)) full_sender_view = View(Chain(merged_store, root_hash=sender_head)) logger.debug('%s / expected view / %s', self.email, sender) # Add relevant objects from the message store. contacts = self.get_accessible_contacts(sender, message_metadata, other_recipients) for contact in contacts - {self.email}: contact_head = self.get_contact_head_from_view( full_sender_view, contact) if contact_head is None: continue contact_latest_block = message_metadata.store.get(contact_head) if contact_latest_block is not None: self.gossip_store[contact_head] = contact_latest_block # NOTE: Assumes people send only contacts' latest blocks contact_chain = Chain(self.gossip_store, root_hash=contact_head) self.global_views[sender][contact] = View(contact_chain) # TODO: Needs a special check for contact==self.email. # Recompute the latest beliefs. for contact in {sender} | contacts: self.get_latest_view(contact)
def read_claim_from(self, chain, claimkey): assert callable(getattr(claimkey, 'encode', None)) try: with self.params.as_default(): return View(chain)[claimkey.encode('utf-8')].decode('utf-8') except (KeyError, ValueError): return None
def register_peer(self, addr, root_hash, store_url, chain=None): # TODO: check for existing entries if not chain: chain = self.get_chain(store_url, root_hash) assert chain view = View(chain) pk = view.params.dh.pk assert pk self.add_claim((addr, dict(root_hash=root_hash, store_url=store_url, public_key=pet2ascii(pk))))
def test_read_claim_from_other_chain(): for i in range(1, 100): alice_params = LocalParams.generate() alice_state = State() alice_store = {} alice_chain = Chain(alice_store, None) alice_state.identity_info = "Hi, I'm " + pet2ascii(alice_params.dh.pk) with alice_params.as_default(): alice_head = alice_state.commit(alice_chain) alice_chain = Chain(alice_store, alice_head) bob_params = LocalParams.generate() bob_state = State() bob_store = {} bob_chain = Chain(bob_store, None) bob_state.identity_info = "Hi, I'm " + pet2ascii(bob_params.dh.pk) with bob_params.as_default(): bob_head = bob_state.commit(bob_chain) bob_chain = Chain(bob_store, bob_head) bob_pk = bob_params.dh.pk with alice_params.as_default(): alice_state[b"bobs_key"] = b"123abc" alice_state.grant_access(bob_pk, [b"bobs_key"]) alice_head = alice_state.commit(alice_chain) alice_chain = Chain(alice_store, alice_head) with alice_params.as_default(): value = View(alice_chain)[b'bobs_key'].decode('utf-8') assert value == "123abc" with bob_params.as_default(): value = View(alice_chain)[b'bobs_key'].decode('utf-8') assert value == "123abc"
def process_incoming_gossip(self, addr2pagh, account_key, dec_msg): root_hash = dec_msg["GossipClaims"] store = FileStore(dec_msg["ChainStore"]) peers_chain = Chain(store, root_hash=ascii2bytes(root_hash)) assert peers_chain view = View(peers_chain) peers_pk = view.params.dh.pk assert peers_pk sender = parse_email_addr(dec_msg["From"]) self.addr2root_hash[sender] = root_hash self.addr2pk[sender] = peers_pk recipients = get_target_emailadr(dec_msg) for recipient in recipients: pagh = addr2pagh[recipient] value = self.read_claim_from(peers_chain, recipient) if value: # for now we can only read claims about ourselves... # so if we get a value it must be our head imprint. assert value == bytes2ascii(pagh.keydata)
def read_claim_as(self, other, claimkey): assert callable(getattr(claimkey, 'encode', None)) print("read-claim-as", other, repr(claimkey)) chain = self._get_current_chain() with other.params.as_default(): return View(chain)[claimkey.encode('utf-8')].decode('utf-8')