public static void Save(LocalDbSyncState state) { var fn = $"{Utilities.GetLyraDataDir(Neo.Settings.Default.LyraNode.Lyra.NetworkId, LyraGlobal.OFFICIALDOMAIN)}{Utilities.PathSeperator}syncState.json"; var str = JsonConvert.SerializeObject(state); File.WriteAllText(fn, str); }
private async Task <bool> SyncDatabaseAsync(ILyraAPI client) { var consensusClient = client; BlockAPIResult seedSvcGen = null; for (int i = 0; i < 10; i++) { seedSvcGen = await consensusClient.GetServiceGenesisBlockAsync(); if (seedSvcGen.ResultCode == APIResultCodes.Success) { break; } await Task.Delay(10 * 1000); _log.LogInformation("Recreate aggregated client..."); //await client.InitAsync(); } var localDbState = await GetNodeStatusAsync(); if (localDbState.totalBlockCount == 0) { LocalDbSyncState.Remove(); } else { var oldState = LocalDbSyncState.Load(); if (oldState.svcGenHash != seedSvcGen.GetBlock().Hash) { LocalDbSyncState.Remove(); } //if(oldState.databaseVersion > 0 && oldState.databaseVersion < LyraGlobal.DatabaseVersion) //{ // // should upgrade database or resync completely // _sys.Storage.Delete(true); // LocalDbSyncState.Remove(); // localDbState = await GetNodeStatusAsync(); //} } var localState = LocalDbSyncState.Load(); if (localState.svcGenHash == null) { localState.svcGenHash = seedSvcGen.GetBlock().Hash; localState.databaseVersion = LyraGlobal.DatabaseVersion; } var lastCons = (await consensusClient.GetLastConsolidationBlockAsync()).GetBlock() as ConsolidationBlock; if (lastCons == null) { return(false); } bool IsSuccess = true; var _authorizers = new AuthorizersFactory(); while (true) { try { var remoteConsQuery = await consensusClient.GetConsolidationBlocksAsync(_sys.PosWallet.AccountId, null, localState.lastVerifiedConsHeight + 1, 1); if (remoteConsQuery.ResultCode == APIResultCodes.Success) { var remoteConsBlocks = remoteConsQuery.GetBlocks(); if (remoteConsBlocks.Any()) { foreach (var block in remoteConsBlocks) { var consTarget = block as ConsolidationBlock; _log.LogInformation($"SyncDatabase: Sync consolidation block {consTarget.Height} of total {lastCons.Height}."); if (await SyncAndVerifyConsolidationBlockAsync(consensusClient, consTarget)) { _log.LogInformation($"Consolidation block {consTarget.Height} is OK."); localState.lastVerifiedConsHeight = consTarget.Height; LocalDbSyncState.Save(localState); } else { throw new Exception($"Consolidation block {consTarget.Height} is failure."); } } } else { IsSuccess = true; break; } } else if (remoteConsQuery.ResultCode == APIResultCodes.APIRouteFailed) { _log.LogWarning("Got inconsistant result from network. retry later."); throw new Exception("Failed to sync. reason: " + remoteConsQuery.ResultCode); } else { _log.LogWarning($"Unexpected error {remoteConsQuery.ResultCode}: {remoteConsQuery.ResultMessage}. retry later."); throw new Exception($"Failed to sync. reason: {remoteConsQuery.ResultCode}: {remoteConsQuery.ResultMessage}"); } } catch (Exception ex) { _log.LogWarning("SyncDatabase Exception: " + ex.Message); await Task.Delay(30000); IsSuccess = false; break; } } return(IsSuccess); }