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));
        }
Exemple #2
0
        protected TransactionBlock GetBlock(BlockTypes blockType, string json)
        {
            var ar = new BlockAPIResult
            {
                ResultBlockType = blockType,
                BlockData       = json
            };

            return(ar.GetBlock() as TransactionBlock);
        }
Exemple #3
0
        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
            });
        }
Exemple #6
0
        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);
        }