Change the WatchMempool pool to build statistics about risk analysis. Removes the pay-to-pubkey detection which was in there.

This commit is contained in:
Andreas Schildbach 2014-12-21 18:51:24 +01:00
parent e8e13de4d4
commit 121d2fcb63
2 changed files with 58 additions and 17 deletions

View File

@ -51,7 +51,7 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
protected final Transaction tx;
protected final List<Transaction> dependencies;
protected final Wallet wallet;
protected final @Nullable Wallet wallet;
private Transaction nonStandard;
protected Transaction nonFinal;
@ -69,17 +69,20 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
analyzed = true;
Result result = analyzeIsFinal();
if (result != Result.OK)
if (result != null && result != Result.OK)
return result;
return analyzeIsStandard();
}
private Result analyzeIsFinal() {
private @Nullable Result analyzeIsFinal() {
// Transactions we create ourselves are, by definition, not at risk of double spending against us.
if (tx.getConfidence().getSource() == TransactionConfidence.Source.SELF)
return Result.OK;
if (wallet == null)
return null;
final int height = wallet.getLastBlockSeenHeight();
final long time = wallet.getLastBlockSeenTimeSecs();
// If the transaction has a lock time specified in blocks, we consider that if the tx would become final in the
@ -172,7 +175,7 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
private Result analyzeIsStandard() {
// The IsStandard rules don't apply on testnet, because they're just a safety mechanism and we don't want to
// crush innovation with valueless test coins.
if (!wallet.getNetworkParameters().getId().equals(NetworkParameters.ID_MAINNET))
if (wallet != null && !wallet.getNetworkParameters().getId().equals(NetworkParameters.ID_MAINNET))
return Result.OK;
RuleViolation ruleViolation = isStandard(tx);

View File

@ -17,35 +17,73 @@
package org.bitcoinj.tools;
import org.bitcoinj.core.*;
import java.util.HashMap;
import java.util.Map;
import org.bitcoinj.core.AbstractPeerEventListener;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Peer;
import org.bitcoinj.core.PeerGroup;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.net.discovery.DnsDiscovery;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.wallet.DefaultRiskAnalysis;
import org.bitcoinj.wallet.RiskAnalysis.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
public class WatchMempool {
private static Logger log = LoggerFactory.getLogger(WatchMempool.class);
private static final NetworkParameters PARAMS = MainNetParams.get();
private static final ImmutableList<Transaction> NO_DEPS = ImmutableList.of();
private static final Map<String, Integer> counters = new HashMap<String, Integer>();
private static final String TOTAL_KEY = "TOTAL";
private static final long START_MS = System.currentTimeMillis();
private static final long STATISTICS_FREQUENCY_MS = 1000 * 5;
public static void main(String[] args) throws InterruptedException {
BriefLogFormatter.init();
NetworkParameters params = MainNetParams.get();
PeerGroup peerGroup = new PeerGroup(params);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
PeerGroup peerGroup = new PeerGroup(PARAMS);
peerGroup.setMaxConnections(32);
peerGroup.addPeerDiscovery(new DnsDiscovery(PARAMS));
peerGroup.addEventListener(new AbstractPeerEventListener() {
@Override
public void onTransaction(Peer peer, Transaction tx) {
try {
log.info("tx {}", tx.getHash());
if (tx.getOutputs().size() != 1) return;
if (!tx.getOutput(0).getScriptPubKey().isSentToRawPubKey()) return;
log.info("Saw raw pay to pubkey {}", tx);
} catch (ScriptException e) {
e.printStackTrace();
}
Result result = DefaultRiskAnalysis.FACTORY.create(null, tx, NO_DEPS).analyze();
incrementCounter(TOTAL_KEY);
log.info("tx {} result {}", tx.getHash(), result);
incrementCounter(result.name());
if (result == Result.NON_STANDARD)
incrementCounter(Result.NON_STANDARD + "-" + DefaultRiskAnalysis.isStandard(tx));
}
});
peerGroup.start();
Thread.sleep(Long.MAX_VALUE);
while (true) {
Thread.sleep(STATISTICS_FREQUENCY_MS);
printCounters();
}
}
private synchronized static void incrementCounter(String name) {
Integer count = counters.get(name);
if (count == null)
count = 0;
count++;
counters.put(name, count);
}
private synchronized static void printCounters() {
System.out.printf("Runtime: %d minutes\n", (System.currentTimeMillis() - START_MS) / 1000 / 60);
Integer total = counters.get(TOTAL_KEY);
if (total == null)
return;
for (Map.Entry<String, Integer> counter : counters.entrySet()) {
System.out.printf(" %-40s%6d (%d%% of total)\n", counter.getKey(), counter.getValue(),
(int) counter.getValue() * 100 / total);
}
}
}