예제 #1
0
        public void TryTake_EmptyCache()
        {
            int chainId   = 123;
            var blockInfo = _blockCacheEntityConsumer.Take <SideChainBlockData>(chainId, 1, false);

            Assert.Null(blockInfo);
        }
예제 #2
0
        private async Task <bool> ValidateSideChainBlockDataAsync(
            IEnumerable <SideChainBlockData> multiSideChainBlockData,
            Hash blockHash, long blockHeight)
        {
            var sideChainValidatedHeightDict = new Dictionary <int, long>(); // chain id => validated height

            foreach (var sideChainBlockData in multiSideChainBlockData)
            {
                if (!sideChainValidatedHeightDict.TryGetValue(sideChainBlockData.ChainId, out var validatedHeight))
                {
                    var height = await _contractReaderFactory
                                 .Create(new ContractReaderContext
                    {
                        BlockHash       = blockHash,
                        BlockHeight     = blockHeight,
                        ContractAddress = await GetCrossChainContractAddressAsync(new ChainContext
                        {
                            BlockHash   = blockHash,
                            BlockHeight = blockHeight
                        })
                    }).GetSideChainHeight
                                 .CallAsync(
                        new Int32Value()
                    {
                        Value = sideChainBlockData.ChainId
                    });

                    validatedHeight = height?.Value ?? 0;
                }

                var targetHeight = validatedHeight + 1;

                if (targetHeight != sideChainBlockData.Height)
                {
                    // this should not happen if it is good data.
                    return(false);
                }

                var cachedSideChainBlockData =
                    _blockCacheEntityConsumer.Take <SideChainBlockData>(sideChainBlockData.ChainId, targetHeight, false);
                if (cachedSideChainBlockData == null)
                {
                    Logger.LogDebug(
                        $"Side chain data not found. ChainId: {ChainHelper.ConvertChainIdToBase58(sideChainBlockData.ChainId)}, side chain height: {targetHeight}.");
                    return(false);
                }

                if (!cachedSideChainBlockData.Equals(sideChainBlockData))
                {
                    Logger.LogDebug(
                        $"Incorrect side chain data. ChainId: {ChainHelper.ConvertChainIdToBase58(sideChainBlockData.ChainId)}, side chain height: {targetHeight}.");
                    return(false);
                }

                sideChainValidatedHeightDict[sideChainBlockData.ChainId] = sideChainBlockData.Height;
            }

            return(true);
        }
        private async Task <List <SideChainBlockData> > GetNonIndexedSideChainBlockDataAsync(Hash blockHash,
                                                                                             long blockHeight)
        {
            var sideChainBlockDataList           = new List <SideChainBlockData>();
            var sideChainIndexingInformationList = await _readerFactory.Create(blockHash, blockHeight)
                                                   .GetSideChainIndexingInformationList.CallAsync(new Empty());

            foreach (var sideChainIndexingInformation in sideChainIndexingInformationList.IndexingInformationList)
            {
                var libDto = await _irreversibleBlockStateProvider.GetLastIrreversibleBlockHashAndHeightAsync();

                var sideChainId = sideChainIndexingInformation.ChainId;
                var sideChainHeightInLibValue = await _readerFactory.Create(libDto.BlockHash, libDto.BlockHeight)
                                                .GetSideChainHeight.CallAsync(new Int32Value {
                    Value = sideChainId
                });

                long toBeIndexedCount;
                long targetHeight;
                var  sideChainHeightInLib = sideChainHeightInLibValue?.Value ?? 0;
                if (sideChainHeightInLib > 0)
                {
                    targetHeight     = sideChainIndexingInformation.IndexedHeight + 1;
                    toBeIndexedCount = CrossChainConstants.DefaultBlockCacheEntityCount;
                    Logger.LogTrace(
                        $"Target height {targetHeight} of side chain " +
                        $"{ChainHelper.ConvertChainIdToBase58(sideChainId)}.");
                }
                else if (sideChainIndexingInformation.IndexedHeight > 0)
                {
                    toBeIndexedCount = 0;
                    targetHeight     = sideChainIndexingInformation.IndexedHeight + 1;
                }
                else
                {
                    toBeIndexedCount = 1;
                    targetHeight     = AElfConstants.GenesisBlockHeight;
                    Logger.LogTrace(
                        $"Target height {targetHeight} of side chain " +
                        $"{ChainHelper.ConvertChainIdToBase58(sideChainId)}.");
                }

                var sideChainBlockDataFromCache = new List <SideChainBlockData>();

                var i = 0;
                while (i < toBeIndexedCount)
                {
                    var sideChainBlockData =
                        _blockCacheEntityConsumer.Take <SideChainBlockData>(sideChainIndexingInformation.ChainId,
                                                                            targetHeight, targetHeight == AElfConstants.GenesisBlockHeight);
                    if (sideChainBlockData == null || sideChainBlockData.Height != targetHeight)
                    {
                        // no more available side chain block info
                        break;
                    }

                    sideChainBlockDataFromCache.Add(sideChainBlockData);
                    targetHeight++;
                    i++;
                }

                if (sideChainBlockDataFromCache.Count > 0)
                {
                    Logger.LogTrace(
                        $"Got height [{sideChainBlockDataFromCache.First().Height} - {sideChainBlockDataFromCache.Last().Height} ]" +
                        $" from side chain {ChainHelper.ConvertChainIdToBase58(sideChainIndexingInformation.ChainId)}.");
                    sideChainBlockDataList.AddRange(sideChainBlockDataFromCache);
                }
            }

            return(sideChainBlockDataList);
        }