Beispiel #1
0
        public async Task <IEnumerable <Transaction> > GetPostTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!IsTargetAcsSymbol(descriptors))
            {
                return(new List <Transaction>());
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;

            // Generate token contract stub.
            var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(new List <Transaction>());
            }

            var tokenStub = GetTokenContractStub(transactionContext.Transaction.To, tokenContractAddress);

            if (transactionContext.Transaction.To == tokenContractAddress &&
                transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeResourceToken))
            {
                return(new List <Transaction>());
            }

            if (transactionContext.Transaction.To == context.Self &&
                transactionContext.Transaction.MethodName == nameof(ResourceConsumptionContractContainer
                                                                    .ResourceConsumptionContractStub.BuyResourceToken))
            {
                return(new List <Transaction>());
            }

            var chainContext = new ChainContext
            {
                BlockHash   = transactionContext.PreviousBlockHash,
                BlockHeight = transactionContext.BlockHeight - 1
            };
            var chargeResourceTokenInput = new ChargeResourceTokenInput
            {
                Caller = transactionContext.Transaction.From
            };

            var feeCalculationResult =
                await _resourceTokenFeeService.CalculateFeeAsync(transactionContext, chainContext);

            chargeResourceTokenInput.CostDic.Add(feeCalculationResult);

            var chargeResourceTokenTransaction =
                (await tokenStub.ChargeResourceToken.SendAsync(chargeResourceTokenInput)).Transaction;

            return(new List <Transaction>
            {
                chargeResourceTokenTransaction
            });
        }
        public async Task <IEnumerable <Transaction> > GetPreTransactionsAsync(IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!IsAcs1(descriptors))
            {
                return(new List <Transaction>());
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;
            var selfStub = new FeeChargedContractContainer.FeeChargedContractStub()
            {
                __factory = new MethodStubFactory(context)
            };

            var fee = await selfStub.GetMethodFee.CallAsync(new MethodName
            {
                Name = context.TransactionContext.Transaction.MethodName
            });

            if (!fee.Amounts.Any())
            {
                return(new List <Transaction>());
            }

            var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(new List <Transaction>());
            }

            var tokenStub = new TokenContractContainer.TokenContractStub()
            {
                __factory = new TransactionGeneratingOnlyMethodStubFactory()
                {
                    Sender          = transactionContext.Transaction.From,
                    ContractAddress = tokenContractAddress
                }
            };

            if (transactionContext.Transaction.To == tokenContractAddress &&
                transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeTransactionFees))
            {
                // Skip ChargeTransactionFees itself
                return(new List <Transaction>());
            }

            var chargeFeeTransaction = (await tokenStub.ChargeTransactionFees.SendAsync(new ChargeTransactionFeesInput
            {
                SymbolToAmount = { fee.Amounts.ToDictionary(a => a.Symbol, a => a.Amount) }
            })).Transaction;

            return(new List <Transaction>
            {
                chargeFeeTransaction
            });
        }
        public async Task Apply_ExceededMaxCallDepth_Test()
        {
            var executive = CreateExecutive();

            var hostSmartContractBridgeContext = _hostSmartContractBridgeContextService.Create();

            executive.SetHostSmartContractBridgeContext(_hostSmartContractBridgeContextService.Create());

            var transactionContext = CreateTransactionContext();

            transactionContext.CallDepth = 16;

            await executive.ApplyAsync(transactionContext);

            hostSmartContractBridgeContext.TransactionContext.ShouldBeNull();
            transactionContext.Trace.ExecutionStatus.ShouldBe(ExecutionStatus.ExceededMaxCallDepth);
            transactionContext.Trace.Error.ShouldContain("ExceededMaxCallDepth");
        }
        public async Task <IEnumerable <Transaction> > GetPreTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!IsTargetAcsSymbol(descriptors))
            {
                return(new List <Transaction>());
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;
            var selfStub = new ThresholdSettingContractContainer.ThresholdSettingContractStub
            {
                __factory = new MethodStubFactory(context)
            };

            var threshold = await selfStub.GetMethodCallingThreshold.CallAsync(new StringValue
            {
                Value = context.TransactionContext.Transaction.MethodName
            });

            // Generate token contract stub.
            var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(new List <Transaction>());
            }

            var tokenStub = new TokenContractContainer.TokenContractStub
            {
                __factory = new TransactionGeneratingOnlyMethodStubFactory
                {
                    Sender          = transactionContext.Transaction.To,
                    ContractAddress = tokenContractAddress
                }
            };

            if (transactionContext.Transaction.To == tokenContractAddress &&
                transactionContext.Transaction.MethodName == nameof(tokenStub.CheckThreshold))
            {
                return(new List <Transaction>());
            }

            var checkThresholdTransaction = (await tokenStub.CheckThreshold.SendAsync(new CheckThresholdInput
            {
                Sender = context.Sender,
                SymbolToThreshold = { threshold.SymbolToAmount },
                IsCheckAllowance = threshold.ThresholdCheckType == ThresholdCheckType.Allowance
            })).Transaction;

            return(new List <Transaction>
            {
                checkThresholdTransaction
            });
        }
