private void OnChangeViewReceived(ConsensusPayload payload, ChangeView message) { if (message.NewViewNumber <= context.ViewNumber) { OnRecoveryRequestReceived(payload); } if (context.CommitSent()) { return; } var expectedView = context.ChangeViewPayloads[payload.ValidatorIndex]?.GetDeserializedMessage <ChangeView>().NewViewNumber ?? (byte)0; if (message.NewViewNumber <= expectedView) { return; } Log($"{nameof(OnChangeViewReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} nv={message.NewViewNumber}"); context.ChangeViewPayloads[payload.ValidatorIndex] = payload; CheckExpectedView(message.NewViewNumber); }
private void CheckExpectedView(byte viewNumber) { if (context.ViewNumber >= viewNumber) { return; } // if there are `M` change view payloads with NewViewNumber greater than viewNumber, then, it is safe to move if (context.ChangeViewPayloads.Count(p => p != null && p.GetDeserializedMessage <ChangeView>().NewViewNumber >= viewNumber) >= context.M()) { if (!context.WatchOnly()) { ChangeView message = context.ChangeViewPayloads[context.MyIndex]?.GetDeserializedMessage <ChangeView>(); // Communicate the network about my agreement to move to `viewNumber` // if my last change view payload, `message`, has NewViewNumber lower than current view to change if (message is null || message.NewViewNumber < viewNumber) { localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeChangeView() }); } } InitializeConsensus(viewNumber); } }