def process_vote(self, vote): """ Process an incoming vote and add to relevant datastructures. """ # authenticate vote signature # update data structures if len(vote) == 0: return vote = json.loads(vote) proposal = vote[0] if not proposal in self.votes: # instantiate data structures for proposal self.votes[proposal] = set() self.signatures[proposal] = [] # vote for every signature signatures = vote[1] for signature in signatures: node_id = signature[0] if node_id in self.votes[proposal]: # node has already voted; ignore it continue proposal_sig = signature[1] # check signature on vote and add node to set of votes and signature (for later rebroadcast) if util.is_message_signed(proposal, proposal_sig, config.PUBLIC_KEYS[node_id]): self.votes[proposal].add(node_id) self.signatures[proposal].append((node_id, proposal_sig)) print("[byz-ag] Signed proposal message accepted", proposal, signature) else: print("[byz-ag] Error: Signed proposal message rejected", proposal, signature)
def seal_is_valid(self): """ Checks whether a block's seal_data forms a valid seal. In PoA, this means that Verif(PK, [block, sig]) = accept. (aka the unsealed block header is validly signed under the authority's public key) Returns: bool: True only if a block's seal data forms a valid seal according to PoA. """ if self.seal_data == 0: return False # Decode signature to bytes, verify it signature = hex(self.seal_data)[2:].zfill(96) return util.is_message_signed(self.unsealed_header(), signature, config.AUTHORITY_PK)