private void OnTimer(Timer timer) { if (context.State.HasFlag(ConsensusState.BlockSent)) { return; } if (timer.Height != context.BlockIndex || timer.ViewNumber != context.ViewNumber) { return; } Log($"timeout: height={timer.Height} view={timer.ViewNumber} state={context.State}", LogLevel.Debug); if (context.State.HasFlag(ConsensusState.Primary) && !context.State.HasFlag(ConsensusState.RequestSent)) { // 没有新的交易请求,并且没有到最长出块时间 if (!blockchain.HasVerifiedTransaction() && TimeProvider.Current.UtcNow - block_received_time < MaxTimeSpanPerBlock) { // 等待下一次出块时间再判断是否需要出块 ChangeTimer(Blockchain.TimePerBlock); return; } context.State |= ConsensusState.RequestSent; if (!context.State.HasFlag(ConsensusState.SignatureSent)) { context.Fill(); context.SignHeader(); } Log($"send prepare request: height={timer.Height} view={timer.ViewNumber} tx={context.TransactionHashes.Length}"); localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakePrepareRequest() }); if (context.TransactionHashes.Length > 1) { foreach (InvPayload payload in InvPayload.CreateGroup(InventoryType.TX, context.TransactionHashes.Skip(1).ToArray())) { localNode.Tell(Message.Create(MessageType.Inv, payload)); } } SetNextTimer(timer.ViewNumber + 1); } else if ((context.State.HasFlag(ConsensusState.Primary) && context.State.HasFlag(ConsensusState.RequestSent)) || context.State.HasFlag(ConsensusState.Backup)) { RequestChangeView(); } }
private void OnTimer(Timer timer) { if (context.State.HasFlag(ConsensusState.BlockSent)) { return; } if (timer.Height != context.BlockIndex || timer.ViewNumber != context.ViewNumber) { return; } Log($"timeout: height={timer.Height} view={timer.ViewNumber} state={context.State}"); if (context.State.HasFlag(ConsensusState.Primary) && !context.State.HasFlag(ConsensusState.RequestSent)) { Log($"send prepare request: height={timer.Height} view={timer.ViewNumber}"); context.State |= ConsensusState.RequestSent; if (!context.State.HasFlag(ConsensusState.SignatureSent)) { context.Fill(); context.SignHeader(); } localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakePrepareRequest() }); if (context.TransactionHashes.Length > 1) { foreach (InvPayload payload in InvPayload.CreateGroup(InventoryType.TX, context.TransactionHashes.Skip(1).ToArray())) { localNode.Tell(Message.Create("inv", payload)); } } ChangeTimer(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (timer.ViewNumber + 1))); } else if ((context.State.HasFlag(ConsensusState.Primary) && context.State.HasFlag(ConsensusState.RequestSent)) || context.State.HasFlag(ConsensusState.Backup)) { RequestChangeView(); } }