/// <summary>
        /// Try take element from cached queue.
        /// </summary>
        /// <param name="height">Height of block info needed</param>
        /// <param name="crossChainBlockEntity"></param>
        /// <param name="isCacheSizeLimited">Use <see cref="CrossChainConstants.ChainCacheEntityCapacity"/> as cache count threshold if true.</param>
        /// <returns></returns>
        public bool TryTake(long height, out ICrossChainBlockEntity crossChainBlockEntity, bool isCacheSizeLimited)
        {
            // clear outdated data
            if (!_cache.TryGetValue(height, out crossChainBlockEntity))
            {
                return(false);
            }

            var lastQueuedHeight = _targetHeight - 1;

            return(!isCacheSizeLimited || lastQueuedHeight >= height + CrossChainConstants.DefaultBlockCacheEntityCount);
        }
        public bool TryAdd(ICrossChainBlockEntity crossChainBlockEntity)
        {
            if (crossChainBlockEntity.Height != TargetChainHeight())
            {
                return(false);
            }
            var res = ValidateBlockCacheEntity(crossChainBlockEntity) &&
                      _cache.TryAdd(crossChainBlockEntity.Height, crossChainBlockEntity);

            if (res)
            {
                _targetHeight = crossChainBlockEntity.Height + 1;
            }
            return(res);
        }
        public bool TryAddBlockCacheEntity(ICrossChainBlockEntity crossChainBlockEntity)
        {
            if (crossChainBlockEntity == null)
            {
                throw new ArgumentNullException(nameof(crossChainBlockEntity));
            }
            if (!_crossChainCacheEntityProvider.TryGetChainCacheEntity(crossChainBlockEntity.ChainId, out var chainCacheEntity))
            {
                return(false);
            }

            var res = chainCacheEntity.TryAdd(crossChainBlockEntity);

            Logger.LogDebug(
                $"Cached height {crossChainBlockEntity.Height} from chain {ChainHelper.ConvertChainIdToBase58(crossChainBlockEntity.ChainId)}, {res}");
            return(res);
        }
 private bool ValidateBlockCacheEntity(ICrossChainBlockEntity crossChainBlockEntity)
 {
     return(crossChainBlockEntity.Height >= AElfConstants.GenesisBlockHeight &&
            crossChainBlockEntity.ChainId == _chainId &&
            crossChainBlockEntity.TransactionStatusMerkleTreeRoot != null);
 }