protected override async Task HandleAsync(BlockSearchAction action, IDispatcher dispatcher) { var hashToSearch = action.hash; Block blockResult = null; Block prevBlock = null; long maxHeight = 0; string key = null; if (string.IsNullOrWhiteSpace(hashToSearch)) { var genSvcRet = await client.GetLastConsolidationBlock(); if (genSvcRet.ResultCode == APIResultCodes.Success) { blockResult = genSvcRet.GetBlock(); } } else { BlockAPIResult ret = null; if (hashToSearch.Length < 40) { ret = await client.GetServiceBlockByIndex(action.hash, action.height); } else if (hashToSearch.Length == 44 || hashToSearch.Length == 43) // hash { ret = await client.GetBlock(action.hash); } else { var exists = await client.GetAccountHeight(action.hash); if (exists.ResultCode == APIResultCodes.Success) { maxHeight = exists.Height; key = action.hash; ret = await client.GetBlockByIndex(action.hash, action.height == 0?exists.Height : action.height); } } if (ret != null && ret.ResultCode == APIResultCodes.Success) { blockResult = ret.GetBlock(); } } (key, maxHeight) = await GetMaxHeightAsync(blockResult); try { if (blockResult != null) { prevBlock = blockResult.PreviousHash == null ? null : (await client.GetBlock(blockResult.PreviousHash)).GetBlock(); } } catch (Exception) { } dispatcher.Dispatch(new BlockSearchResultAction(blockResult, prevBlock, key, maxHeight)); }
protected TransactionBlock GetBlock(BlockTypes blockType, string json) { var ar = new BlockAPIResult { ResultBlockType = blockType, BlockData = json }; return(ar.GetBlock() as TransactionBlock); }
public TransactionBlock GetLastBlock() { if (LastBlockType == BlockTypes.Null) { return(null); } var br = new BlockAPIResult { ResultBlockType = LastBlockType, BlockData = LastBlockJson, }; return(br.GetBlock() as TransactionBlock); }
private async Task <(string, long)> GetMaxHeightAsync(Block block) { BlockAPIResult lastBlockResult = null; switch (block) { case ServiceBlock sb: lastBlockResult = await client.GetLastServiceBlock(); break; case ConsolidationBlock cb: lastBlockResult = await client.GetLastConsolidationBlock(); break; case TransactionBlock tb: var tbLastResult = await client.GetAccountHeight(tb.AccountID); if (tbLastResult.ResultCode == APIResultCodes.Success) { return(tb.AccountID, tbLastResult.Height); } break; default: break; } if (lastBlockResult != null && lastBlockResult.ResultCode == APIResultCodes.Success) { var lb = lastBlockResult.GetBlock(); return(lb.BlockType.ToString(), lb.Height); } else { return(null, 0); } }
public async Task <SimpleJsonAPIResult> AuthorizeAsync(string blockType, string jsonBlock) { BlockTypes types; try { types = (BlockTypes)Enum.Parse(typeof(BlockTypes), blockType); } catch (Exception) { return(new SimpleJsonAPIResult { ResultCode = APIResultCodes.InvalidBlockType }); } var br = new BlockAPIResult { BlockData = jsonBlock, ResultBlockType = types }; var block = br.GetBlock(); if (block == null) { return(new SimpleJsonAPIResult { ResultCode = APIResultCodes.InvalidBlockData }); } // block is valid. send it to consensus network AuthorizationAPIResult result; switch (types) { case BlockTypes.SendTransfer: result = await _trans.SendTransferAsync(block as SendTransferBlock); break; case BlockTypes.ReceiveTransfer: result = await _trans.ReceiveTransferAsync(block as ReceiveTransferBlock); break; case BlockTypes.OpenAccountWithReceiveTransfer: result = await _trans.ReceiveTransferAndOpenAccountAsync(block as OpenWithReceiveTransferBlock); break; case BlockTypes.TokenGenesis: result = await _trans.CreateTokenAsync(block as TokenGenesisBlock); break; default: result = null; break; } if (result == null) { return new SimpleJsonAPIResult { ResultCode = APIResultCodes.UnsupportedBlockType } } ; return(new SimpleJsonAPIResult { ResultCode = result.ResultCode }); }
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); }