public virtual void Disconnect(bool error) { if (Interlocked.Exchange(ref disposed, 1) == 0) { Disconnected?.Invoke(this, error); bool needSync = false; lock (missions_global) lock (missions) if (missions.Count > 0) { foreach (UInt256 hash in missions) { missions_global.Remove(hash); } needSync = true; } if (needSync) { localNode.RequestGetBlocks(); } } }
private void LocalNode_InventoryReceived(object sender, IInventory inventory) { ConsensusPayload payload = inventory as ConsensusPayload; if (payload != null) { lock (context) { if (payload.ValidatorIndex == context.MyIndex) { return; } if (payload.Version != ConsensusContext.Version) { return; } if (payload.PrevHash != context.PrevHash || payload.BlockIndex != context.BlockIndex) { // Request blocks if (Blockchain.Default?.Height + 1 < payload.BlockIndex) { Log($"chain sync: expected={payload.BlockIndex} current: {Blockchain.Default?.Height}"); localNode.RequestGetBlocks(); } return; } if (payload.ValidatorIndex >= context.Validators.Length) { return; } ConsensusMessage message; try { message = ConsensusMessage.DeserializeFrom(payload.Data); } catch { return; } if (message.ViewNumber != context.ViewNumber && message.Type != ConsensusMessageType.ChangeView) { return; } switch (message.Type) { case ConsensusMessageType.ChangeView: OnChangeViewReceived(payload, (ChangeView)message); break; case ConsensusMessageType.PrepareRequest: OnPrepareRequestReceived(payload, (PrepareRequest)message); break; case ConsensusMessageType.PrepareResponse: OnPrepareResponseReceived(payload, (PrepareResponse)message); break; } } } }