public async Task MergeBlockStateAsync(ChainStateInfo chainStateInfo, Hash blockStateHash)
        {
            var blockState = await _blockStateSets.GetAsync(blockStateHash.ToStorageKey());

            if (blockState == null)
            {
                if (chainStateInfo.Status == ChainStateMergingStatus.Merged &&
                    chainStateInfo.MergingBlockHash == blockStateHash)
                {
                    chainStateInfo.Status           = ChainStateMergingStatus.Common;
                    chainStateInfo.MergingBlockHash = null;

                    await _chainStateInfoCollection.SetAsync(chainStateInfo.ChainId.ToStorageKey(), chainStateInfo);

                    return;
                }

                throw new InvalidOperationException($"cannot get block state of {blockStateHash}");
            }

            if (chainStateInfo.BlockHash == null || chainStateInfo.BlockHash == blockState.PreviousHash)
            {
                chainStateInfo.Status           = ChainStateMergingStatus.Merging;
                chainStateInfo.MergingBlockHash = blockStateHash;

                await _chainStateInfoCollection.SetAsync(chainStateInfo.ChainId.ToStorageKey(), chainStateInfo);

                var dic = blockState.Changes.Select(change => new VersionedState()
                {
                    Key         = change.Key,
                    Value       = change.Value,
                    BlockHash   = blockState.BlockHash,
                    BlockHeight = blockState.BlockHeight,
                    //OriginBlockHash = origin.BlockHash
                }).ToDictionary(p => p.Key, p => p);

                await _versionedStates.PipelineSetAsync(dic);

                chainStateInfo.Status      = ChainStateMergingStatus.Merged;
                chainStateInfo.BlockHash   = blockState.BlockHash;
                chainStateInfo.BlockHeight = blockState.BlockHeight;
                await _chainStateInfoCollection.SetAsync(chainStateInfo.ChainId.ToStorageKey(), chainStateInfo);

                await _blockStateSets.RemoveAsync(blockStateHash.ToStorageKey());

                chainStateInfo.Status           = ChainStateMergingStatus.Common;
                chainStateInfo.MergingBlockHash = null;

                await _chainStateInfoCollection.SetAsync(chainStateInfo.ChainId.ToStorageKey(), chainStateInfo);
            }
            else
            {
                throw new InvalidOperationException(
                          "cannot merge block not linked, check new block's previous block hash ");
            }
        }
示例#2
0
 public async Task PipelineSetAsync(Dictionary <string, T> pipelineSet)
 {
     await _stateStoreImplementation.PipelineSetAsync(pipelineSet);
 }