Beispiel #5
0
        private async Task <CachedStateProvider> GenerateStateProviderAsync()
        {
            var chain = await _smartContractHelper.CreateChainAsync();

            var smartContractBridgeContext = _hostSmartContractBridgeContextService.Create();

            smartContractBridgeContext.TransactionContext = new TransactionContext
            {
                Transaction = new Transaction
                {
                    To = SampleAddress.AddressList[0]
                },
                BlockHeight       = chain.BestChainHeight,
                PreviousBlockHash = chain.BestChainHash
            };
            _innerProvider.ContractAddress = SampleAddress.AddressList[0];
            _innerProvider.HostSmartContractBridgeContext = smartContractBridgeContext;
            var statePath = new ScopedStatePath
            {
                Address = _innerProvider.ContractAddress,
                Path    = new StatePath
                {
                    Parts = { "test2" }
                }
            };
            await _blockStateSetManger.SetBlockStateSetAsync(new BlockStateSet
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight,
                Changes     =
                {
                    {
                        statePath.ToStateKey(), ByteString.CopyFrom(1, 2, 3, 4)
                    }
                }
            });

            var cachedStateProvider = new CachedStateProvider(_innerProvider);
            var cacheProvider       = cachedStateProvider as CachedStateProvider;

            cacheProvider.Cache[new ScopedStatePath
                                {
                                    Address = _innerProvider.ContractAddress,
                                    Path = new StatePath
                                    {
                                        Parts = { "test1" }
                                    }
                                }] = new byte[] { 0, 1, 2, 3 };

            return(cachedStateProvider);
        }
Beispiel #6
0
        private async Task <IExecutive> GetExecutiveAsync(Address address, SmartContractRegistration reg)
        {
            // get runner
            var runner = _smartContractRunnerContainer.GetRunner(reg.Category);

            // run smartcontract executive info and return executive
            var executive = await runner.RunAsync(reg);

            var context =
                _hostSmartContractBridgeContextService.Create();

            executive.SetHostSmartContractBridgeContext(context);
            return(executive);
        }
        public async Task <IEnumerable <Transaction> > GetPreTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!IsAcs8(descriptors))
            {
                return(new List <Transaction>());
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;

            // Generate token contract stub.
            var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(new List <Transaction>());
            }

            var tokenStub = new TokenContractContainer.TokenContractStub
            {
                __factory = new TransactionGeneratingOnlyMethodStubFactory
                {
                    Sender          = transactionContext.Transaction.To,
                    ContractAddress = tokenContractAddress
                }
            };

            if (transactionContext.Transaction.To == tokenContractAddress &&
                transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeResourceToken))
            {
                return(new List <Transaction>());
            }

            if (transactionContext.Transaction.To == context.Self &&
                transactionContext.Transaction.MethodName == nameof(ResourceConsumptionContractContainer
                                                                    .ResourceConsumptionContractStub.BuyResourceToken))
            {
                return(new List <Transaction>());
            }

            var checkResourceTokenTransaction =
                (await tokenStub.CheckResourceToken.SendAsync(new Empty())).Transaction;

            return(new List <Transaction>
            {
                checkResourceTokenTransaction
            });
        }
