func (s *State) LeaderExecute(m interfaces.IMsg) { _, ok := s.Replay.Valid(constants.INTERNAL_REPLAY, m.GetRepeatHash().Fixed(), m.GetTimestamp(), s.GetTimestamp()) if !ok { delete(s.Holding, m.GetRepeatHash().Fixed()) delete(s.Holding, m.GetMsgHash().Fixed()) return } ack := s.NewAck(m).(*messages.Ack) m.SetLeaderChainID(ack.GetLeaderChainID()) m.SetMinute(ack.Minute) s.ProcessLists.Get(ack.DBHeight).AddToProcessList(ack, m) }
func (p *ProcessList) AddToSystemList(m interfaces.IMsg) bool { // Make sure we have a list, and punt if we don't. if p == nil { p.State.Holding[m.GetRepeatHash().Fixed()] = m return false } fullFault, ok := m.(*messages.FullServerFault) if !ok { return false // Should never happen; Don't pass junk to be added to the System List } // If we have already processed past this fault, just ignore. if p.System.Height > int(fullFault.SystemHeight) { return false } // If the fault is in the future, hold it. if p.System.Height < int(fullFault.SystemHeight) { p.State.Holding[m.GetRepeatHash().Fixed()] = m return false } for len(p.System.List) > 0 && p.System.List[len(p.System.List)-1] == nil { p.System.List = p.System.List[:len(p.System.List)-1] } // If we are here, fullFault.SystemHeight == p.System.Height if len(p.System.List) <= p.System.Height { // Nothing in our list a this slot yet, so insert this FullFault message p.System.List = append(p.System.List, fullFault) return true } // Something is in our SystemList at this height; // We will prioritize the FullFault with the highest VMIndex existingSystemFault, _ := p.System.List[p.System.Height].(*messages.FullServerFault) if int(existingSystemFault.VMIndex) >= int(fullFault.VMIndex) { return false } p.System.List[p.System.Height] = fullFault return true }
func (s *State) executeMsg(vm *VM, msg interfaces.IMsg) (ret bool) { _, ok := s.Replay.Valid(constants.INTERNAL_REPLAY, msg.GetRepeatHash().Fixed(), msg.GetTimestamp(), s.GetTimestamp()) if !ok { return } s.SetString() msg.ComputeVMIndex(s) switch msg.Validate(s) { case 1: if s.RunLeader && s.Leader && !s.Saving && vm != nil && int(vm.Height) == len(vm.List) && (!s.Syncing || !vm.Synced) && (msg.IsLocal() || msg.GetVMIndex() == s.LeaderVMIndex) && s.LeaderPL.DBHeight+1 >= s.GetHighestKnownBlock() { if len(vm.List) == 0 { s.SendDBSig(s.LLeaderHeight, s.LeaderVMIndex) s.XReview = append(s.XReview, msg) } else { msg.LeaderExecute(s) } } else { msg.FollowerExecute(s) } ret = true case 0: s.Holding[msg.GetMsgHash().Fixed()] = msg default: s.Holding[msg.GetMsgHash().Fixed()] = msg if !msg.SentInvlaid() { msg.MarkSentInvalid(true) s.networkInvalidMsgQueue <- msg } } return }
func Peers(fnode *FactomNode) { cnt := 0 for { for i := 0; i < 100 && len(fnode.State.APIQueue()) > 0; i++ { select { case msg := <-fnode.State.APIQueue(): if msg == nil { break } repeatHash := msg.GetRepeatHash() if repeatHash == nil { fmt.Println("dddd ERROR!", msg.String()) break } cnt++ msg.SetOrigin(0) if fnode.State.Replay.IsTSValid_(constants.NETWORK_REPLAY, repeatHash.Fixed(), msg.GetTimestamp(), fnode.State.GetTimestamp()) { fnode.MLog.add2(fnode, false, fnode.State.FactomNodeName, "API", true, msg) if len(fnode.State.InMsgQueue()) < 9000 { fnode.State.InMsgQueue() <- msg } } default: } } // Put any broadcasts from our peers into our BroadcastIn queue for i, peer := range fnode.Peers { for j := 0; j < 100; j++ { var msg interfaces.IMsg var err error if !fnode.State.GetNetStateOff() { msg, err = peer.Recieve() } if msg == nil { // Recieve is not blocking; nothing to do, we get a nil. break } cnt++ if err != nil { fmt.Println("ERROR recieving message on", fnode.State.FactomNodeName+":", err) break } msg.SetOrigin(i + 1) if fnode.State.Replay.IsTSValid_(constants.NETWORK_REPLAY, msg.GetRepeatHash().Fixed(), msg.GetTimestamp(), fnode.State.GetTimestamp()) { //if state.GetOut() { // fnode.State.Println("In Comming!! ",msg) //} in := "PeerIn" if msg.IsPeer2Peer() { in = "P2P In" } nme := fmt.Sprintf("%s %d", in, i+1) fnode.MLog.add2(fnode, false, peer.GetNameTo(), nme, true, msg) // Ignore messages if there are too many. if len(fnode.State.InMsgQueue()) < 9000 { fnode.State.InMsgQueue() <- msg } } else { fnode.MLog.add2(fnode, false, peer.GetNameTo(), "PeerIn", false, msg) } } } if cnt == 0 { time.Sleep(50 * time.Millisecond) } cnt = 0 } }
func (p *ProcessList) AddToProcessList(ack *messages.Ack, m interfaces.IMsg) { if p == nil { return } // We don't check the SaltNumber if this isn't an actual message, i.e. a response from // the past. if !ack.Response && ack.LeaderChainID.IsSameAs(p.State.IdentityChainID) { num := p.State.GetSalt(ack.Timestamp) if num != ack.SaltNumber { os.Stderr.WriteString(fmt.Sprintf("This ChainID %x\n", p.State.IdentityChainID.Bytes())) os.Stderr.WriteString(fmt.Sprintf("This Salt %x\n", p.State.Salt.Bytes()[:8])) os.Stderr.WriteString(fmt.Sprintf("This SaltNumber %x\n for this ack", num)) os.Stderr.WriteString(fmt.Sprintf("Ack ChainID %x\n", ack.LeaderChainID.Bytes())) os.Stderr.WriteString(fmt.Sprintf("Ack Salt %x\n", ack.Salt)) os.Stderr.WriteString(fmt.Sprintf("Ack SaltNumber %x\n for this ack", ack.SaltNumber)) panic("There are two leaders configured with the same Identity in this network! This is a configuration problem!") } } if _, ok := m.(*messages.MissingMsg); ok { panic("This shouldn't happen") } toss := func(hint string) { fmt.Println("dddd TOSS in Process List", p.State.FactomNodeName, hint) fmt.Println("dddd TOSS in Process List", p.State.FactomNodeName, ack.String()) fmt.Println("dddd TOSS in Process List", p.State.FactomNodeName, m.String()) delete(p.State.Holding, ack.GetHash().Fixed()) delete(p.State.Acks, ack.GetHash().Fixed()) } now := p.State.GetTimestamp() vm := p.VMs[ack.VMIndex] if len(vm.List) > int(ack.Height) && vm.List[ack.Height] != nil { _, isNew2 := p.State.Replay.Valid(constants.INTERNAL_REPLAY, m.GetRepeatHash().Fixed(), m.GetTimestamp(), now) if !isNew2 { toss("seen before, or too old") return } } if ack.DBHeight != p.DBHeight { panic(fmt.Sprintf("Ack is wrong height. Expected: %d Ack: %s", p.DBHeight, ack.String())) return } if len(vm.List) > int(ack.Height) && vm.List[ack.Height] != nil { if vm.List[ack.Height].GetMsgHash().IsSameAs(m.GetMsgHash()) { fmt.Printf("dddd %-30s %10s %s\n", "xxxxxxxxx PL Duplicate ", p.State.GetFactomNodeName(), m.String()) fmt.Printf("dddd %-30s %10s %s\n", "xxxxxxxxx PL Duplicate ", p.State.GetFactomNodeName(), ack.String()) fmt.Printf("dddd %-30s %10s %s\n", "xxxxxxxxx PL Duplicate vm", p.State.GetFactomNodeName(), vm.List[ack.Height].String()) fmt.Printf("dddd %-30s %10s %s\n", "xxxxxxxxx PL Duplicate vm", p.State.GetFactomNodeName(), vm.ListAck[ack.Height].String()) toss("2") return } vm.List[ack.Height] = nil return } // From this point on, we consider the transaction recorded. If we detect it has already been // recorded, then we still treat it as if we recorded it. vm.heartBeat = 0 // We have heard from this VM // We have already tested and found m to be a new message. We now record its hashes so later, we // can detect that it has been recorded. We don't care about the results of IsTSValid_ at this point. p.State.Replay.IsTSValid_(constants.INTERNAL_REPLAY, m.GetRepeatHash().Fixed(), m.GetTimestamp(), now) p.State.Replay.IsTSValid_(constants.INTERNAL_REPLAY, m.GetMsgHash().Fixed(), m.GetTimestamp(), now) delete(p.State.Acks, ack.GetHash().Fixed()) delete(p.State.Holding, m.GetMsgHash().Fixed()) // Both the ack and the message hash to the same GetHash() m.SetLocal(false) ack.SetLocal(false) ack.SetPeer2Peer(false) m.SetPeer2Peer(false) ack.SendOut(p.State, ack) m.SendOut(p.State, m) for len(vm.List) <= int(ack.Height) { vm.List = append(vm.List, nil) vm.ListAck = append(vm.ListAck, nil) } p.VMs[ack.VMIndex].List[ack.Height] = m p.VMs[ack.VMIndex].ListAck[ack.Height] = ack p.AddOldMsgs(m) p.OldAcks[m.GetMsgHash().Fixed()] = ack }