示例#1
0
        public async Task <T> GetAsync(string key)
        {
            if (_cache.TryGetValue(key, out var item))
            {
                return(item);
            }

            var state = await _stateStoreImplementation.GetAsync(key);

            if (state != null)
            {
                _toBeCleanedKeys.Enqueue(key);
                while (_toBeCleanedKeys.Count > 1024)
                {
                    try
                    {
                        if (_toBeCleanedKeys.TryDequeue(out var cleanKey))
                        {
                            _cache.TryRemove(cleanKey, out _);
                        }
                    }
                    catch
                    {
                        //ignore concurrency exceptions
                    }
                }

                _cache[key] = state;
            }

            return(state);
        }
        public async Task GlobalSetup()
        {
            _chains = GetRequiredService <IBlockchainStore <Chain> >();
            _chainStateInfoCollection = GetRequiredService <IStateStore <ChainStateInfo> >();
            _blockchainStateService   = GetRequiredService <IBlockchainStateService>();
            _blockStateSetManger      = GetRequiredService <IBlockStateSetManger>();
            _blockchainService        = GetRequiredService <IBlockchainService>();
            _osTestHelper             = GetRequiredService <OSTestHelper>();
            _chainManager             = GetRequiredService <IChainManager>();
            _blockManager             = GetRequiredService <IBlockManager>();
            _transactionManager       = GetRequiredService <ITransactionManager>();
            _transactionPoolService   = GetRequiredService <ITransactionPoolService>();


            _blockStateSets = new List <BlockStateSet>();
            _blocks         = new List <Block>();

            _chain = await _blockchainService.GetChainAsync();

            var blockHash = _chain.BestChainHash;

            while (true)
            {
                var blockState = await _blockStateSetManger.GetBlockStateSetAsync(blockHash);

                _blockStateSets.Add(blockState);

                var blockHeader = await _blockchainService.GetBlockHeaderByHashAsync(blockHash);

                blockHash = blockHeader.PreviousBlockHash;
                if (blockHash == _chain.LastIrreversibleBlockHash)
                {
                    break;
                }
            }

            await _blockchainStateService.MergeBlockStateAsync(_chain.BestChainHeight, _chain.BestChainHash);

            for (var i = 0; i < BlockCount; i++)
            {
                var transactions = await _osTestHelper.GenerateTransferTransactions(TransactionCount);

                await _osTestHelper.BroadcastTransactions(transactions);

                var block = await _osTestHelper.MinedOneBlock();

                _blocks.Add(block);

                var blockState = await _blockStateSetManger.GetBlockStateSetAsync(block.GetHash());

                _blockStateSets.Add(blockState);
            }

            var chain = await _blockchainService.GetChainAsync();

            await _chainManager.SetIrreversibleBlockAsync(chain, chain.BestChainHash);

            _chainStateInfo = await _chainStateInfoCollection.GetAsync(chain.Id.ToStorageKey());
        }
示例#3
0
        public async Task <ChainContractInfo> GetChainContractInfoAsync()
        {
            var chainContractInfo = await _chainContractInfoCollection.GetAsync(_chainId.ToStorageKey());

            return(chainContractInfo ?? new ChainContractInfo {
                ChainId = _chainId
            });
        }
        public async Task <ChainStateInfo> GetChainStateInfoAsync()
        {
            var o = await _chainStateInfoCollection.GetAsync(_chainId.ToStorageKey());

            return(o ?? new ChainStateInfo()
            {
                ChainId = _chainId
            });
        }
示例#5
0
        public async Task <T> GetAsync(string key)
        {
            if (_cache.TryGetValue(key, out var item))
            {
                return(item);
            }

            var state = await _stateStoreImplementation.GetAsync(key);

            if (state != null)
            {
                _cache[key] = state;
            }

            return(state);
        }
        public async Task <DateTime> Now(CancellationToken cancellationToken = default)
        {
            var result = default(DateTime);

            try
            {
                result = _opt.UseDatetimeCache
                    ? await _stateStore.GetAsync(_opt.DatetimeKey, new CancellationTokenSource(200).Token)
                    : DateTime.UtcNow;
            }
            catch (Exception)
            {
            }

            return(result == default ? DateTime.UtcNow : result);
        }
示例#7
0
        public async Task <DateTime> Now(CancellationToken cancellationToken = default)
        {
            var result = default(DateTime);

            try
            {
                result = _opt.UseDatetimeCache
                    ? await _stateStore.GetAsync(_opt.DatetimeKey, new CancellationTokenSource(200).Token)
                    : DateTime.UtcNow;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "DaprDateTimeCache Unhandled Exception");
            }

            return(result == default ? DateTime.UtcNow : result);
        }