Beispiel #8
0
        public Task <IEnumerable <Transaction> > GetPreTransactionsAsync(IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!descriptors.Any(service => service.File.Name == "test_basic_function_with_parallel_contract.proto"))
            {
                return(Task.FromResult(new List <Transaction>().AsEnumerable()));
            }

            if (transactionContext.Transaction.To == ParallelTestHelper.BasicFunctionWithParallelContractAddress &&
                !transactionContext.Transaction.MethodName.EndsWith("Plugin"))
            {
                return(Task.FromResult(new List <Transaction>().AsEnumerable()));
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;

            var transactions = new List <Transaction>();

            switch (transactionContext.Transaction.MethodName)
            {
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.RemoveValueFromInlineWithPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.RemoveValueFromPostPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.RemoveValueWithPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.RemoveValueParallelFromPostPlugin):
            {
                var input = RemoveValueInput.Parser.ParseFrom(transactionContext.Transaction.Params);
                transactions.Add(new Transaction
                    {
                        From   = transactionContext.Transaction.From,
                        To     = ParallelTestHelper.BasicFunctionWithParallelContractAddress,
                        Params = new IncreaseValueInput
                        {
                            Key  = input.Key,
                            Memo = Guid.NewGuid().ToString()
                        }.ToByteString(),
                        MethodName     = nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValue),
                        RefBlockNumber = transactionContext.BlockHeight - 1,
                        RefBlockPrefix =
                            BlockHelper.GetRefBlockPrefix(transactionContext.PreviousBlockHash)
                    });
                break;
            }

            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.RemoveValueFromPrePlugin):
            {
                var input = RemoveValueInput.Parser.ParseFrom(transactionContext.Transaction.Params);
                transactions.Add(new Transaction
                    {
                        From           = transactionContext.Transaction.From,
                        To             = ParallelTestHelper.BasicFunctionWithParallelContractAddress,
                        Params         = input.ToByteString(),
                        MethodName     = nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.RemoveValue),
                        RefBlockNumber = transactionContext.BlockHeight - 1,
                        RefBlockPrefix =
                            BlockHelper.GetRefBlockPrefix(transactionContext.PreviousBlockHash)
                    });
                break;
            }

            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithInlineAndPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithInlineAndPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueParallelWithInlineAndPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueFailedWithPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueFailedWithPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueFailedWithInlineAndPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueFailedParallelWithInlineAndPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueFailedWithInlineAndPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithFailedInlineAndPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithFailedInlineAndPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueParallelWithFailedInlineAndPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithPrePluginAndFailedPostPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithInlineAndPrePluginAndFailedPostPlugin):
            {
                var input = IncreaseValueInput.Parser.ParseFrom(transactionContext.Transaction.Params);
                transactions.Add(new Transaction
                    {
                        From   = transactionContext.Transaction.From,
                        To     = ParallelTestHelper.BasicFunctionWithParallelContractAddress,
                        Params = new IncreaseValueInput
                        {
                            Key  = input.Key,
                            Memo = Guid.NewGuid().ToString()
                        }.ToByteString(),
                        MethodName     = nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValue),
                        RefBlockNumber = transactionContext.BlockHeight - 1,
                        RefBlockPrefix =
                            BlockHelper.GetRefBlockPrefix(transactionContext.PreviousBlockHash)
                    });
                break;
            }

            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithFailedPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithInlineAndFailedPrePlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithFailedPrePluginAndPostPlugin):
            case nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueWithInlineAndFailedPrePluginAndPostPlugin):
            {
                var input = IncreaseValueInput.Parser.ParseFrom(transactionContext.Transaction.Params);
                transactions.Add(new Transaction
                    {
                        From   = transactionContext.Transaction.From,
                        To     = ParallelTestHelper.BasicFunctionWithParallelContractAddress,
                        Params = new IncreaseValueInput
                        {
                            Key  = input.Key,
                            Memo = Guid.NewGuid().ToString()
                        }.ToByteString(),
                        MethodName     = nameof(BasicFunctionWithParallelContractContainer.BasicFunctionWithParallelContractStub.IncreaseValueFailed),
                        RefBlockNumber = transactionContext.BlockHeight - 1,
                        RefBlockPrefix =
                            BlockHelper.GetRefBlockPrefix(transactionContext.PreviousBlockHash)
                    });
                break;
            }
            }

            return(Task.FromResult(transactions.AsEnumerable()));
        }
        public async Task <IEnumerable <Transaction> > GetPostTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!IsAcs8(descriptors))
            {
                return(new List <Transaction>());
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;

            // Generate token contract stub.
            var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(new List <Transaction>());
            }

            var tokenStub = new TokenContractContainer.TokenContractStub
            {
                __factory = new TransactionGeneratingOnlyMethodStubFactory
                {
                    Sender          = transactionContext.Transaction.To,
                    ContractAddress = tokenContractAddress
                }
            };

            if (transactionContext.Transaction.To == tokenContractAddress &&
                transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeResourceToken))
            {
                return(new List <Transaction>());
            }

            if (transactionContext.Transaction.To == context.Self &&
                transactionContext.Transaction.MethodName == nameof(ResourceConsumptionContractContainer
                                                                    .ResourceConsumptionContractStub.BuyResourceToken))
            {
                return(new List <Transaction>());
            }

            // Transaction size related to NET Token.
            var transactionSize = transactionContext.Transaction.Size();
            // Transaction trace state set writes count related to STO Token.
            var writesCount = transactionContext.Trace.StateSet.Writes.Count;
            // Transaction trace state set reads count related to CPU Token.
            var readsCount = transactionContext.Trace.StateSet.Reads.Count;

            var chargeResourceTokenTransaction = (await tokenStub.ChargeResourceToken.SendAsync(
                                                      new ChargeResourceTokenInput
            {
                TransactionSize = transactionSize,
                WritesCount = writesCount,
                ReadsCount = readsCount,
                Caller = transactionContext.Transaction.From
            })).Transaction;

            return(new List <Transaction>
            {
                chargeResourceTokenTransaction
            });
        }
