func (s *State) LeaderExecuteEOM(m interfaces.IMsg) { if !m.IsLocal() { s.FollowerExecuteEOM(m) return } // The zero based minute for the message is equal to // the one based "LastMinute". This way we know we are // generating minutes in order. eom := m.(*messages.EOM) pl := s.ProcessLists.Get(s.LLeaderHeight) vm := pl.VMs[s.LeaderVMIndex] // Put the System Height and Serial Hash into the EOM eom.SysHeight = uint32(pl.System.Height) if pl.System.Height > 1 { ff, ok := pl.System.List[pl.System.Height-1].(*messages.FullServerFault) if ok { eom.SysHash = ff.GetSerialHash() } } if s.Syncing && vm.Synced { return } else if !s.Syncing { s.Syncing = true s.EOM = true s.EOMsyncing = true s.EOMProcessed = 0 for _, vm := range pl.VMs { vm.Synced = false } s.EOMLimit = len(pl.FedServers) s.EOMMinute = int(s.CurrentMinute) } //_, vmindex := pl.GetVirtualServers(s.EOMMinute, s.IdentityChainID) eom.DBHeight = s.LLeaderHeight eom.VMIndex = s.LeaderVMIndex // eom.Minute is zerobased, while LeaderMinute is 1 based. So // a simple assignment works. eom.Minute = byte(s.CurrentMinute) eom.Sign(s) eom.MsgHash = nil ack := s.NewAck(m) s.Acks[eom.GetMsgHash().Fixed()] = ack m.SetLocal(false) s.FollowerExecuteEOM(m) s.UpdateState() }
// Messages that will go into the Process List must match an Acknowledgement. // The code for this is the same for all such messages, so we put it here. // // Returns true if it finds a match, puts the message in holding, or invalidates the message func (s *State) FollowerExecuteEOM(m interfaces.IMsg) { if m.IsLocal() { return // This is an internal EOM message. We are not a leader so ignore. } s.Holding[m.GetMsgHash().Fixed()] = m ack, _ := s.Acks[m.GetMsgHash().Fixed()].(*messages.Ack) if ack != nil { pl := s.ProcessLists.Get(ack.DBHeight) pl.AddToProcessList(ack, m) } }
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 }