示例#8
0
        public async Task <byte[]> GetAsync(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (_cache.TryGetValue(key, out var value))
            {
                return(value.Get());
            }

            var bytes = await _stateStore.GetAsync(GetStatePathFor(key));

            _cache[key] = StateValue.Create(bytes);
            return(bytes);
        }
示例#9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <param name="blockHeight"></param>
        /// <param name="blockHash">should already in store</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public async Task <ByteString> GetStateAsync(string key, long blockHeight, Hash blockHash)
        {
            ByteString value = null;

            //first DB read
            var bestChainState = await _versionedStates.GetAsync(key);

            if (bestChainState != null)
            {
                if (bestChainState.BlockHash == blockHash)
                {
                    value = bestChainState.Value;
                }
                else
                {
                    if (bestChainState.BlockHeight >= blockHeight)
                    {
                        //because we may clear history state
                        throw new InvalidOperationException($"cannot read history state, best chain state hash: {bestChainState.BlockHash.ToHex()}, key: {key}, block height: {blockHeight}, block hash{blockHash.ToHex()}");
                    }
                    else
                    {
                        //find value in block state set
                        var blockStateKey = blockHash.ToStorageKey();
                        var blockStateSet = await _blockStateSets.GetAsync(blockStateKey);

                        while (blockStateSet != null && blockStateSet.BlockHeight > bestChainState.BlockHeight)
                        {
                            if (blockStateSet.Deletes.Contains(key))
                            {
                                break;
                            }

                            if (blockStateSet.Changes.ContainsKey(key))
                            {
                                value = blockStateSet.Changes[key];
                                break;
                            }

                            blockStateKey = blockStateSet.PreviousHash?.ToStorageKey();

                            if (blockStateKey != null)
                            {
                                blockStateSet = await _blockStateSets.GetAsync(blockStateKey);
                            }
                            else
                            {
                                blockStateSet = null;
                            }
                        }

                        if (value == null && (blockStateSet == null || !blockStateSet.Deletes.Contains(key) || blockStateSet.BlockHeight <= bestChainState.BlockHeight))
                        {
                            //not found value in block state sets. for example, best chain is 100, blockHeight is 105,
                            //it will find 105 ~ 101 block state set. so the value could only be the best chain state value.
                            // retry versioned state in case conflict of get state during merging
                            bestChainState = await _versionedStates.GetAsync(key);

                            value = bestChainState.Value;
                        }
                    }
                }
            }
            else
            {
                //best chain state is null, it will find value in block state set
                var blockStateKey = blockHash.ToStorageKey();
                var blockStateSet = await _blockStateSets.GetAsync(blockStateKey);

                while (blockStateSet != null)
                {
                    if (blockStateSet.Deletes.Contains(key))
                    {
                        break;
                    }

                    if (blockStateSet.Changes.ContainsKey(key))
                    {
                        value = blockStateSet.Changes[key];
                        break;
                    }

                    blockStateKey = blockStateSet.PreviousHash?.ToStorageKey();

                    if (blockStateKey != null)
                    {
                        blockStateSet = await _blockStateSets.GetAsync(blockStateKey);
                    }
                    else
                    {
                        blockStateSet = null;
                    }
                }

                if (value == null && blockStateSet == null)
                {
                    // retry versioned state in case conflict of get state during merging
                    bestChainState = await _versionedStates.GetAsync(key);

                    value = bestChainState?.Value;
                }
            }

            return(value);
        }