Beispiel #10
0
        public async Task <IEnumerable <Transaction> > GetPreTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            try
            {
                var context = _contextService.Create();

                if (_transactionFeeExemptionService.IsFree(transactionContext.Transaction))
                {
                    return(new List <Transaction>());
                }

                context.TransactionContext = transactionContext;
                var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

                if (context.CurrentHeight < Constants.GenesisBlockHeight + 1 || tokenContractAddress == null)
                {
                    return(new List <Transaction>());
                }

                if (!IsAcs1(descriptors) && transactionContext.Transaction.To != tokenContractAddress)
                {
                    return(new List <Transaction>());
                }

                var tokenStub = GetTokenContractStub(transactionContext.Transaction.From, tokenContractAddress);
                if (transactionContext.Transaction.To == tokenContractAddress &&
                    transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeTransactionFees))
                {
                    // Skip ChargeTransactionFees itself
                    return(new List <Transaction>());
                }

                var txSize       = transactionContext.Transaction.Size();
                var chainContext = new ChainContext
                {
                    BlockHash   = transactionContext.PreviousBlockHash,
                    BlockHeight = transactionContext.BlockHeight - 1
                };
                var txCost = await _calStrategy.GetCostAsync(chainContext, txSize);

                var chargeTransactionFeesInput = new ChargeTransactionFeesInput
                {
                    MethodName         = transactionContext.Transaction.MethodName,
                    ContractAddress    = transactionContext.Transaction.To,
                    TransactionSizeFee = txCost,
                    PrimaryTokenSymbol = await _primaryTokenSymbolProvider.GetPrimaryTokenSymbol(),
                };
                var symbolListToPayTxSizeFee =
                    await _symbolListToPayTxFeeService.GetExtraAcceptedTokensInfoAsync(chainContext);

                if (symbolListToPayTxSizeFee != null)
                {
                    foreach (var tokenInfo in symbolListToPayTxSizeFee)
                    {
                        chargeTransactionFeesInput.SymbolsToPayTxSizeFee.Add(new SymbolToPayTXSizeFee
                        {
                            TokenSymbol      = tokenInfo.TokenSymbol,
                            BaseTokenWeight  = tokenInfo.BaseTokenWeight,
                            AddedTokenWeight = tokenInfo.AddedTokenWeight
                        });
                    }
                }

                var chargeFeeTransaction = (await tokenStub.ChargeTransactionFees.SendAsync(chargeTransactionFeesInput))
                                           .Transaction;
                return(new List <Transaction>
                {
                    chargeFeeTransaction
                });
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Failed to generate ChargeTransactionFees tx.");
                throw;
            }
        }
        public async Task <IEnumerable <Transaction> > GetPreTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            try
            {
                var context = _contextService.Create();

                if (_transactionFeeExemptionService.IsFree(transactionContext.Transaction))
                {
                    return(new List <Transaction>());
                }

                context.TransactionContext = transactionContext;
                var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

                if (context.CurrentHeight < Constants.GenesisBlockHeight + 1 || tokenContractAddress == null)
                {
                    return(new List <Transaction>());
                }

                if (!IsAcs1(descriptors) && transactionContext.Transaction.To != tokenContractAddress)
                {
                    return(new List <Transaction>());
                }

                var tokenStub = new TokenContractContainer.TokenContractStub
                {
                    __factory = new TransactionGeneratingOnlyMethodStubFactory
                    {
                        Sender          = transactionContext.Transaction.From,
                        ContractAddress = tokenContractAddress
                    }
                };
                if (transactionContext.Transaction.To == tokenContractAddress &&
                    transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeTransactionFees))
                {
                    // Skip ChargeTransactionFees itself
                    return(new List <Transaction>());
                }

                var txSize = transactionContext.Transaction.Size();
                var txCost = _calService.CalculateFee(FeeType.Tx, txSize);
                var chargeFeeTransaction = (await tokenStub.ChargeTransactionFees.SendAsync(
                                                new ChargeTransactionFeesInput
                {
                    MethodName = transactionContext.Transaction.MethodName,
                    ContractAddress = transactionContext.Transaction.To,
                    TransactionSizeFee = txCost,
                    PrimaryTokenSymbol = await _primaryTokenSymbolProvider.GetPrimaryTokenSymbol()
                })).Transaction;
                return(new List <Transaction>
                {
                    chargeFeeTransaction
                });
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Failed to generate ChargeTransactionFees tx.");
                throw;
            }
        }
