func (sn *Node) ComputeCombinedMerkleRoot(view, Round int) { sn.roundLock.RLock() round := sn.Rounds[Round] sn.roundLock.RUnlock() // add hash of whole log to leaves round.Leaves = append(round.Leaves, round.HashedLog) // compute MT root based on Log as right child and // MT of leaves as left child and send it up to parent sort.Sort(hashid.ByHashId(round.Leaves)) left, proofs := proof.ProofTree(sn.Suite().Hash, round.Leaves) right := round.HashedLog moreLeaves := make([]hashid.HashId, 0) moreLeaves = append(moreLeaves, left, right) round.MTRoot, _ = proof.ProofTree(sn.Suite().Hash, moreLeaves) // Hashed Log has to come first in the proof; len(sn.CMTRoots)+1 proofs round.Proofs = make(map[string]proof.Proof, 0) children := sn.Children(view) for name := range children { round.Proofs[name] = append(round.Proofs[name], right) } round.Proofs["local"] = append(round.Proofs["local"], right) // separate proofs by children (need to send personalized proofs to children) // also separate local proof (need to send it to timestamp server) sn.SeparateProofs(proofs, round.Leaves, Round) }
func (s *Server) AggregateCommits(view int) []byte { //log.Println(s.Name(), "calling AggregateCommits") s.mux.Lock() // get data from s once to avoid refetching from structure Queue := s.Queue READING := s.READING PROCESSING := s.PROCESSING // messages read will now be processed READING, PROCESSING = PROCESSING, READING s.READING, s.PROCESSING = s.PROCESSING, s.READING s.Queue[READING] = s.Queue[READING][:0] // give up if nothing to process if len(Queue[PROCESSING]) == 0 { s.mux.Unlock() s.Root = make([]byte, hashid.Size) s.Proofs = make([]proof.Proof, 1) return s.Root } // pull out to be Merkle Tree leaves s.Leaves = make([]hashid.HashId, 0) for _, msg := range Queue[PROCESSING] { s.Leaves = append(s.Leaves, hashid.HashId(msg.Tsm.Sreq.Val)) } s.mux.Unlock() // non root servers keep track of rounds here if !s.IsRoot(view) { s.rLock.Lock() lsr := s.LastRound() mr := s.maxRounds s.rLock.Unlock() // if this is our last round then close the connections if lsr >= mr && mr >= 0 { s.closeChan <- true } } // create Merkle tree for this round's messages and check corectness s.Root, s.Proofs = proof.ProofTree(s.Suite().Hash, s.Leaves) if sign.DEBUG == true { if proof.CheckLocalProofs(s.Suite().Hash, s.Root, s.Leaves, s.Proofs) == true { log.Println("Local Proofs of", s.Name(), "successful for round "+strconv.Itoa(int(s.LastRound()))) } else { panic("Local Proofs" + s.Name() + " unsuccessful for round " + strconv.Itoa(int(s.LastRound()))) } } return s.Root }