public virtual async Task <AppState> CommitBlock(int head) { var state = Cache.AppState.Get(); Logger.LogDebug($"Load block {state.Level + 1}"); var block = await Rpc.GetBlockAsync(state.Level + 1); Logger.LogDebug("Begin DB transaction"); using var tx = await Db.Database.BeginTransactionAsync(); try { Logger.LogDebug("Warm up cache"); await WarmUpCache(block); if (Config.Validation) { Logger.LogDebug("Validate block"); await Validator.ValidateBlock(block); } Logger.LogDebug("Process block"); await Commit(block); var nextProtocol = this; if (state.Protocol != state.NextProtocol) { Logger.LogDebug($"Activate next protocol {state.NextProtocol.Substring(0, 8)}"); nextProtocol = Services.GetProtocolHandler(state.Level + 1, state.NextProtocol); await nextProtocol.Activate(state, block); } Logger.LogDebug("Touch accounts"); TouchAccounts(); if (Config.Diagnostics) { Logger.LogDebug("Diagnostics"); await nextProtocol.Diagnostics.Run(block); } Logger.LogDebug("Save changes"); await Db.SaveChangesAsync(); Logger.LogDebug("Save post-changes"); await AfterCommit(block); Logger.LogDebug("Process quotes"); await Quotes.Commit(); Logger.LogDebug("Commit DB transaction"); await tx.CommitAsync(); } catch (Exception) { await tx.RollbackAsync(); throw; } ClearCachedRelations(); return(Cache.AppState.Get()); }