public async Task BlockState_NoNeed_To_Merge()
        {
            var lastIrreversibleBlockHeight = -2;
            var lastIrreversibleBlockHash   = Hash.Generate();

            await _blockchainStateMergingService.MergeBlockStateAsync(lastIrreversibleBlockHeight,
                                                                      lastIrreversibleBlockHash);

            var chainStateInfo = await _blockchainStateManager.GetChainStateInfoAsync();

            chainStateInfo.BlockHeight.ShouldNotBe(lastIrreversibleBlockHeight);
            chainStateInfo.MergingBlockHash.ShouldNotBe(lastIrreversibleBlockHash);
        }
        public async Task MergeBlockStateAsync(long lastIrreversibleBlockHeight, Hash lastIrreversibleBlockHash)
        {
            var chainStateInfo = await _blockchainStateManager.GetChainStateInfoAsync();

            var firstHeightToMerge = chainStateInfo.BlockHeight == 0L
                ? Constants.GenesisBlockHeight
                : chainStateInfo.BlockHeight + 1;
            var mergeCount = lastIrreversibleBlockHeight - firstHeightToMerge;

            if (mergeCount < 0)
            {
                Logger.LogWarning(
                    $"Last merge height: {chainStateInfo.BlockHeight}, lib height: {lastIrreversibleBlockHeight}, needn't merge");
                return;
            }

            var blockIndexes = new List <IBlockIndex>();

            if (chainStateInfo.Status == ChainStateMergingStatus.Merged)
            {
                blockIndexes.Add(new BlockIndex(chainStateInfo.MergingBlockHash, -1));
            }

            var reversedBlockIndexes = await _blockchainService.GetReversedBlockIndexes(lastIrreversibleBlockHash, (int)mergeCount);

            reversedBlockIndexes.Reverse();

            blockIndexes.AddRange(reversedBlockIndexes);

            blockIndexes.Add(new BlockIndex(lastIrreversibleBlockHash, lastIrreversibleBlockHeight));

            Logger.LogTrace(
                $"Start merge lib height: {lastIrreversibleBlockHeight}, lib block hash: {lastIrreversibleBlockHash}, merge count: {blockIndexes.Count}");

            foreach (var blockIndex in blockIndexes)
            {
                try
                {
                    Logger.LogDebug($"Merging state {chainStateInfo} for block {blockIndex}");
                    await _blockchainStateManager.MergeBlockStateAsync(chainStateInfo, blockIndex.Hash);
                }
                catch (Exception e)
                {
                    Logger.LogError(e,
                                    $"Exception while merge state {chainStateInfo} for block {blockIndex}");
                    throw;
                }
            }
        }
Example #3
0
        public async Task InitContractInfoCacheAsync()
        {
            if (!_contractInfoCache.IsEmpty)
            {
                return;
            }

            var chainContractInfo = await _blockchainStateManager.GetChainContractInfoAsync();

            if (chainContractInfo.ContractInfos.IsNullOrEmpty())
            {
                return;
            }
            var chainStateInfo = await _blockchainStateManager.GetChainStateInfoAsync();

            chainContractInfo.ContractInfos.RemoveAll(c => c.Value <= chainStateInfo.BlockHeight);
            await _blockchainStateManager.SetChainContractInfoAsync(chainContractInfo);

            foreach (var key in chainContractInfo.ContractInfos.Keys)
            {
                _contractInfoCache[AddressHelper.Base58StringToAddress(key)] = chainContractInfo.ContractInfos[key];
            }
        }