public async Task ProcessAsync(Block block, TransactionResult transactionResult, LogEvent logEvent)
        {
            var eventData = new TransactionFeeCharged();

            eventData.MergeFrom(logEvent);
            if (eventData.Symbol == null || eventData.Amount == 0)
            {
                return;
            }

            var blockHash   = block.GetHash();
            var blockHeight = block.Height;
            // TODO: Get -> Modify -> Set is slow, consider collect all logEvents then generate the totalTxFeesMap at once.
            var totalTxFeesMap = await _totalTransactionFeesMapProvider.GetTotalTransactionFeesMapAsync(new ChainContext
            {
                BlockHash   = blockHash,
                BlockHeight = blockHeight
            });

            // Initial totalTxFeesMap if necessary (either never initialized or not initialized for current block link)
            if (totalTxFeesMap == null)
            {
                totalTxFeesMap = new TotalTransactionFeesMap
                {
                    BlockHash   = blockHash,
                    BlockHeight = blockHeight
                };
            }
            else if (totalTxFeesMap.BlockHash != blockHash || totalTxFeesMap.BlockHeight != blockHeight)
            {
                totalTxFeesMap = new TotalTransactionFeesMap
                {
                    BlockHash   = blockHash,
                    BlockHeight = blockHeight
                };
            }

            if (totalTxFeesMap.Value.ContainsKey(eventData.Symbol))
            {
                totalTxFeesMap.Value[eventData.Symbol] = totalTxFeesMap.Value[eventData.Symbol] + eventData.Amount;
            }
            else
            {
                totalTxFeesMap.Value[eventData.Symbol] = eventData.Amount;
            }

            await _totalTransactionFeesMapProvider.SetTotalTransactionFeesMapAsync(new BlockIndex
            {
                BlockHash   = blockHash,
                BlockHeight = blockHeight
            }, totalTxFeesMap);
        }
Пример #2
0
        public override Empty ClaimTransactionFees(TotalTransactionFeesMap input)
        {
            Context.LogDebug(() => $"Claim transaction fee. {input}");
            State.LatestTotalTransactionFeesMapHash.Value = Hash.FromMessage(input);
            foreach (var bill in input.Value)
            {
                var symbol = bill.Key;
                var amount = bill.Value;
                ModifyBalance(Context.Self, symbol, amount);
                TransferTransactionFeesToFeeReceiver(symbol, amount);
            }

            Context.LogDebug(() => "Finish claim transaction fee.");

            return(new Empty());
        }
Пример #3
0
        public async Task ClaimTransactionFee_Balance_With_Receiver_Test()
        {
            var tokenSymbol = "JAN";
            var feeAmount   = 10000;

            await CreateTokenAsync(DefaultSender, tokenSymbol);

            var receiver = await ParliamentContractStub.GetDefaultOrganizationAddress.CallAsync(new Empty());

            var input = new InitializeFromParentChainInput
            {
                Creator = receiver
            };

            await SubmitAndPassProposalOfDefaultParliamentAsync(TokenContractAddress,
                                                                nameof(TokenContractImplContainer.TokenContractImplStub.InitializeFromParentChain), input);
            await SubmitAndPassProposalOfDefaultParliamentAsync(TokenContractAddress,
                                                                nameof(TokenContractImplContainer.TokenContractImplStub.SetFeeReceiver), receiver);

            var beforeBurned = await GetTokenSupplyAmount(tokenSymbol);

            var beforeBalance = await GetBalanceAsync(receiver, tokenSymbol);

            var claimFeeInput = new TotalTransactionFeesMap
            {
                Value =
                {
                    { tokenSymbol, feeAmount }
                }
            };
            await TokenContractStub.ClaimTransactionFees.SendAsync(claimFeeInput);

            var afterBurned = await GetTokenSupplyAmount(tokenSymbol);

            var afterBalance = await GetBalanceAsync(receiver, tokenSymbol);

            var shouldBurned = feeAmount.Div(10);

            (beforeBurned - afterBurned).ShouldBe(shouldBurned);
            (afterBalance - beforeBalance).ShouldBe(feeAmount - shouldBurned);
        }
Пример #4
0
        public async Task ClaimTransactionFee_Balance_WithOut_Receiver_Test()
        {
            var tokenSymbol = "JAN";
            var feeAmount   = 10000;

            await CreateTokenAsync(DefaultSender, tokenSymbol);

            var beforeBurned = await GetTokenSupplyAmount(tokenSymbol);

            var claimFeeInput = new TotalTransactionFeesMap
            {
                Value =
                {
                    { tokenSymbol, feeAmount }
                }
            };
            await TokenContractStub.ClaimTransactionFees.SendAsync(claimFeeInput);

            var afterBurned = await GetTokenSupplyAmount(tokenSymbol);

            (beforeBurned - afterBurned).ShouldBe(feeAmount);
        }
Пример #5
0
        public override Empty ClaimTransactionFees(TotalTransactionFeesMap input)
        {
            AssertSenderIsCurrentMiner();
            var claimTransactionExecuteHeight = State.ClaimTransactionFeeExecuteHeight.Value;

            Assert(claimTransactionExecuteHeight < Context.CurrentHeight,
                   $"This method already executed in height {State.ClaimTransactionFeeExecuteHeight.Value}");
            State.ClaimTransactionFeeExecuteHeight.Value = Context.CurrentHeight;
            Context.LogDebug(() => $"Claim transaction fee. {input}");
            State.LatestTotalTransactionFeesMapHash.Value = HashHelper.ComputeFrom(input);
            foreach (var bill in input.Value)
            {
                var symbol = bill.Key;
                var amount = bill.Value;
                ModifyBalance(Context.Self, symbol, amount);
                TransferTransactionFeesToFeeReceiver(symbol, amount);
            }

            Context.LogDebug(() => "Finish claim transaction fee.");

            return(new Empty());
        }
        public override async Task ProcessAsync(Block block, Dictionary <TransactionResult, List <LogEvent> > logEventsMap)
        {
            var blockHash      = block.GetHash();
            var blockHeight    = block.Height;
            var totalTxFeesMap = new TotalTransactionFeesMap
            {
                BlockHash   = blockHash,
                BlockHeight = blockHeight
            };

            foreach (var logEvent in logEventsMap.Values.SelectMany(logEvents => logEvents))
            {
                var eventData = new TransactionFeeCharged();
                eventData.MergeFrom(logEvent);
                if (eventData.Symbol == null || eventData.Amount == 0)
                {
                    continue;
                }

                if (totalTxFeesMap.Value.ContainsKey(eventData.Symbol))
                {
                    totalTxFeesMap.Value[eventData.Symbol] += eventData.Amount;
                }
                else
                {
                    totalTxFeesMap.Value[eventData.Symbol] = eventData.Amount;
                }
            }

            if (totalTxFeesMap.Value.Any()) // for some TransactionFeeCharged event with 0 fee to charge.
            {
                await _totalTransactionFeesMapProvider.SetTotalTransactionFeesMapAsync(new BlockIndex
                {
                    BlockHash   = blockHash,
                    BlockHeight = blockHeight
                }, totalTxFeesMap);
            }
        }