Skip to content

Commit efbc7ed

Browse files
committed
feat: add ignore address type for token transfer monitoring
- Add Ignore type to AddressClassification enum - Add IgnoreAddresses configuration option - Update monitoring service to skip metrics for ignore addresses individually - Only skip the specific address metrics, not the entire transaction - Add detailed logging for ignored addresses - Use example addresses in configuration to avoid exposing real addresses
1 parent 39d9630 commit efbc7ed

4 files changed

Lines changed: 98 additions & 41 deletions

File tree

src/AElfScanServer.Worker.Core/Dtos/TransferEventDto.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public enum AddressClassification
3131
Normal,
3232
Blacklist,
3333
ToOnlyMonitored,
34-
LargeAmountOnly
34+
LargeAmountOnly,
35+
Ignore
3536
}
3637

3738
/// <summary>

src/AElfScanServer.Worker.Core/Options/TokenTransferMonitoringOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public class TokenTransferMonitoringOptions
2929
/// </summary>
3030
public List<string> LargeAmountOnlyAddresses { get; set; } = new();
3131

32+
/// <summary>
33+
/// Addresses to ignore completely - no metrics will be recorded for these addresses
34+
/// </summary>
35+
public List<string> IgnoreAddresses { get; set; } = new();
36+
3237
/// <summary>
3338
/// Minimum USD value threshold for histogram recording, default is 0
3439
/// </summary>

src/AElfScanServer.Worker.Core/Service/TokenTransferMonitoringService.cs

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/AElfScanServer.Worker/appsettings.json

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,12 +264,27 @@
264264
},
265265
"TokenTransferMonitoring": {
266266
"EnableMonitoring": true,
267-
"EnableSystemContractFilter":false,
267+
"EnableSystemContractFilter":true,
268268
"BlacklistAddresses": [
269-
"2Ue8S2qAb8dGMrRgcNtjWgBx48Bx3XmNT6UBBKwNLYm5ZpbA"],
269+
"ExampleBlacklistAddress1234567890ABCDEFGHIJKLMNOP",
270+
"ExampleBlacklistAddress2345678901BCDEFGHIJKLMNOP"
271+
],
272+
"ToOnlyMonitoredAddresses": [
273+
"ExampleToOnlyAddress1234567890ABCDEFGHIJKLMNOPQR",
274+
"ExampleToOnlyAddress2345678901BCDEFGHIJKLMNOPQR"
275+
],
276+
"LargeAmountOnlyAddresses": [
277+
"ExampleLargeAmountAddress1234567890ABCDEFGHIJKLMN",
278+
"ExampleLargeAmountAddress2345678901BCDEFGHIJKLMN"
279+
],
280+
"IgnoreAddresses": [
281+
"ExampleIgnoreAddress1234567890ABCDEFGHIJKLMNOPQRST",
282+
"TestIgnoreAddress2345678901BCDEFGHIJKLMNOPQRSTUV"
283+
],
284+
"MinUsdValueThreshold": 0.1,
270285
"MonitoredTokens": ["ELF", "USDT", "BTC", "ETH"],
271286
"ScanConfig": {
272-
"ChainIds": ["AELF", "tDVW"],
287+
"ChainIds": ["AELF", "tDVV"],
273288
"IntervalSeconds": 30,
274289
"BatchSize": 1000
275290
}

0 commit comments

Comments
 (0)