예제 #1
0
        //private async Task SyncManyBlocksAsync(LyraClientForNode client, ConsolidationBlock consBlock)
        //{
        //    _log.LogInformation($"Syncing Consolidations {consBlock.Height} / {consBlock.Hash.Shorten()} ");

        //    var blocksResult = await client.GetBlocksByConsolidation(consBlock.Hash);
        //    if (blocksResult.ResultCode == APIResultCodes.Success)
        //    {
        //        foreach (var block in blocksResult.GetBlocks())
        //        {
        //            var localBlock = await _sys.Storage.FindBlockByHashAsync(block.Hash);
        //            if (localBlock != null)
        //                await _sys.Storage.RemoveBlockAsync(block.Hash);

        //            await _sys.Storage.AddBlockAsync(block);
        //        }

        //        // save cons block itself
        //        var localCons = await _sys.Storage.FindBlockByHashAsync(consBlock.Hash);
        //        if (localCons != null)
        //            await _sys.Storage.RemoveBlockAsync(consBlock.Hash);

        //        await _sys.Storage.AddBlockAsync(consBlock);
        //    }
        //}

        //private async Task SyncManyBlocksAsync(LyraClientForNode client, List<string> hashes)
        //{
        //    _log.LogInformation($"Syncing {hashes.Count()} blocks...");

        //    foreach (var hash in hashes)
        //    {
        //        var blockResult = await client.GetBlockByHash(hash);
        //        if (blockResult.ResultCode == APIResultCodes.Success)
        //        {
        //            var localBlock = await _sys.Storage.FindBlockByHashAsync(hash);
        //            if (localBlock != null)
        //                await _sys.Storage.RemoveBlockAsync(hash);

        //            await _sys.Storage.AddBlockAsync(blockResult.GetBlock());
        //        }
        //    }
        //}

        private async Task <bool> SyncOneBlockAsync(ILyraAPI client, string hash)
        {
            if (null != await _sys.Storage.FindBlockByHashAsync(hash))
            {
                await _sys.Storage.RemoveBlockAsync(hash);
            }

            var remoteBlock = await client.GetBlockByHashAsync(_sys.PosWallet.AccountId, hash, null);

            if (remoteBlock.ResultCode == APIResultCodes.Success)
            {
                var block = remoteBlock.GetBlock();

                // when block stored into database, they lost their order. so it's hard to do verification style of authorizer.
                // and mixed with code change/logic upgrade, so just use hash verify to keep database integraty.
                //if(block is TransactionBlock tb)
                //{
                //    var authorizer = factory.Create(tb.BlockType);
                //    var authResult = await authorizer.AuthorizeAsync(GetDagSystem(), tb);
                //    if (authResult.Item1 != APIResultCodes.Success)
                //    {
                //        _log.LogWarning($"SyncOneBlockAsync: TX block {tb.Hash.Shorten()} failed to verify for {authResult.Item1}");
                //    }
                //}

                // non tx block just verify hash
                if (block != null && block.VerifyHash())
                {
                    return(await _sys.Storage.AddBlockAsync(block));
                }
                else
                {
                    _log.LogWarning($"Error SyncOneBlockAsync: block null? {block is null}");
                    if (!(block is null))
                    {
                        _log.LogWarning($"Error SyncOneBlockAsync: block VerifyHash? {block.VerifyHash()}");
                    }
                    return(false);
                }
            }
            else
            {
                _log.LogWarning($"Error SyncOneBlockAsync: remote return: {remoteBlock.ResultCode}");
                return(false);
            }
        }
예제 #2
0
        private async Task <bool> SyncAndVerifyConsolidationBlockAsync(ILyraAPI client, ConsolidationBlock consBlock)
        {
            _log.LogInformation($"Sync and verify consolidation block height {consBlock.Height}");

            foreach (var hash in consBlock.blockHashes)
            {
                if (!await SyncOneBlockAsync(client, hash))
                {
                    return(false);
                }
            }

            if (null != await _sys.Storage.FindBlockByHashAsync(consBlock.Hash))
            {
                await _sys.Storage.RemoveBlockAsync(consBlock.Hash);
            }

            var mt = new MerkleTree();

            foreach (var hash1 in consBlock.blockHashes)
            {
                mt.AppendLeaf(MerkleHash.Create(hash1));
            }
            var merkelTreeHash = mt.BuildTree().ToString();

            if (consBlock.MerkelTreeHash != merkelTreeHash)
            {
                _log.LogWarning($"SyncAndVerifyConsolidationBlock: consMerkelTree: {consBlock.MerkelTreeHash} mine: {merkelTreeHash}");
                return(false);
            }

            // make sure no extra blocks here
            if (consBlock.Height > 1)
            {
                var prevConsHash   = consBlock.blockHashes.First();
                var prevConsResult = await client.GetBlockByHashAsync(_sys.PosWallet.AccountId, prevConsHash, null);

                if (prevConsResult.ResultCode != APIResultCodes.Success)
                {
                    _log.LogWarning($"SyncAndVerifyConsolidationBlock: prevConsResult.ResultCode: {prevConsResult.ResultCode}");
                    return(false);
                }

                var prevConsBlock = prevConsResult.GetBlock() as ConsolidationBlock;
                if (prevConsBlock == null)
                {
                    _log.LogWarning($"SyncAndVerifyConsolidationBlock: prevConsBlock: null");
                    return(false);
                }

                var blocksInTimeRange = await _sys.Storage.GetBlockHashesByTimeRangeAsync(prevConsBlock.TimeStamp, consBlock.TimeStamp);

                var q = blocksInTimeRange.Where(a => !consBlock.blockHashes.Contains(a));
                foreach (var extraBlock in q)
                {
                    await _sys.Storage.RemoveBlockAsync(extraBlock);
                }
            }

            return(await _sys.Storage.AddBlockAsync(consBlock));
        }