예제 #1
0
        public override Empty ChargeResourceToken(ChargeResourceTokenInput input)
        {
            Context.LogDebug(() => $"Start executing ChargeResourceToken.{input}");
            if (input.Equals(new ChargeResourceTokenInput()))
            {
                return(new Empty());
            }

            var symbolToAmount = new Dictionary <string, long>
            {
                { "CPU", State.CpuUnitPrice.Value.Mul(input.ReadsCount) },
                { "NET", State.NetUnitPrice.Value.Mul(input.TransactionSize) },
                { "STO", State.StoUnitPrice.Value.Mul(input.WritesCount) }
            };

            foreach (var pair in symbolToAmount)
            {
                Context.LogDebug(() => $"Charging {pair.Value} {pair.Key} tokens.");
                var existingBalance = State.Balances[Context.Sender][pair.Key];
                Assert(existingBalance >= pair.Value,
                       $"Insufficient resource. {pair.Key}: {existingBalance} / {pair.Value}");
                State.ChargedResourceTokens[input.Caller][Context.Sender][pair.Key] =
                    State.ChargedResourceTokens[input.Caller][Context.Sender][pair.Key].Add(pair.Value);
            }

            Context.LogDebug(() => "Finished executing ChargeResourceToken.");

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

            var chainContext = new ChainContext
            {
                BlockHash   = transactionContext.PreviousBlockHash,
                BlockHeight = transactionContext.BlockHeight - 1
            };

            // Generate token contract stub.
            var tokenContractAddress =
                await _smartContractAddressService.GetAddressByContractNameAsync(chainContext,
                                                                                 TokenSmartContractAddressNameProvider.StringName);

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

            var tokenStub = _contractReaderFactory.Create(new ContractReaderContext
            {
                ContractAddress = tokenContractAddress,
                Sender          = transactionContext.Transaction.To
            });

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

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

            var chargeResourceTokenInput = new ChargeResourceTokenInput
            {
                Caller = transactionContext.Transaction.From
            };

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

            chargeResourceTokenInput.CostDic.Add(feeCalculationResult);

            var chargeResourceTokenTransaction = tokenStub.ChargeResourceToken.GetTransaction(chargeResourceTokenInput);

            return(new List <Transaction>
            {
                chargeResourceTokenTransaction
            });
        }
예제 #3
0
        public override ConsumedResourceTokens ChargeResourceToken(ChargeResourceTokenInput input)
        {
            var consumedResourceTokens = new ConsumedResourceTokens();

            Context.LogDebug(() => $"Start executing ChargeResourceToken.{input}");
            if (input.Equals(new ChargeResourceTokenInput()))
            {
                return(consumedResourceTokens);
            }

            var symbolToAmount = new Dictionary <string, long>
            {
                { "READ", input.ReadCost },
                { "TRAFFIC", input.TrafficCost },
                { "STORAGE", input.StorageCost },
                { "WRITE", input.WriteCost }
            };

            var bill = new TransactionFeeBill();

            foreach (var pair in symbolToAmount)
            {
                Context.LogDebug(() => $"Charging {pair.Value} {pair.Key} tokens.");
                var existingBalance = State.Balances[Context.Sender][pair.Key];
                if (existingBalance < pair.Value)
                {
                    bill.TokenToAmount.Add(pair.Key, existingBalance);
                    var owningBalance = State.OwningResourceToken[Context.Sender][pair.Key]
                                        .Add(pair.Value.Sub(existingBalance));
                    State.OwningResourceToken[Context.Sender][pair.Key] = owningBalance;

                    consumedResourceTokens.IsFailedToCharge = true;
                    consumedResourceTokens.Owning.Add(pair.Key, owningBalance);

                    Context.LogDebug(() => $"Insufficient resource. {pair.Key}: {existingBalance} / {pair.Value}");
                }
                else
                {
                    bill.TokenToAmount.Add(pair.Key, pair.Value);
                }
            }

            foreach (var pair in bill.TokenToAmount)
            {
                State.ChargedResourceTokens[input.Caller][Context.Sender][pair.Key] =
                    State.ChargedResourceTokens[input.Caller][Context.Sender][pair.Key].Add(pair.Value);
                consumedResourceTokens.Value.Add(pair.Key, pair.Value);
            }

            Context.LogDebug(() => $"Finished executing ChargeResourceToken.{consumedResourceTokens}");

            return(consumedResourceTokens);
        }
예제 #4
0
        public override Empty ChargeResourceToken(ChargeResourceTokenInput input)
        {
            Context.LogDebug(() => $"Start executing ChargeResourceToken.{input}");
            if (input.Equals(new ChargeResourceTokenInput()))
            {
                return(new Empty());
            }

            var bill = new TransactionFeeBill();

            foreach (var pair in input.CostDic)
            {
                Context.LogDebug(() => $"Charging {pair.Value} {pair.Key} tokens.");
                var existingBalance = GetBalance(Context.Sender, pair.Key);
                if (existingBalance < pair.Value)
                {
                    bill.FeesMap.Add(pair.Key, existingBalance);
                    var owningBalance = State.OwningResourceToken[Context.Sender][pair.Key]
                                        .Add(pair.Value.Sub(existingBalance));
                    State.OwningResourceToken[Context.Sender][pair.Key] = owningBalance;
                    Context.LogDebug(() => $"Insufficient resource. {pair.Key}: {existingBalance} / {pair.Value}");
                    Context.Fire(new ResourceTokenOwned
                    {
                        Symbol = pair.Key,
                        Amount = owningBalance
                    });
                }
                else
                {
                    bill.FeesMap.Add(pair.Key, pair.Value);
                }
            }

            foreach (var pair in bill.FeesMap)
            {
                Context.Fire(new ResourceTokenCharged
                {
                    Symbol          = pair.Key,
                    Amount          = pair.Value,
                    ContractAddress = Context.Sender
                });
                if (pair.Value == 0)
                {
                    Context.LogDebug(() => $"Maybe incorrect charged resource fee of {pair.Key}: it's 0.");
                }
            }

            return(new Empty());
        }
예제 #5
0
        public override Empty ChargeResourceToken(ChargeResourceTokenInput input)
        {
            AssertTransactionGeneratedByPlugin();
            Context.LogDebug(() => $"Start executing ChargeResourceToken.{input}");
            if (input.Equals(new ChargeResourceTokenInput()))
            {
                return(new Empty());
            }

            var bill = new TransactionFeeBill();

            foreach (var pair in input.CostDic)
            {
                Context.LogDebug(() => $"Charging {pair.Value} {pair.Key} tokens.");
                var existingBalance = GetBalance(Context.Sender, pair.Key);
                Assert(existingBalance >= pair.Value,
                       $"Insufficient resource of {pair.Key}. Need balance: {pair.Value}; Current balance: {existingBalance}.");
                bill.FeesMap.Add(pair.Key, pair.Value);
            }

            foreach (var pair in bill.FeesMap)
            {
                Context.Fire(new ResourceTokenCharged
                {
                    Symbol          = pair.Key,
                    Amount          = pair.Value,
                    ContractAddress = Context.Sender
                });
                if (pair.Value == 0)
                {
                    Context.LogDebug(() => $"Maybe incorrect charged resource fee of {pair.Key}: it's 0.");
                }
            }

            return(new Empty());
        }