From 643088145e35b21262042e474d42e39195ec2216 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Fri, 8 Jun 2012 17:53:50 +0200 Subject: [PATCH] Clear out some FindBugs warnings. --- .../java/com/google/bitcoin/core/Base58.java | 27 +++++++------------ .../com/google/bitcoin/core/MemoryPool.java | 13 ++++----- .../java/com/google/bitcoin/core/Peer.java | 9 ++++--- .../com/google/bitcoin/core/Transaction.java | 8 +++--- .../bitcoin/core/TransactionConfidence.java | 13 +++++---- .../java/com/google/bitcoin/core/Wallet.java | 16 +++++------ .../bitcoin/discovery/IrcDiscovery.java | 4 +-- .../com/google/bitcoin/core/WalletTest.java | 3 --- 8 files changed, 45 insertions(+), 48 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/core/Base58.java b/core/src/main/java/com/google/bitcoin/core/Base58.java index e622b847..58d6bf7a 100644 --- a/core/src/main/java/com/google/bitcoin/core/Base58.java +++ b/core/src/main/java/com/google/bitcoin/core/Base58.java @@ -16,6 +16,7 @@ package com.google.bitcoin.core; +import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.util.Arrays; @@ -54,18 +55,12 @@ public class Base58 { return ""; } input = copyOfRange(input, 0, input.length); - - // - // Count leading zeroes - // + // Count leading zeroes. int zeroCount = 0; while (zeroCount < input.length && input[zeroCount] == 0) { ++zeroCount; } - - // - // The actual encoding - // + // The actual encoding. byte[] temp = new byte[input.length * 2]; int j = temp.length; @@ -75,27 +70,25 @@ public class Base58 { if (input[startAt] == 0) { ++startAt; } - temp[--j] = (byte) ALPHABET[mod]; } - // - // Strip extra '1' if there are some after decoding - // + // Strip extra '1' if there are some after decoding. while (j < temp.length && temp[j] == ALPHABET[0]) { ++j; } - - // // Add as many leading '1' as there were leading zeros. - // while (--zeroCount >= 0) { temp[--j] = (byte) ALPHABET[0]; } byte[] output = copyOfRange(temp, j, temp.length); - return new String(output); - } + try { + return new String(output, "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // Cannot happen. + } + } public static byte[] decode(String input) throws AddressFormatException { if (input.length() == 0) { diff --git a/core/src/main/java/com/google/bitcoin/core/MemoryPool.java b/core/src/main/java/com/google/bitcoin/core/MemoryPool.java index 15f7c560..5657ddbe 100644 --- a/core/src/main/java/com/google/bitcoin/core/MemoryPool.java +++ b/core/src/main/java/com/google/bitcoin/core/MemoryPool.java @@ -49,14 +49,14 @@ public class MemoryPool { // Before we see the full transaction, we need to track how many peers advertised it, so we can estimate its // confidence pre-chain inclusion assuming an un-tampered with network connection. After we see the full transaction // we need to switch from tracking that data in the Entry to tracking it in the TransactionConfidence object itself. - private class WeakTransactionReference extends WeakReference { + private static class WeakTransactionReference extends WeakReference { public Sha256Hash hash; public WeakTransactionReference(Transaction tx, ReferenceQueue queue) { super(tx, queue); hash = tx.getHash(); } }; - private class Entry { + private static class Entry { // Invariants: one of the two fields must be null, to indicate which is used. Set addresses; // We keep a weak reference to the transaction. This means that if no other bit of code finds the transaction @@ -160,14 +160,15 @@ public class MemoryPool { Preconditions.checkState(entry.addresses == null); // We only want one canonical object instance for a transaction no matter how many times it is // deserialized. - if (entry.tx.get() == null) { + Transaction transaction = entry.tx.get(); + if (transaction == null) { // We previously downloaded this transaction, but the garbage collector threw it away because // no other part of the system cared enough to keep it around (it's not relevant to us). // Given the lack of interest last time we probably don't need to track it this time either. log.info("{}: Provided with a transaction that we previously threw away: {}", byPeer, tx.getHash()); } else { // We saw it before and kept it around. Hand back the canonical copy. - tx = entry.tx.get(); + tx = transaction; log.info("{}: Provided with a transaction downloaded before: [{}] {}", new Object[] { byPeer, tx.getConfidence().numBroadcastPeers(), tx.getHash() }); } @@ -209,8 +210,8 @@ public class MemoryPool { // This TX or its hash have been previously announced. if (entry.tx != null) { Preconditions.checkState(entry.addresses == null); - if (entry.tx.get() != null) { - Transaction tx = entry.tx.get(); + Transaction tx = entry.tx.get(); + if (tx != null) { tx.getConfidence().markBroadcastBy(byPeer); log.info("{}: Announced transaction we have seen before [{}] {}", new Object[] { byPeer, tx.getConfidence().numBroadcastPeers(), tx.getHashAsString() }); diff --git a/core/src/main/java/com/google/bitcoin/core/Peer.java b/core/src/main/java/com/google/bitcoin/core/Peer.java index 8b9be0c5..4f99fd24 100644 --- a/core/src/main/java/com/google/bitcoin/core/Peer.java +++ b/core/src/main/java/com/google/bitcoin/core/Peer.java @@ -403,6 +403,7 @@ public class Peer { switch (item.type) { case Transaction: transactions.add(item); break; case Block: blocks.add(item); break; + default: throw new IllegalStateException("Not implemented: " + item.type); } } @@ -411,9 +412,11 @@ public class Peer { Iterator it = transactions.iterator(); while (it.hasNext()) { InventoryItem item = it.next(); - if (memoryPool == null && downloadData) { - // If there's no memory pool only download transactions if we're configured to. - getdata.addItem(item); + if (memoryPool == null) { + if (downloadData) { + // If there's no memory pool only download transactions if we're configured to. + getdata.addItem(item); + } } else { // Only download the transaction if we are the first peer that saw it be advertised. Other peers will also // see it be advertised in inv packets asynchronously, they co-ordinate via the memory pool. We could diff --git a/core/src/main/java/com/google/bitcoin/core/Transaction.java b/core/src/main/java/com/google/bitcoin/core/Transaction.java index ce7b78c9..b5ff6112 100644 --- a/core/src/main/java/com/google/bitcoin/core/Transaction.java +++ b/core/src/main/java/com/google/bitcoin/core/Transaction.java @@ -527,9 +527,9 @@ public class Transaction extends ChildMessage implements Serializable { public String toString() { // Basic info about the tx. StringBuffer s = new StringBuffer(); - s.append(String.format(" %s: %s\n", getHashAsString(), getConfidence())); + s.append(String.format(" %s: %s%n", getHashAsString(), getConfidence())); if (inputs.size() == 0) { - s.append(" INCOMPLETE: No inputs!\n"); + s.append(String.format(" INCOMPLETE: No inputs!%n")); return s.toString(); } if (isCoinBase()) { @@ -561,7 +561,7 @@ public class Transaction extends ChildMessage implements Serializable { } catch (Exception e) { s.append("[exception: ").append(e.getMessage()).append("]"); } - s.append("\n"); + s.append(String.format("%n")); } for (TransactionOutput out : outputs) { s.append(" "); @@ -588,7 +588,7 @@ public class Transaction extends ChildMessage implements Serializable { } catch (Exception e) { s.append("[exception: ").append(e.getMessage()).append("]"); } - s.append("\n"); + s.append(String.format("%n")); } return s.toString(); } diff --git a/core/src/main/java/com/google/bitcoin/core/TransactionConfidence.java b/core/src/main/java/com/google/bitcoin/core/TransactionConfidence.java index 5f9ec2e8..2356ba8f 100644 --- a/core/src/main/java/com/google/bitcoin/core/TransactionConfidence.java +++ b/core/src/main/java/com/google/bitcoin/core/TransactionConfidence.java @@ -373,11 +373,14 @@ public class TransactionConfidence implements Serializable { /** Returns a copy of this object. Event listeners are not duplicated. */ public synchronized TransactionConfidence duplicate() { TransactionConfidence c = new TransactionConfidence(transaction); - c.broadcastBy.addAll(broadcastBy); - c.confidenceType = confidenceType; - c.overridingTransaction = overridingTransaction; - c.appearedAtChainHeight = appearedAtChainHeight; - return c; + // There is no point in this sync block, it's just to help FindBugs. + synchronized (c) { + c.broadcastBy.addAll(broadcastBy); + c.confidenceType = confidenceType; + c.overridingTransaction = overridingTransaction; + c.appearedAtChainHeight = appearedAtChainHeight; + return c; + } } private void runListeners() { diff --git a/core/src/main/java/com/google/bitcoin/core/Wallet.java b/core/src/main/java/com/google/bitcoin/core/Wallet.java index 8e17c93a..ec5f7d86 100644 --- a/core/src/main/java/com/google/bitcoin/core/Wallet.java +++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java @@ -1327,13 +1327,13 @@ public class Wallet implements Serializable { @Override public synchronized String toString() { StringBuilder builder = new StringBuilder(); - builder.append(String.format("Wallet containing %s BTC in:\n", bitcoinValueToFriendlyString(getBalance()))); - builder.append(String.format(" %d unspent transactions\n", unspent.size())); - builder.append(String.format(" %d spent transactions\n", spent.size())); - builder.append(String.format(" %d pending transactions\n", pending.size())); - builder.append(String.format(" %d inactive transactions\n", inactive.size())); - builder.append(String.format(" %d dead transactions\n", dead.size())); - builder.append(String.format("Last seen best block: %s\n", getLastBlockSeenHash())); + builder.append(String.format("Wallet containing %s BTC in:%n", bitcoinValueToFriendlyString(getBalance()))); + builder.append(String.format(" %d unspent transactions%n", unspent.size())); + builder.append(String.format(" %d spent transactions%n", spent.size())); + builder.append(String.format(" %d pending transactions%n", pending.size())); + builder.append(String.format(" %d inactive transactions%n", inactive.size())); + builder.append(String.format(" %d dead transactions%n", dead.size())); + builder.append(String.format("Last seen best block: %s%n", getLastBlockSeenHash())); // Do the keys. builder.append("\nKeys:\n"); for (ECKey key : keychain) { @@ -1514,7 +1514,7 @@ public class Wallet implements Serializable { // The old blocks have contributed to the depth and work done for all the transactions in the // wallet that are in blocks up to and including the chain split block. // The total depth and work done is calculated here and then subtracted from the appropriate transactions. - int depthToSubtract = oldBlocks == null ? 0 : oldBlocks.size(); + int depthToSubtract = oldBlocks.size(); BigInteger workDoneToSubtract = BigInteger.ZERO; for (StoredBlock b : oldBlocks) { diff --git a/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java b/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java index 46a7e259..1d41abd1 100644 --- a/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java +++ b/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java @@ -94,8 +94,8 @@ public class IrcDiscovery implements PeerDiscovery { InetAddress ip = InetAddress.getByName("irc.lfnet.org"); log.info("Connecting to IRC with " + ip); connection = new Socket(server, port); - writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream())); - BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8")); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); // Generate a random nick for the connection. This is chosen to be clearly identifiable as coming from // BitCoinJ but not match the standard nick format, so full peers don't try and connect to us. diff --git a/core/src/test/java/com/google/bitcoin/core/WalletTest.java b/core/src/test/java/com/google/bitcoin/core/WalletTest.java index ae72f2a1..1c090c97 100644 --- a/core/src/test/java/com/google/bitcoin/core/WalletTest.java +++ b/core/src/test/java/com/google/bitcoin/core/WalletTest.java @@ -402,9 +402,6 @@ public class WalletTest { assertEquals(TransactionConfidence.ConfidenceType.OVERRIDDEN_BY_DOUBLE_SPEND, send1.getConfidence().getConfidenceType()); - // Receive 10 BTC. - nanos = Utils.toNanoCoins(10, 0); - TestUtils.DoubleSpends doubleSpends = TestUtils.createFakeDoubleSpendTxns(params, myAddress); // t1 spends to our wallet. t2 double spends somewhere else. wallet.receivePending(doubleSpends.t1);