Beispiel #12
0
        public async Task <IEnumerable <Transaction> > GetPostTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            if (!IsAcs8(descriptors))
            {
                return(new List <Transaction>());
            }

            var context = _contextService.Create();

            context.TransactionContext = transactionContext;

            // Generate token contract stub.
            var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

            if (tokenContractAddress == null)
            {
                return(new List <Transaction>());
            }

            var tokenStub = GetTokenContractStub(transactionContext.Transaction.To, tokenContractAddress);

            if (transactionContext.Transaction.To == tokenContractAddress &&
                transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeResourceToken))
            {
                return(new List <Transaction>());
            }

            if (transactionContext.Transaction.To == context.Self &&
                transactionContext.Transaction.MethodName == nameof(ResourceConsumptionContractContainer
                                                                    .ResourceConsumptionContractStub.BuyResourceToken))
            {
                return(new List <Transaction>());
            }

            // Transaction size related to TRAFFIC Token.
            var trafficSize = transactionContext.Transaction.Size();
            // Transaction trace state set writes count related to STORAGE Token.
            var writesCount = transactionContext.Trace.StateSet.Writes.Count;
            // Transaction trace state set reads count related to WRITE Token.
            var readsCount   = transactionContext.Trace.StateSet.Reads.Count;
            var chainContext = new ChainContext
            {
                BlockHash   = transactionContext.PreviousBlockHash,
                BlockHeight = transactionContext.BlockHeight - 1
            };
            var trafficCost = await _trafficCostStrategy.GetCostAsync(chainContext, trafficSize);

            var readCost = await _readCostStrategy.GetCostAsync(chainContext, readsCount);

            var storageCost = await _storageCostStrategy.GetCostAsync(chainContext, trafficSize);

            var writeCost = await _writeCostStrategy.GetCostAsync(chainContext, writesCount);

            var chargeResourceTokenTransaction = (await tokenStub.ChargeResourceToken.SendAsync(
                                                      new ChargeResourceTokenInput
            {
                TrafficCost = trafficCost,
                StorageCost = storageCost,
                ReadCost = readCost,
                WriteCost = writeCost,
                Caller = transactionContext.Transaction.From
            })).Transaction;

            return(new List <Transaction>
            {
                chargeResourceTokenTransaction
            });
        }
