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 }