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