Beispiel #13
0
        public async Task <IEnumerable <Transaction> > GetPreTransactionsAsync(
            IReadOnlyList <ServiceDescriptor> descriptors, ITransactionContext transactionContext)
        {
            try
            {
                var context = _contextService.Create();

                var systemContractAddresses = new List <Address>
                {
                    context.GetZeroSmartContractAddress(context.ChainId),
                    context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name),
                    // TODO: Try to use contract address name providers - put providers to one place easy to ref.
                    context.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Consensus")),
                    context.GetContractAddressByName(Hash.FromString("AElf.ContractNames.CrossChain")),
                    context.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Economic")),
                };
                if (systemContractAddresses.Contains(transactionContext.Transaction.To))
                {
                    if (_systemTransactionMethodNameListProvider.GetSystemTransactionMethodNameList()
                        .Contains(transactionContext.Transaction.MethodName))
                    {
                        return(new List <Transaction>());
                    }

                    var methodNameWhiteList = new List <string>
                    {
                        nameof(TokenContractContainer.TokenContractStub.Create),
                        nameof(TokenContractContainer.TokenContractStub.Issue),
                        nameof(TokenContractContainer.TokenContractStub.CrossChainTransfer),
                        nameof(TokenContractContainer.TokenContractStub.CrossChainReceiveToken),
                        "IssueNativeToken"
                    };

                    if (methodNameWhiteList.Contains(transactionContext.Transaction.MethodName))
                    {
                        return(new List <Transaction>());
                    }
                }

                context.TransactionContext = transactionContext;
                var tokenContractAddress = context.GetContractAddressByName(TokenSmartContractAddressNameProvider.Name);

                if (context.CurrentHeight < Constants.GenesisBlockHeight + 1 || tokenContractAddress == null)
                {
                    return(new List <Transaction>());
                }

                if (!IsAcs1(descriptors) && transactionContext.Transaction.To != tokenContractAddress)
                {
                    return(new List <Transaction>());
                }

                var tokenStub = new TokenContractContainer.TokenContractStub
                {
                    __factory = new TransactionGeneratingOnlyMethodStubFactory
                    {
                        Sender          = transactionContext.Transaction.From,
                        ContractAddress = tokenContractAddress
                    }
                };
                if (transactionContext.Transaction.To == tokenContractAddress &&
                    transactionContext.Transaction.MethodName == nameof(tokenStub.ChargeTransactionFees))
                {
                    // Skip ChargeTransactionFees itself
                    return(new List <Transaction>());
                }

                var unitPrice = await _transactionSizeFeeUnitPriceProvider.GetUnitPriceAsync();

                var chargeFeeTransaction = (await tokenStub.ChargeTransactionFees.SendAsync(
                                                new ChargeTransactionFeesInput
                {
                    MethodName = transactionContext.Transaction.MethodName,
                    ContractAddress = transactionContext.Transaction.To,
                    TransactionSizeFee = unitPrice * transactionContext.Transaction.Size(),
                    PrimaryTokenSymbol = await _primaryTokenSymbolProvider.GetPrimaryTokenSymbol()
                })).Transaction;
                return(new List <Transaction>
                {
                    chargeFeeTransaction
                });
            }
            catch (Exception e)
            {
                Logger.LogError("Failed to generate ChargeTransactionFees tx.", e);
                throw;
            }
        }