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()); }
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 }); }
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); }
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); }
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); }
/// <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); }
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()); }