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

            var lastQueuedHeight = _targetHeight - 1;

            return(!isCacheSizeLimited || lastQueuedHeight >= height + CrossChainConstants.DefaultBlockCacheEntityCount);
        }
Beispiel #2
0
        /// <summary>
        /// Cache block info lately removed.
        /// Dequeue one element if the cached count reaches <see cref="CrossChainConstants.ChainCacheEntityCapacity"/>
        /// </summary>
        /// <param name="blockCacheEntity"></param>
        private bool TryDequeue(out IBlockCacheEntity blockCacheEntity)
        {
            var res = BlockCacheEntities.TryTake(out blockCacheEntity,
                                                 CrossChainConstants.WaitingIntervalInMillisecond);

            if (res)
            {
                DequeuedBlockCacheEntities.Add(blockCacheEntity);
            }

            return(res);
        }
Beispiel #3
0
        public bool TryAdd(IBlockCacheEntity blockCacheEntity)
        {
            if (BlockCacheEntities.Count >= CrossChainConstants.ChainCacheEntityCapacity)
            {
                return(false);
            }
            // thread unsafe in some extreme cases, but it can be covered with caching mechanism.
            if (blockCacheEntity.Height != TargetChainHeight())
            {
                return(false);
            }
            var res = BlockCacheEntities.TryAdd(blockCacheEntity);

            return(res);
        }
Beispiel #4
0
        public bool TryAdd(IBlockCacheEntity blockCacheEntity)
        {
            if (blockCacheEntity.Height != TargetChainHeight())
            {
                return(false);
            }
            var res = ValidateBlockCacheEntity(blockCacheEntity) &&
                      _cache.TryAdd(blockCacheEntity.Height, blockCacheEntity);

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

            var res = chainCacheEntity.TryAdd(blockCacheEntity);

            Logger.LogTrace(
                $"Cached height {blockCacheEntity.Height} from chain {ChainHelper.ConvertChainIdToBase58(blockCacheEntity.ChainId)}, {res}");
            return(res);
        }
Beispiel #6
0
        /// <summary>
        /// Try take element from cached queue.
        /// Make sure that more than <see cref="CrossChainConstants.MinimalBlockCacheEntityCount"/> block cache entities are left in <see cref="BlockCacheEntities"/>.
        /// </summary>
        /// <param name="height">Height of block info needed</param>
        /// <param name="blockCacheEntity"></param>
        /// <param name="isCacheSizeLimited">Use <see cref="CrossChainConstants.ChainCacheEntityCapacity"/> as cache count threshold if true.</param>
        /// <returns></returns>
        public bool TryTake(long height, out IBlockCacheEntity blockCacheEntity, bool isCacheSizeLimited)
        {
            // clear outdated data
            var cachedInQueue = DequeueBlockCacheEntitiesBeforeHeight(height);
            // isCacheSizeLimited means minimal caching size limit, so that most nodes have this block.
            var lastQueuedHeight = BlockCacheEntities.LastOrDefault()?.Height ?? 0;

            if (cachedInQueue && !(isCacheSizeLimited && lastQueuedHeight < height + CrossChainConstants.MinimalBlockCacheEntityCount))
            {
                return(TryDequeue(out blockCacheEntity));
            }

            blockCacheEntity = GetLastDequeuedBlockCacheEntity(height);
            if (blockCacheEntity != null)
            {
                return(!isCacheSizeLimited ||
                       BlockCacheEntities.Count + DequeuedBlockCacheEntities.Count(ci => ci.Height >= height)
                       >= CrossChainConstants.MinimalBlockCacheEntityCount);
            }

            return(false);
        }
Beispiel #7
0
 private bool ValidateBlockCacheEntity(IBlockCacheEntity blockCacheEntity)
 {
     return(blockCacheEntity.Height >= AElfConstants.GenesisBlockHeight &&
            blockCacheEntity.ChainId == _chainId &&
            blockCacheEntity.TransactionStatusMerkleTreeRoot != null);
 }