public void DeferredBroadcast(ushort round, Action onBroadcasted) { if (_synchronizationContext == null) { return; } //if (_synchronizationContext.LastBlockDescriptor != null && _synchronizationContext.LastBlockDescriptor.BlockHeight - 1 > _lastLaunchedSyncBlockOrder) //{ // _syncProducingCancellation?.Cancel(); // _syncProducingCancellation = null; //} int delay = 1; if (_syncProducingCancellation != null) { delay = Math.Max((int)(60000 * round - (DateTime.Now - (_synchronizationContext.LastBlockDescriptor?.UpdateTime ?? DateTime.Now)).TotalMilliseconds), 0); } _syncProducingCancellation = new CancellationTokenSource(); //if (delay > 0) { Task.Delay(delay, _syncProducingCancellation.Token) .ContinueWith(t => { try { SynchronizationDescriptor synchronizationDescriptor = _synchronizationContext.LastBlockDescriptor; SynchronizationProducingBlock synchronizationBlock = new SynchronizationProducingBlock { SyncBlockHeight = synchronizationDescriptor?.BlockHeight ?? 0, BlockHeight = (synchronizationDescriptor?.BlockHeight ?? 0) + 1, ReportedTime = synchronizationDescriptor?.MedianTime.AddMinutes(1) ?? DateTime.Now, Round = round, HashPrev = synchronizationDescriptor?.Hash ?? new byte[Globals.DEFAULT_HASH_SIZE], PowHash = _proofOfWorkCalculation.CalculateHash(synchronizationDescriptor?.Hash ?? new byte[Globals.DEFAULT_HASH_SIZE]) }; using (ISerializer serializer = _serializersFactory.Create(synchronizationBlock)) { serializer.SerializeBody(); _nodeContext.SigningService.Sign(synchronizationBlock); _communicationService.PostMessage(_synchronizationGroupState.GetAllNeighbors(), serializer); _lastLaunchedSyncBlockOrder = synchronizationBlock.BlockHeight; } } finally { onBroadcasted.Invoke(); } }, _syncProducingCancellation.Token, TaskContinuationOptions.NotOnCanceled, TaskScheduler.Current); } }
protected override Memory <byte> ParseSynchronization(ushort version, Memory <byte> spanBody, out SynchronizationBlockBase synchronizationBlockBase) { if (version == 1) { ushort round = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span); SynchronizationProducingBlock synchronizationBlock = new SynchronizationProducingBlock { Round = round }; synchronizationBlockBase = synchronizationBlock; return(spanBody.Slice(2)); } throw new BlockVersionNotSupportedException(version, BlockType); }
private async void RetransmitSynchronizationBlock(SynchronizationProducingBlock synchronizationBlockV1) { SynchronizationBlockRetransmissionV1 synchronizationBlockRetransmissionForSend = new SynchronizationBlockRetransmissionV1() { BlockHeight = synchronizationBlockV1.BlockHeight, ReportedTime = synchronizationBlockV1.ReportedTime, OffsetSinceLastMedian = (ushort)(DateTime.Now - _synchronizationContext.LastBlockDescriptor.UpdateTime).TotalSeconds, ConfirmationPublicKey = synchronizationBlockV1.Signer.Value.ToArray(), ConfirmationSignature = synchronizationBlockV1.Signature.ToArray(), Signer = _accountState.AccountKey }; //TODO: refactor //byte[] body = _signatureSupportSerializersFactory.Create(PacketType.Synchronization, BlockTypes.Synchronization_RetransmissionBlock).GetBytes(synchronizationBlockRetransmissionForSend); //synchronizationBlockRetransmissionForSend.Signature = _cryptoService.Sign(body); //TODO: complete logic of sync block propagation //await _communicationHub.PostMessage(synchronizationBlockRetransmissionForSend); _retransmittedBlocks.TryAdd(synchronizationBlockRetransmissionForSend); }