private async Task <SmartContractRegistrationCache> GetSmartContractRegistrationCacheFromLibCache( IChainContext chainContext, Address address) { if (_smartContractRegistrationCacheProvider.TryGetLibCache(address, out var smartContractRegistrationCache)) { return(smartContractRegistrationCache); } if (chainContext.BlockHeight > 0 && _initLibBlockHeight == 0) { var chain = await _blockchainService.GetChainAsync(); _initLibBlockHash = chain.LastIrreversibleBlockHash; _initLibBlockHeight = chain.LastIrreversibleBlockHeight; } //Use lib chain context to set lib cache. Genesis block need to execute with state cache var context = new ChainContext { BlockHash = _initLibBlockHash, BlockHeight = _initLibBlockHeight, StateCache = chainContext.BlockHeight == 0 ? chainContext.StateCache : null }; if (!_deployedContractAddressProvider.CheckContractAddress(context, address)) { return(null); } SmartContractRegistration smartContractRegistration; if (address == _defaultContractZeroCodeProvider.ContractZeroAddress) { smartContractRegistration = _defaultContractZeroCodeProvider.DefaultContractZeroRegistration; if (context.BlockHeight > Constants.GenesisBlockHeight) { var executive = await GetExecutiveAsync(smartContractRegistration); smartContractRegistration = await GetSmartContractRegistrationFromZeroAsync(executive, context, address); } } else { smartContractRegistration = await GetSmartContractRegistrationFromZeroAsync(context, address); } smartContractRegistrationCache = new SmartContractRegistrationCache { SmartContractRegistration = smartContractRegistration, BlockHash = context.BlockHash, BlockHeight = context.BlockHeight, Address = address }; _smartContractRegistrationCacheProvider.SetLibCache(address, smartContractRegistrationCache); return(smartContractRegistrationCache); }
public async Task <bool> ValidateTransactionAsync(Transaction transaction) { var chain = await _blockchainService.GetChainAsync(); var chainContext = new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight }; if (_deployedContractAddressProvider.CheckContractAddress(chainContext, transaction.To)) { return(true); } Logger.LogWarning($"Invalid contract address: {transaction}"); return(false); }
public async Task <bool> ValidateTransactionAsync(Transaction transaction) { // Skip if this is a system transaction. if (_feeExemptionService.IsFree(transaction)) { return(true); } var chain = await _blockchainService.GetChainAsync(); var chainContext = new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight }; // Skip if the sender is a contract. if (_deployedContractAddressProvider.CheckContractAddress(chainContext, transaction.From)) { return(true); } // Skip this validation at the very beginning of current chain. if (chain.LastIrreversibleBlockHeight == Constants.GenesisBlockHeight) { return(true); } var tokenStub = _tokenContractReaderFactory.Create(chainContext); var balance = (await tokenStub.GetBalance.CallAsync(new GetBalanceInput { Owner = transaction.From, Symbol = await _primaryTokenSymbolProvider.GetPrimaryTokenSymbol() }))?.Balance; // balance == null means token contract hasn't deployed. if (balance == null || balance > 0) { return(true); } Logger.LogWarning($"Empty balance of tx from address: {transaction}"); return(false); }