def sign(self): # Initialize the probability array, the core of the signature best_guesses = [None] * len(self.received_blocks) sign_from = max(0, self.max_finalized_height - 30) for i, b in list(enumerate(self.received_blocks))[sign_from:]: # Compute this validator's own initial vote based on when the block # was received, compared to what time the block should have arrived received_time = self.time_received[b.hash] if b is not None else None my_opinion = default_vote(BLKTIME * i, received_time, self.get_time(), blktime=BLKTIME) # Get others' bets on this height votes = self.received_signatures[i].values() if i < len(self.received_signatures) else [] votes = [x for x in votes if x != 0] # Fill in the not-yet-received votes with this validator's default bet votes += [my_opinion] * (NUM_VALIDATORS - len(votes)) vote_from_signatures = int(vote(votes)) # Add the bet to the list bg = min(vote_from_signatures, 10 if self.received_blocks[i] is not None else my_opinion) best_guesses[i] = bg # Request a block if we should have it, and should have had it for # a long time, but don't if vote_from_signatures > 3 and self.received_blocks[i] is None: self.broadcast(BlockRequest(self.id, i)) elif i < len(self.received_blocks) - 50 and self.received_blocks[i] is None: if random.random() < 0.05: self.broadcast(BlockRequest(self.id, i)) # Block finalized if best_guesses[i] >= 10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = self.received_blocks[i].hash # Absense of the block finalized elif best_guesses[i] <= -10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = False # Add to the list of finalized states while self.max_finalized_height < len(self.finalized_hashes) - 1 \ and self.finalized_hashes[self.max_finalized_height + 1] is not None: self.max_finalized_height += 1 last_state = self.finalized_states[-1] if len(self.finalized_states) else GENESIS_STATE self.finalized_states.append(state_transition(last_state, self.received_blocks[self.max_finalized_height])) self.probs = self.probs[:sign_from] + best_guesses[sign_from:] log('Making signature: %r' % self.probs[-10:], lvl=1) sign_from_state = self.finalized_states[sign_from - 1] if sign_from > 0 else GENESIS_STATE s = Signature(self.pos, self.probs[sign_from:], sign_from_state, sign_from) all_signatures.append(s) return s
def sign(self): # Initialize the probability array, the core of the signature best_guesses = [None] * len(self.received_blocks) sign_from = max(0, self.max_finalized_height - 3) while not self.received_blocks[sign_from] and sign_from: sign_from -= 1 for i, b in list(enumerate(self.received_blocks))[sign_from:]: # print i, b # Compute this validator's own initial vote based on when the block # was received, compared to what time the block should have arrived received_time = self.time_received[ b.hash] if b is not None else None # if received_time: # print 'delta', received_time - BLKTIME * i my_opinion = default_vote(BLKTIME * i, received_time, self.get_time(), blktime=BLKTIME) # Get others' bets on this height votes = self.received_signatures[i].values() if i < len( self.received_signatures) else [] votes = [x for x in votes if x != 0] # Fill in the not-yet-received votes with this validator's default bet votes += [my_opinion] * (NUM_VALIDATORS - len(votes)) vote_from_signatures = int(vote(votes)) # If you have not received a block, reserve judgement bg = min(vote_from_signatures, 10 if self.received_blocks[i] is not None else my_opinion) # Add the bet to the list best_guesses[i] = bg # Request a block if we should have it, and should have had it for # a long time, but don't if vote_from_signatures > 3 and self.received_blocks[i] is None: self.broadcast(BlockRequest(self.id, i)) elif i < len(self.received_blocks ) - 50 and self.received_blocks[i] is None: if random.random() < 0.05: self.broadcast(BlockRequest(self.id, i)) # Block finalized if best_guesses[i] >= 10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = self.received_blocks[i].hash # Absense of the block finalized elif best_guesses[i] <= -10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = False # Add to the list of finalized states while self.max_finalized_height < len(self.finalized_hashes) - 1 \ and self.finalized_hashes[self.max_finalized_height + 1] is not None: self.max_finalized_height += 1 last_state = self.states[ self.max_finalized_height - 1] if self.max_finalized_height else GENESIS_STATE assert len(self.states) == len(self.received_blocks), (len( self.states), len(self.received_blocks)) self.states[self.max_finalized_height] = state_transition( last_state, self.received_blocks[self.max_finalized_height]) self.probs = self.probs[:sign_from] + best_guesses[sign_from:] new_states = [ self.states[self.max_finalized_height] if self.max_finalized_height >= 0 else GENESIS_STATE ] prob = 1 for h in range(self.max_finalized_height + 1, len(self.received_blocks)): if self.probs[sign_from] > 0: new_states.append( state_transition(new_states[-1], self.received_blocks[h])) prob *= 1 / (1 + 0.5**self.probs[sign_from]) else: new_states.append(state_transition(new_states[-1], None)) prob *= 1 / (1 + 2.0**self.probs[sign_from]) diff_index = 0 for i in range(-1, -min(len(new_states), len(self.states)) - 1, -1): if new_states[i] != self.states[i]: self.states[i] = new_states[i] diff_index = i log('Making signature: %r' % self.probs[-10:], lvl=1) sign_from_state = self.states[sign_from - 1] if sign_from > 0 else GENESIS_STATE s = Signature(self.pos, self.probs[sign_from:], self.states[diff_index:], len(self.received_blocks), self.most_recent_sig) self.most_recent_sig = s all_signatures.append(s) return s
def sign(self): # Initialize the probability array, the core of the signature best_guesses = [None] * len(self.received_blocks) sign_from = max(0, self.max_finalized_height - 3) while not self.received_blocks[sign_from] and sign_from: sign_from -= 1 for i, b in list(enumerate(self.received_blocks))[sign_from:]: # print i, b # Compute this validator's own initial vote based on when the block # was received, compared to what time the block should have arrived received_time = self.time_received[b.hash] if b is not None else None # if received_time: # print 'delta', received_time - BLKTIME * i my_opinion = default_vote(BLKTIME * i, received_time, self.get_time(), blktime=BLKTIME) # Get others' bets on this height votes = self.received_signatures[i].values() if i < len(self.received_signatures) else [] votes = [x for x in votes if x != 0] # Fill in the not-yet-received votes with this validator's default bet votes += [my_opinion] * (NUM_VALIDATORS - len(votes)) vote_from_signatures = int(vote(votes)) # If you have not received a block, reserve judgement bg = min(vote_from_signatures, 10 if self.received_blocks[i] is not None else my_opinion) # Add the bet to the list best_guesses[i] = bg # Request a block if we should have it, and should have had it for # a long time, but don't if vote_from_signatures > 3 and self.received_blocks[i] is None: self.broadcast(BlockRequest(self.id, i)) elif i < len(self.received_blocks) - 50 and self.received_blocks[i] is None: if random.random() < 0.05: self.broadcast(BlockRequest(self.id, i)) # Block finalized if best_guesses[i] >= 10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = self.received_blocks[i].hash # Absense of the block finalized elif best_guesses[i] <= -10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = False # Add to the list of finalized states while self.max_finalized_height < len(self.finalized_hashes) - 1 \ and self.finalized_hashes[self.max_finalized_height + 1] is not None: self.max_finalized_height += 1 last_state = self.states[self.max_finalized_height - 1] if self.max_finalized_height else GENESIS_STATE assert len(self.states) == len(self.received_blocks), (len(self.states), len(self.received_blocks)) self.states[self.max_finalized_height] = state_transition(last_state, self.received_blocks[self.max_finalized_height]) self.probs = self.probs[:sign_from] + best_guesses[sign_from:] new_states = [self.states[self.max_finalized_height] if self.max_finalized_height >= 0 else GENESIS_STATE] prob = 1 for h in range(self.max_finalized_height + 1, len(self.received_blocks)): if self.probs[sign_from] > 0: new_states.append(state_transition(new_states[-1], self.received_blocks[h])) prob *= 1 / (1 + 0.5 ** self.probs[sign_from]) else: new_states.append(state_transition(new_states[-1], None)) prob *= 1 / (1 + 2.0 ** self.probs[sign_from]) diff_index = 0 for i in range(-1, -min(len(new_states), len(self.states))-1, -1): if new_states[i] != self.states[i]: self.states[i] = new_states[i] diff_index = i log('Making signature: %r' % self.probs[-10:], lvl=1) sign_from_state = self.states[sign_from - 1] if sign_from > 0 else GENESIS_STATE s = Signature(self.pos, self.probs[sign_from:], self.states[diff_index:], len(self.received_blocks), self.most_recent_sig) self.most_recent_sig = s all_signatures.append(s) return s
def sign(self): # Initialize the probability array, the core of the signature best_guesses = [None] * len(self.received_blocks) sign_from = max(0, self.max_finalized_height - 30) for i, b in list(enumerate(self.received_blocks))[sign_from:]: # Compute this validator's own initial vote based on when the block # was received, compared to what time the block should have arrived received_time = self.time_received[ b.hash] if b is not None else None my_opinion = default_vote(BLKTIME * i, received_time, self.get_time(), blktime=BLKTIME) # Get others' bets on this height votes = self.received_signatures[i].values() if i < len( self.received_signatures) else [] votes = [x for x in votes if x != 0] # Fill in the not-yet-received votes with this validator's default bet votes += [my_opinion] * (NUM_VALIDATORS - len(votes)) vote_from_signatures = int(vote(votes)) # Add the bet to the list bg = min(vote_from_signatures, 10 if self.received_blocks[i] is not None else my_opinion) best_guesses[i] = bg # Request a block if we should have it, and should have had it for # a long time, but don't if vote_from_signatures > 3 and self.received_blocks[i] is None: self.broadcast(BlockRequest(self.id, i)) elif i < len(self.received_blocks ) - 50 and self.received_blocks[i] is None: if random.random() < 0.05: self.broadcast(BlockRequest(self.id, i)) # Block finalized if best_guesses[i] >= 10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = self.received_blocks[i].hash # Absense of the block finalized elif best_guesses[i] <= -10: while len(self.finalized_hashes) <= i: self.finalized_hashes.append(None) self.finalized_hashes[i] = False # Add to the list of finalized states while self.max_finalized_height < len(self.finalized_hashes) - 1 \ and self.finalized_hashes[self.max_finalized_height + 1] is not None: self.max_finalized_height += 1 last_state = self.finalized_states[-1] if len( self.finalized_states) else GENESIS_STATE self.finalized_states.append( state_transition( last_state, self.received_blocks[self.max_finalized_height])) self.probs = self.probs[:sign_from] + best_guesses[sign_from:] log('Making signature: %r' % self.probs[-10:], lvl=1) sign_from_state = self.finalized_states[ sign_from - 1] if sign_from > 0 else GENESIS_STATE s = Signature(self.pos, self.probs[sign_from:], sign_from_state, sign_from) all_signatures.append(s) return s