diff --git a/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java b/tools/src/main/java/org/bitcoinj/tools/WatchMempool.java index d9f8660a013..dc193e12f00 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; @@ -35,6 +36,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,41 +48,55 @@ 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 + // 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(); - 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); }); + // 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(); } } - 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); }