protected override Task WorkAction()
{
using (updatedTracker.TryUpdate(staleAction: NotifyWork))
{
try
{
foreach (var pathElement in unconfirmedTxesBuilder.Chain.NavigateTowards(() => chainStateWorker.CurrentChain))
{
// cooperative loop
ThrowIfCancelled();
// get block and metadata for next link in blockchain
var direction = pathElement.Item1;
var chainedHeader = pathElement.Item2;
IEnumerator<BlockTx> blockTxes;
if (!coreStorage.TryReadBlockTransactions(chainedHeader.Hash, out blockTxes))
{
BlockMissed?.Invoke(this, chainedHeader.Hash);
break;
}
if (direction > 0)
unconfirmedTxesBuilder.AddBlock(chainedHeader, blockTxes.UsingAsEnumerable());
else if (direction < 0)
unconfirmedTxesBuilder.RollbackBlock(chainedHeader, blockTxes.UsingAsEnumerable());
else
throw new InvalidOperationException();
currentChain = new Lazy<Chain>(() => unconfirmedTxesBuilder.Chain);
OnChanged?.Invoke(this, EventArgs.Empty);
}
}
catch (OperationCanceledException) { }
catch (AggregateException ex)
{
foreach (var innerException in ex.Flatten().InnerExceptions)
HandleException(innerException);
}
catch (Exception ex)
{
HandleException(ex);
}
}
return Task.CompletedTask;
}