def reduction(self, hblock,t_step): self.votes_heard = [] self.committeeVote(3, t_step, str(hblock)) yield self.env.timeout(L_step) # self.log ("%d: %d heard %d votes\n"%(self.env.now, self.id, len(self.votes_heard))) # Count received votes hblock1 = self.countVotes(3, T_step, t_step) self.log("%d: got max votes for %s\n"%(self.env.now, hblock1)) eblock = Block(self.block_pointer.hash(),'Empty',self.block_pointer) ehash = utils.hashBlock(str(eblock)) self.votes_heard = [] if hblock1 == None : self.committeeVote(4, t_step,str(ehash)) else : self.committeeVote(4, t_step,str(hblock1)) yield self.env.timeout(L_step) hblock2 = self.countVotes(4, T_step, t_step) self.votes_heard = [] if hblock2 == None : self.log('%d: Result of Reduction is Empty Hash\n'%(self.env.now)) return ehash else : self.log('%d: Result of Reduction is %s\n'%(self.env.now,hblock2)) return hblock2
def commonCoin(self, step, t): minhash = 2**256 for m in self.votes_heard: votes, value, sorthash = self.processMsg(t, m) for j in range(1, votes): h = int(utils.hashBlock(str(sorthash) + str(j)), base=16) if h < minhash : minhash = h self.log('Result of Common Coin : %s\n'%(str(minhash % 2))) return minhash % 2
def byzagreement(self,round,block,t_step): hblock = yield from self.reduction(utils.hashBlock(str(block)),t_step) self.log('%d: Result of Reduction is %s, %d\n'%(self.env.now,str(hblock),t_step)) hblock1 = yield from self.binarybyzagreement(round,hblock,t_step) yield self.env.timeout(L_step) r = self.countVotes('FINAL',T_final,t_final) if hblock1 == r : self.log('%d: Final consensus is achieved with block %s\n'%(self.env.now,str(block))) return 'FINAL',block else : self.log('%d: Tentative consensus is achieved with block %s\n'%(self.env.now,str(block))) return 'TENTATIVE',block
def binarybyzagreement(self,round,block_hash,t_step): step = 3 r = block_hash eblock = Block(self.block_pointer.hash(),'Empty',self.block_pointer) empty_hash = utils.hashBlock(str(eblock)) while step < MAX_STEPS : self.committeeVote(step, t_step, r) yield self.env.timeout(L_step) r = self.countVotes(step,T_step,t_step) if r == None : r = block_hash elif r != empty_hash : for s in range(step+1,step+4) : self.committeeVote(s, t_step, r) if step == 3 : self.committeeVote("FINAL", t_final, r) return r step += 1 self.committeeVote(step, t_step, r) yield self.env.timeout(L_step) r = self.countVotes(step,T_step,t_step) if r == None : r = block_hash elif r == empty_hash : for s in range(step+1,step+4) : self.committeeVote(s, t_step, r) return r step += 1 self.committeeVote(step, t_step, r) yield self.env.timeout(L_step) r = self.countVotes(step,T_step,t_step) if r == None: if self.commonCoin(step, t_step) == 0: r = block_hash else: r = empty_hash step += 1 self.hangForever()
def processMsg(self, t, message): if message.payload.prev_block_hash != utils.hashBlock(str(self.block_pointer)): return 0, None, None votes = utils.verifySortition(message.pub_key, message.payload.vrf_hash, message.payload.vrf_proof, message.payload.prev_block_hash, message.payload.round, message.payload.step, t, "committee", ctx['weight'][str(message.pub_key)], ctx['W']) return votes, message.payload.curr_block_hash, message.payload.vrf_hash
def hash(self): return utils.hashBlock(str(self))