From c1d1c9ac2863497474e00fc977c1deffc08ba1c9 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Sat, 21 Mar 2026 10:04:44 -0700 Subject: [PATCH 1/3] WatchMempool: reduce logging verbosity to `Level.WARNING` --- tools/src/main/java/org/bitcoinj/tools/WatchMempool.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java index d9f8660a013..c5ef7e0f008 100644 --- a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java +++ b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java @@ -35,6 +35,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; public class WatchMempool { private static final Logger log = LoggerFactory.getLogger(WatchMempool.class); @@ -46,7 +47,7 @@ public class WatchMempool { private static final Duration STATISTICS_FREQUENCY = Duration.ofSeconds(5); public static void main(String[] args) throws InterruptedException { - BriefLogFormatter.init(); + BriefLogFormatter.init(Level.WARNING); // Only log WARNING or higher messages PeerGroup peerGroup = new PeerGroup(NETWORK); peerGroup.setMaxConnections(32); peerGroup.addPeerDiscovery(new DnsDiscovery(NETWORK)); From 11713d844317e799f3b3378acebb3032b3d6db11 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Sat, 21 Mar 2026 10:18:45 -0700 Subject: [PATCH 2/3] WatchMempool: make updates of field `counters` atomic * synchronize before updating or snapshotting and printing counters as a group so the printed results are consistent at the time the snapshot is made * use `Map.merge()` to increment the count of individual counters --- .../java/org/bitcoinj/tools/WatchMempool.java | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java index c5ef7e0f008..2cb397b9bed 100644 --- a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java +++ b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java @@ -26,6 +26,7 @@ import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.wallet.DefaultRiskAnalysis; import org.bitcoinj.wallet.RiskAnalysis.Result; +import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,11 +54,11 @@ public static void main(String[] args) throws InterruptedException { peerGroup.addPeerDiscovery(new DnsDiscovery(NETWORK)); peerGroup.addOnTransactionBroadcastListener((peer, tx) -> { Result result = DefaultRiskAnalysis.FACTORY.create(null, tx, NO_DEPS).analyze(); - incrementCounter(TOTAL_KEY); log.info("tx {} result {}", tx.getTxId(), result); - incrementCounter(result.name()); - if (result == Result.NON_STANDARD) - incrementCounter(Result.NON_STANDARD + "-" + DefaultRiskAnalysis.isStandard(tx)); + String violationName = (result == Result.NON_STANDARD) + ? Result.NON_STANDARD + "-" + DefaultRiskAnalysis.isStandard(tx) + : null; + incrementCounters(result.name(), violationName); }); peerGroup.start(); @@ -67,21 +68,30 @@ public static void main(String[] args) throws InterruptedException { } } - private static synchronized void incrementCounter(String name) { - Integer count = counters.get(name); - if (count == null) - count = 0; - count++; - counters.put(name, count); + private static void incrementCounters(String name, @Nullable String violationName) { + synchronized (counters) { + incrementCounter(TOTAL_KEY); + incrementCounter(name); + if (violationName != null) + incrementCounter(violationName); + } + } + + private static void incrementCounter(String name) { + counters.merge(name, 1, Integer::sum); } - private static synchronized void printCounters() { + private static void printCounters() { Duration elapsed = TimeUtils.elapsedTime(START); + Map snapshot; + synchronized (counters) { + snapshot = Map.copyOf(counters); + } System.out.printf("Runtime: %d:%02d minutes\n", elapsed.toMinutes(), elapsed.toSecondsPart()); - Integer total = counters.get(TOTAL_KEY); + Integer total = snapshot.get(TOTAL_KEY); if (total == null) return; - for (Map.Entry counter : counters.entrySet()) { + for (Map.Entry counter : snapshot.entrySet()) { System.out.printf(" %-40s%6d (%d%% of total)\n", counter.getKey(), counter.getValue(), (int) counter.getValue() * 100 / total); } From 162f0f079e8fe02c09b565eae967113893cd3639 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Sat, 21 Mar 2026 10:17:32 -0700 Subject: [PATCH 3/3] WatchMempool: add comments --- tools/src/main/java/org/bitcoinj/tools/WatchMempool.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java index 2cb397b9bed..dc193e12f00 100644 --- a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java +++ b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java @@ -49,9 +49,11 @@ public class WatchMempool { public static void main(String[] args) throws InterruptedException { BriefLogFormatter.init(Level.WARNING); // Only log WARNING or higher messages + // Create a PeerGroup PeerGroup peerGroup = new PeerGroup(NETWORK); peerGroup.setMaxConnections(32); peerGroup.addPeerDiscovery(new DnsDiscovery(NETWORK)); + // Listen for every transaction received by the PeerGroup peerGroup.addOnTransactionBroadcastListener((peer, tx) -> { Result result = DefaultRiskAnalysis.FACTORY.create(null, tx, NO_DEPS).analyze(); log.info("tx {} result {}", tx.getTxId(), result); @@ -60,8 +62,11 @@ public static void main(String[] args) throws InterruptedException { : null; incrementCounters(result.name(), violationName); }); + // Start the PeerGroup peerGroup.start(); + // Transactions will be counted by the listener + // We will print the current counters every STATISTICS_FREQUENCY seconds while (true) { Thread.sleep(STATISTICS_FREQUENCY.toMillis()); printCounters();