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