示例#10
0
        protected async Task <StateReturn> GetAsync(string key, long blockHeight, Hash blockHash)
        {
            ByteString value     = null;
            var        isInStore = false;
            //first DB read
            var bestChainState = await _versionedStates.GetAsync(key);

            if (bestChainState != null)
            {
                if (bestChainState.BlockHash == blockHash)
                {
                    value     = bestChainState.Value;
                    isInStore = true;
                }
                else
                {
                    if (bestChainState.BlockHeight >= blockHeight)
                    {
                        //because we may clear history state
                        throw new InvalidOperationException(
                                  $"cannot read history state, best chain state hash: {bestChainState.BlockHash.ToHex()}, key: {key}, block height: {blockHeight}, block hash{blockHash.ToHex()}");
                    }

                    //find value in block state set
                    var blockStateSet = await FindBlockStateSetWithKeyAsync(key, bestChainState.BlockHeight, blockHash);

                    TryGetFromBlockStateSet(blockStateSet, key, out value);

                    if (value == null && (blockStateSet == null || !blockStateSet.Deletes.Contains(key) ||
                                          blockStateSet.BlockHeight <= bestChainState.BlockHeight))
                    {
                        //not found value in block state sets. for example, best chain is 100, blockHeight is 105,
                        //it will find 105 ~ 101 block state set. so the value could only be the best chain state value.
                        // retry versioned state in case conflict of get state during merging
                        bestChainState = await _versionedStates.GetAsync(key);

                        value     = bestChainState.Value;
                        isInStore = true;
                    }
                }
            }
            else
            {
                //best chain state is null, it will find value in block state set
                var blockStateSet = await FindBlockStateSetWithKeyAsync(key, 0, blockHash);

                TryGetFromBlockStateSet(blockStateSet, key, out value);

                if (value == null && blockStateSet == null)
                {
                    // retry versioned state in case conflict of get state during merging
                    bestChainState = await _versionedStates.GetAsync(key);

                    value = bestChainState?.Value;
                }
            }


            return(new StateReturn()
            {
                Value = value,
                IsInStore = isInStore
            });
        }
        public async Task WrongParallelTest()
        {
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.SetIrreversibleBlockAsync(chain, chain.BestChainHeight, chain.BestChainHash);

            //prepare token for tx verify
            var(tokenTransactions, groupUsers) =
                await _parallelTestHelper.PrepareTokenForParallel(_groupCount, 1000_00000000);

            await _parallelTestHelper.BroadcastTransactions(tokenTransactions);

            var prepareBlock =
                _parallelTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, tokenTransactions);

            prepareBlock =
                (await _blockExecutingService.ExecuteBlockAsync(prepareBlock.Header,
                                                                tokenTransactions)).Block;
            await _blockchainService.AddBlockAsync(prepareBlock);

            await _blockAttachService.AttachBlockAsync(prepareBlock);

            chain = await _blockchainService.GetChainAsync();

            var transactions =
                _parallelTestHelper.GenerateBasicFunctionWithParallelTransactions(groupUsers, _transactionCount);
            var transferTransaction = await _parallelTestHelper.GenerateTransferTransaction(Address.FromPublicKey(groupUsers[1].PublicKey)
                                                                                            , "ELF", 10);

            transactions.Add(transferTransaction);
            await _parallelTestHelper.BroadcastTransactions(transactions);

            var otherTransactions        = _parallelTestHelper.GenerateBasicFunctionWithParallelTransactions(groupUsers, _transactionCount);
            var otherTransferTransaction = await _parallelTestHelper.GenerateTransferTransaction(Address.FromPublicKey(groupUsers[2].PublicKey)
                                                                                                 , "ELF", 10);

            otherTransactions.Add(otherTransferTransaction);
            await _parallelTestHelper.BroadcastTransactions(otherTransactions);

            var transferTransactions = await _parallelTestHelper.GenerateTransferTransactions(16);

            await _parallelTestHelper.BroadcastTransactions(transferTransactions);

            var poolSize = (await _txHub.GetTransactionPoolStatusAsync()).AllTransactionCount;

            poolSize.ShouldBe(transactions.Count * 2 + transferTransactions.Count);

            var groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(_transactionCount + 1);
            groupedTransactions.NonParallelizables.Count.ShouldBe(0);
            for (var i = 0; i < transactions.Count; i++)
            {
                transactions[i].GetHash().ShouldBe(groupedTransactions.Parallelizables[i][0].GetHash());
            }

            var otherGroupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                otherTransactions);

            otherGroupedTransactions.Parallelizables.Count.ShouldBe(_transactionCount + 1);
            otherGroupedTransactions.NonParallelizables.Count.ShouldBe(0);

            var groupedTransferTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transferTransactions);

            groupedTransferTransactions.Parallelizables.Count.ShouldBe(1);
            groupedTransferTransactions.Parallelizables[0].Count.ShouldBe(transferTransactions.Count);
            groupedTransferTransactions.NonParallelizables.Count.ShouldBe(0);

            _localEventBus.Subscribe <ConflictingTransactionsFoundInParallelGroupsEvent>(e =>
            {
                e.ConflictingSets.Count.ShouldBe(_groupCount + 1);
                e.ExistingSets.Count.ShouldBe(_groupCount);
                return(Task.CompletedTask);
            });

            var block = _parallelTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, transactions);

            block = (await _blockExecutingService.ExecuteBlockAsync(block.Header, transactions)).Block;
            block.TransactionIds.Count().ShouldBe(_transactionCount + 1);

            var transactionResults = await GetTransactionResultsAsync(block.Body.TransactionIds.ToList(), block.Header);

            transactionResults.Count(t => t.Status == TransactionResultStatus.Mined).ShouldBe(_groupCount);
            transactionResults.Count(t => t.Status == TransactionResultStatus.Conflict).ShouldBe(_groupCount + 1);
            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            var accountAddress = await _accountService.GetAccountAsync();

            var chainContext = new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            };
            var tokenContractAddress =
                await _smartContractAddressService.GetAddressByContractNameAsync(chainContext, TokenSmartContractAddressNameProvider.StringName);

            var nonparallelContractCode =
                await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(chainContext,
                                                                                       tokenContractAddress);

            nonparallelContractCode.ShouldBeNull();

            foreach (var transaction in transactions)
            {
                if (transaction.To == tokenContractAddress)
                {
                    continue;
                }
                var param = IncreaseWinMoneyInput.Parser.ParseFrom(transaction.Params);
                var input = new QueryTwoUserWinMoneyInput
                {
                    First  = param.First,
                    Second = param.Second
                };
                var queryTransaction = _parallelTestHelper.GenerateTransaction(accountAddress,
                                                                               ParallelTestHelper.BasicFunctionWithParallelContractAddress,
                                                                               nameof(BasicFunctionWithParallelContract.QueryTwoUserWinMoney), input);
                var byteString = await _parallelTestHelper.ExecuteReadOnlyAsync(queryTransaction, block.GetHash(), block.Height);

                var output = TwoUserMoneyOut.Parser.ParseFrom(byteString);
                output.FirstInt64Value.ShouldBe(1);
                var result = transactionResults.First(t => t.TransactionId == transaction.GetHash());
                if (result.Status == TransactionResultStatus.Mined)
                {
                    output.SecondInt64Value.ShouldBe(1);
                }
                else if (result.Status == TransactionResultStatus.Conflict)
                {
                    output.SecondInt64Value.ShouldBe(0);
                }
            }

            nonparallelContractCode =
                await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            }, ParallelTestHelper.BasicFunctionWithParallelContractAddress);

            nonparallelContractCode.CodeHash.ShouldBe(HashHelper.ComputeFrom(_parallelTestHelper.BasicFunctionWithParallelContractCode));

            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(block.GetHash());

            blockStateSet.Changes.Count.ShouldBeGreaterThan(0);
            var blockExecutedData = blockStateSet.BlockExecutedData.First();
            var versionedState    = await _versionedStates.GetAsync(blockExecutedData.Key);

            versionedState.ShouldBeNull();

            await _blockchainStateService.MergeBlockStateAsync(block.Height, block.GetHash());

            blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(block.GetHash());

            blockStateSet.ShouldBeNull();

            nonparallelContractCode =
                await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            }, ParallelTestHelper.BasicFunctionWithParallelContractAddress);

            nonparallelContractCode.CodeHash.ShouldBe(HashHelper.ComputeFrom(_parallelTestHelper.BasicFunctionWithParallelContractCode));

            versionedState = await _versionedStates.GetAsync(blockExecutedData.Key);

            versionedState.Key.ShouldBe(blockExecutedData.Key);
            versionedState.Value.ShouldBe(blockExecutedData.Value);

            groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                transactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(1);
            groupedTransactions.Parallelizables[0][0].To.ShouldBe(tokenContractAddress);
            groupedTransactions.NonParallelizables.Count.ShouldBe(_transactionCount);

            otherGroupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                otherTransactions);

            otherGroupedTransactions.Parallelizables.Count.ShouldBe(1);
            otherGroupedTransactions.Parallelizables[0][0].To.ShouldBe(tokenContractAddress);
            otherGroupedTransactions.NonParallelizables.Count.ShouldBe(_transactionCount);

            groupedTransferTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transferTransactions);

            groupedTransferTransactions.Parallelizables.Count.ShouldBe(1);
            groupedTransferTransactions.Parallelizables[0].Count.ShouldBe(transferTransactions.Count);
            groupedTransferTransactions.NonParallelizables.Count.ShouldBe(0);

            poolSize = (await _txHub.GetTransactionPoolStatusAsync()).AllTransactionCount;

            poolSize.ShouldBe(transactions.Count * 2 + transferTransactions.Count - block.TransactionIds.Count());
        }