@@ -38,6 +38,7 @@ public class TokenTransferMonitoringService : ITokenTransferMonitoringService, I
3838 private readonly HashSet < string > _blacklistAddresses ;
3939 private readonly HashSet < string > _toOnlyMonitoredAddresses ;
4040 private readonly HashSet < string > _largeAmountOnlyAddresses ;
41+ private readonly HashSet < string > _ignoreAddresses ;
4142 private readonly IOptionsMonitor < TokenTransferMonitoringOptions > _optionsMonitor ;
4243
4344 public TokenTransferMonitoringService (
@@ -62,6 +63,7 @@ public TokenTransferMonitoringService(
6263 _blacklistAddresses = new HashSet < string > ( _options . BlacklistAddresses , StringComparer . OrdinalIgnoreCase ) ;
6364 _toOnlyMonitoredAddresses = new HashSet < string > ( _options . ToOnlyMonitoredAddresses , StringComparer . OrdinalIgnoreCase ) ;
6465 _largeAmountOnlyAddresses = new HashSet < string > ( _options . LargeAmountOnlyAddresses , StringComparer . OrdinalIgnoreCase ) ;
66+ _ignoreAddresses = new HashSet < string > ( _options . IgnoreAddresses , StringComparer . OrdinalIgnoreCase ) ;
6567 // Initialize histogram with configured buckets
6668 _transferUSDEventsHistogram = instrumentationProvider . Meter . CreateHistogram < double > (
6769 "aelf_transfer_usd_value" ,
@@ -310,58 +312,88 @@ public void SendTransferMetrics(TransferEventDto transfer)
310312 // Determine if this is a high-value transfer once
311313 var isHighValue = transfer . UsdValue >= currentOptions . MinUsdValueThreshold ;
312314
313- // Record outbound transaction (from perspective)
314- var outboundTags = new KeyValuePair < string , object ? > [ ]
315+ // Record outbound transaction (from perspective) - skip if fromAddress is ignore type
316+ if ( transfer . FromAddressType != AddressClassification . Ignore && ! transfer . FromAddress . IsNullOrEmpty ( ) )
315317 {
316- new ( "chain_id" , transfer . ChainId ) ,
317- new ( "symbol" , transfer . Symbol ) ,
318- new ( "transfer_type" , transfer . Type . ToString ( ) ) ,
319- new ( "address" , transfer . FromAddress ) ,
320- new ( "direction" , "outbound" ) ,
321- new ( "address_type" , transfer . FromAddressType . ToString ( ) ) ,
322- } ;
323-
324- // Record inbound transaction (to perspective)
325- var inboundTags = new KeyValuePair < string , object ? > [ ]
326- {
327- new ( "chain_id" , transfer . ChainId ) ,
328- new ( "symbol" , transfer . Symbol ) ,
329- new ( "transfer_type" , transfer . Type . ToString ( ) ) ,
330- new ( "address" , transfer . ToAddress ) ,
331- new ( "direction" , "inbound" ) ,
332- new ( "address_type" , transfer . ToAddressType . ToString ( ) ) ,
333- } ;
334-
335- // Always record counter (for all transfers)
318+ var outboundTags = new KeyValuePair < string , object ? > [ ]
319+ {
320+ new ( "chain_id" , transfer . ChainId ) ,
321+ new ( "symbol" , transfer . Symbol ) ,
322+ new ( "transfer_type" , transfer . Type . ToString ( ) ) ,
323+ new ( "address" , transfer . FromAddress ) ,
324+ new ( "direction" , "outbound" ) ,
325+ new ( "address_type" , transfer . FromAddressType . ToString ( ) ) ,
326+ } ;
327+
328+ // Always record counter
329+ _transferCountsCounter . Add ( 1 , outboundTags ) ;
336330
337- if ( ! transfer . FromAddress . IsNullOrEmpty ( ) )
331+ // Only record histogram for high-value transfers
332+ if ( isHighValue )
333+ {
334+ _transferUSDEventsHistogram . Record ( ( double ) transfer . UsdValue , outboundTags ) ;
335+ }
336+ }
337+ else if ( transfer . FromAddressType == AddressClassification . Ignore )
338338 {
339- _transferCountsCounter . Add ( 1 , outboundTags ) ;
339+ _logger . LogInformation ( "Skipping outbound metrics for transaction {TransactionId} from ignore address {FromAddress}" ,
340+ transfer . TransactionId , transfer . FromAddress ) ;
340341 }
341342
342- if ( ! transfer . ToAddress . IsNullOrEmpty ( ) || ! IsSystemContractTransfer ( transfer . ToAddress ) )
343+ // Record inbound transaction (to perspective) - skip if toAddress is ignore type
344+ if ( transfer . ToAddressType != AddressClassification . Ignore &&
345+ ! transfer . ToAddress . IsNullOrEmpty ( ) &&
346+ ! IsSystemContractTransfer ( transfer . ToAddress ) )
343347 {
348+ var inboundTags = new KeyValuePair < string , object ? > [ ]
349+ {
350+ new ( "chain_id" , transfer . ChainId ) ,
351+ new ( "symbol" , transfer . Symbol ) ,
352+ new ( "transfer_type" , transfer . Type . ToString ( ) ) ,
353+ new ( "address" , transfer . ToAddress ) ,
354+ new ( "direction" , "inbound" ) ,
355+ new ( "address_type" , transfer . ToAddressType . ToString ( ) ) ,
356+ } ;
357+
358+ // Always record counter
344359 _transferCountsCounter . Add ( 1 , inboundTags ) ;
360+
361+ // Only record histogram for high-value transfers
362+ if ( isHighValue )
363+ {
364+ _transferUSDEventsHistogram . Record ( ( double ) transfer . UsdValue , inboundTags ) ;
365+ }
345366 }
346- // Only record histogram for high-value transfers
347- if ( isHighValue )
367+ else if ( transfer . ToAddressType == AddressClassification . Ignore )
348368 {
349- if ( ! transfer . FromAddress . IsNullOrEmpty ( ) )
369+ _logger . LogInformation ( "Skipping inbound metrics for transaction {TransactionId} to ignore address {ToAddress}" ,
370+ transfer . TransactionId , transfer . ToAddress ) ;
371+ }
372+
373+ // Log transaction processing summary
374+ var recordedMetrics = new List < string > ( ) ;
375+ if ( transfer . FromAddressType != AddressClassification . Ignore && ! transfer . FromAddress . IsNullOrEmpty ( ) )
376+ recordedMetrics . Add ( "outbound" ) ;
377+ if ( transfer . ToAddressType != AddressClassification . Ignore && ! transfer . ToAddress . IsNullOrEmpty ( ) && ! IsSystemContractTransfer ( transfer . ToAddress ) )
378+ recordedMetrics . Add ( "inbound" ) ;
379+
380+ if ( recordedMetrics . Any ( ) )
381+ {
382+ if ( isHighValue )
350383 {
351- _transferUSDEventsHistogram . Record ( ( double ) transfer . UsdValue , outboundTags ) ;
384+ _logger . LogInformation ( "Sent transfer metrics ({Directions}) for transaction {TransactionId}, amount {Amount} {Symbol}, USD value {UsdValue}" ,
385+ string . Join ( ", " , recordedMetrics ) , transfer . TransactionId , transfer . Amount , transfer . Symbol , transfer . UsdValue ) ;
352386 }
353-
354- if ( ! transfer . ToAddress . IsNullOrEmpty ( ) || ! IsSystemContractTransfer ( transfer . ToAddress ) )
387+ else
355388 {
356- _transferUSDEventsHistogram . Record ( ( double ) transfer . UsdValue , inboundTags ) ;
389+ _logger . LogInformation ( "Sent counter metrics only ({Directions}) for transaction {TransactionId}, amount {Amount} {Symbol}, USD value {UsdValue} below histogram threshold" ,
390+ string . Join ( ", " , recordedMetrics ) , transfer . TransactionId , transfer . Amount , transfer . Symbol , transfer . UsdValue ) ;
357391 }
358- _logger . LogInformation ( "Sent transfer metrics for transaction {TransactionId}, amount {Amount} {Symbol}, USD value {UsdValue}" ,
359- transfer . TransactionId , transfer . Amount , transfer . Symbol , transfer . UsdValue ) ;
360392 }
361393 else
362394 {
363- _logger . LogInformation ( "Sent counter metrics only for transaction {TransactionId}, amount {Amount} {Symbol}, USD value {UsdValue} below histogram threshold " ,
364- transfer . TransactionId , transfer . Amount , transfer . Symbol , transfer . UsdValue ) ;
395+ _logger . LogInformation ( "No metrics recorded for transaction {TransactionId} - both addresses are ignore type or system contracts " ,
396+ transfer . TransactionId ) ;
365397 }
366398 }
367399 catch ( Exception ex )
@@ -394,7 +426,11 @@ private AddressClassification ClassifyAddress(string address)
394426 if ( string . IsNullOrEmpty ( address ) )
395427 return AddressClassification . Normal ;
396428
397- // Check blacklist first (highest priority)
429+ // Check ignore addresses first (highest priority)
430+ if ( _ignoreAddresses . Contains ( address ) )
431+ return AddressClassification . Ignore ;
432+
433+ // Check blacklist (second highest priority)
398434 if ( _blacklistAddresses . Contains ( address ) )
399435 return AddressClassification . Blacklist ;
400436
0 commit comments