Replace all asserts with Preconditions, which are always enabled. Updates issue 132.

This commit is contained in:
Mike Hearn
2012-04-02 14:09:52 +02:00
parent 3e5f796407
commit 628cbb6a1d
16 changed files with 104 additions and 70 deletions

View File

@@ -24,6 +24,8 @@ import org.slf4j.LoggerFactory;
import java.math.BigInteger;
import java.util.*;
import static com.google.common.base.Preconditions.*;
/**
* A BlockChain holds a series of {@link Block} objects, links them together, and knows how to verify that the
* chain follows the rules of the {@link NetworkParameters} for this chain.<p>
@@ -195,7 +197,7 @@ public class BlockChain {
// We can't find the previous block. Probably we are still in the process of downloading the chain and a
// block was solved whilst we were doing it. We put it to one side and try to connect it later when we
// have more blocks.
assert tryConnecting : "bug in tryConnectingUnconnected";
checkState(tryConnecting, "bug in tryConnectingUnconnected");
log.warn("Block does not connect: {}", block.getHashAsString());
unconnectedBlocks.add(block);
return false;
@@ -293,13 +295,12 @@ public class BlockChain {
* Returns the set of contiguous blocks between 'higher' and 'lower'. Higher is included, lower is not.
*/
private List<StoredBlock> getPartialChain(StoredBlock higher, StoredBlock lower) throws BlockStoreException {
assert higher.getHeight() > lower.getHeight();
checkArgument(higher.getHeight() > lower.getHeight(), "higher and lower are reversed");
LinkedList<StoredBlock> results = new LinkedList<StoredBlock>();
StoredBlock cursor = higher;
while (true) {
results.add(cursor);
cursor = cursor.getPrev(blockStore);
assert cursor != null : "Ran off the end of the chain";
cursor = checkNotNull(cursor.getPrev(blockStore), "Ran off the end of the chain");
if (cursor.equals(lower)) break;
}
return results;
@@ -322,10 +323,10 @@ public class BlockChain {
while (!currentChainCursor.equals(newChainCursor)) {
if (currentChainCursor.getHeight() > newChainCursor.getHeight()) {
currentChainCursor = currentChainCursor.getPrev(blockStore);
assert currentChainCursor != null : "Attempt to follow an orphan chain";
checkNotNull(currentChainCursor, "Attempt to follow an orphan chain");
} else {
newChainCursor = newChainCursor.getPrev(blockStore);
assert newChainCursor != null : "Attempt to follow an orphan chain";
checkNotNull(newChainCursor, "Attempt to follow an orphan chain");
}
}
return currentChainCursor;

View File

@@ -33,6 +33,8 @@ import java.io.Serializable;
import java.math.BigInteger;
import java.security.SecureRandom;
import static com.google.common.base.Preconditions.checkArgument;
// TODO: This class is quite a mess by now. Once users are migrated away from Java serialization for the wallets,
// refactor this to have better internal layout and a more consistent API.
@@ -281,8 +283,9 @@ public class ECKey implements Serializable {
try {
ASN1InputStream decoder = new ASN1InputStream(asn1privkey);
DERSequence seq = (DERSequence) decoder.readObject();
assert seq.size() == 4 : "Input does not appear to be an ASN.1 OpenSSL EC private key";
assert ((DERInteger) seq.getObjectAt(0)).getValue().equals(BigInteger.ONE) : "Input is of wrong version";
checkArgument(seq.size() == 4, "Input does not appear to be an ASN.1 OpenSSL EC private key");
checkArgument(((DERInteger) seq.getObjectAt(0)).getValue().equals(BigInteger.ONE),
"Input is of wrong version");
DEROctetString key = (DEROctetString) seq.getObjectAt(1);
decoder.close();
return new BigInteger(key.getOctets());

View File

@@ -23,6 +23,8 @@ import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import static com.google.common.base.Preconditions.checkState;
/**
* A Message is a data structure that can be serialized/deserialized using both the BitCoin proprietary serialization
* format and built-in Java object serialization. Specific types of messages that are used both in the block chain,
@@ -114,9 +116,12 @@ public abstract class Message implements Serializable {
parse();
parsed = true;
}
assert this.length != UNKNOWN_LENGTH: "Length field has not been set in constructor for " + getClass().getSimpleName() + " after " + (parseLazy ? "lite" : "full") + " parse. Refer to Message.parseLite() for detail of required Length field contract.";
checkState(this.length != UNKNOWN_LENGTH,
"Length field has not been set in constructor for %s after %s parse. " +
"Refer to Message.parseLite() for detail of required Length field contract.",
getClass().getSimpleName(), parseLazy ? "lite" : "full");
if (SELF_CHECK) {
selfCheck(msg, offset);
}
@@ -307,7 +312,7 @@ public abstract class Message implements Serializable {
return buf;
}
assert bytes == null : "cached bytes present but failed to use them for serialization";
checkState(bytes == null, "Cached bytes present but failed to use them for serialization");
// No cached array available so serialize parts by stream.
ByteArrayOutputStream stream = new UnsafeByteArrayOutputStream(length < 32 ? 32 : length + 32);
@@ -386,7 +391,8 @@ public abstract class Message implements Serializable {
if (length != UNKNOWN_LENGTH)
return length;
maybeParse();
assert length != UNKNOWN_LENGTH: "Length field has not been set in " + getClass().getSimpleName() + " after full parse.";
checkState(length != UNKNOWN_LENGTH,
"Length field has not been set in %s after full parse.", getClass().getSimpleName());
return length;
}

View File

@@ -22,6 +22,8 @@ import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.math.BigInteger;
import static com.google.common.base.Preconditions.checkState;
/**
* NetworkParameters contains the data needed for working with an instantiation of a BitCoin chain.
*
@@ -140,7 +142,8 @@ public class NetworkParameters implements Serializable {
n.genesisBlock.setNonce(384568319);
n.id = ID_TESTNET;
String genesisHash = n.genesisBlock.getHashAsString();
assert genesisHash.equals("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008") : genesisHash;
checkState(genesisHash.equals("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"),
genesisHash);
return n;
}
@@ -167,7 +170,8 @@ public class NetworkParameters implements Serializable {
n.genesisBlock.setNonce(2083236893);
n.id = ID_PRODNET;
String genesisHash = n.genesisBlock.getHashAsString();
assert genesisHash.equals("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") : genesisHash;
checkState(genesisHash.equals("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"),
genesisHash);
return n;
}

View File

@@ -31,6 +31,9 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Maintain a number of connections to peers.<p>
*
@@ -228,13 +231,12 @@ public class PeerGroup {
* to stop until the listener returns.</p>
*/
public synchronized void addEventListener(PeerEventListener listener) {
assert listener != null;
peerEventListeners.add(listener);
peerEventListeners.add(checkNotNull(listener));
}
/** The given event listener will no longer be called with events. */
public synchronized boolean removeEventListener(PeerEventListener listener) {
return peerEventListeners.remove(listener);
return peerEventListeners.remove(checkNotNull(listener));
}
/**
@@ -730,7 +732,7 @@ public class PeerGroup {
log.info("Peer death while shutting down");
return;
}
assert !peers.contains(peer);
checkArgument(!peers.contains(peer));
if (peer == downloadPeer) {
log.info("Download peer died. Picking a new one.");
setDownloadPeer(null);

View File

@@ -24,6 +24,8 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import static com.google.common.base.Preconditions.checkArgument;
/**
* A Sha256Hash just wraps a byte[] so that equals and hashcode work correctly, allowing it to be used as keys in a
* map. It also checks that the length is correct and provides a bit more type safety.
@@ -69,13 +71,13 @@ public class Sha256Hash implements Serializable {
* Creates a Sha256Hash by wrapping the given byte array. It must be 32 bytes long.
*/
public Sha256Hash(byte[] bytes) {
assert bytes.length == 32;
checkArgument(bytes.length == 32);
this.bytes = bytes;
}
private Sha256Hash(byte[] bytes, int hash) {
assert bytes.length == 32;
checkArgument(bytes.length == 32);
this.bytes = bytes;
this.hash = hash;
}
@@ -84,7 +86,7 @@ public class Sha256Hash implements Serializable {
* Creates a Sha256Hash by decoding the given hex string. It must be 64 characters long.
*/
public Sha256Hash(String string) {
assert string.length() == 64;
checkArgument(string.length() == 64);
this.bytes = Hex.decode(string);
}

View File

@@ -16,6 +16,7 @@
package com.google.bitcoin.core;
import com.google.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -198,7 +199,7 @@ public class Transaction extends ChildMessage implements Serializable {
return appearsInHashes;
if (appearsIn != null) {
assert appearsInHashes == null;
Preconditions.checkState(appearsInHashes == null);
log.info("Migrating a tx to appearsInHashes");
appearsInHashes = new HashSet<Sha256Hash>(appearsIn.size());
for (StoredBlock block : appearsIn) {
@@ -592,11 +593,11 @@ public class Transaction extends ChildMessage implements Serializable {
* @param wallet A wallet is required to fetch the keys needed for signing.
*/
public void signInputs(SigHash hashType, Wallet wallet) throws ScriptException {
assert inputs.size() > 0;
assert outputs.size() > 0;
Preconditions.checkState(inputs.size() > 0);
Preconditions.checkState(outputs.size() > 0);
// I don't currently have an easy way to test other modes work, as the official client does not use them.
assert hashType == SigHash.ALL;
Preconditions.checkArgument(hashType == SigHash.ALL, "Only SIGHASH_ALL is currently supported");
// The transaction is signed with the input scripts empty except for the input we are signing. In the case
// where addInput has been used to set up a new transaction, they are already all empty. The input being signed
@@ -609,14 +610,15 @@ public class Transaction extends ChildMessage implements Serializable {
ECKey[] signingKeys = new ECKey[inputs.size()];
for (int i = 0; i < inputs.size(); i++) {
TransactionInput input = inputs.get(i);
assert input.getScriptBytes().length == 0 : "Attempting to sign a non-fresh transaction";
Preconditions.checkState(input.getScriptBytes().length == 0, "Attempting to sign a non-fresh transaction");
// Set the input to the script of its output.
input.setScriptBytes(input.getOutpoint().getConnectedPubKeyScript());
// Find the signing key we'll need to use.
byte[] connectedPubKeyHash = input.getOutpoint().getConnectedPubKeyHash();
ECKey key = wallet.findKeyFromPubHash(connectedPubKeyHash);
// This assert should never fire. If it does, it means the wallet is inconsistent.
assert key != null : "Transaction exists in wallet that we cannot redeem: " + bytesToHexString(connectedPubKeyHash);
Preconditions.checkNotNull(key, "Transaction exists in wallet that we cannot redeem: %s",
bytesToHexString(connectedPubKeyHash));
// Keep the key around for the script creation step below.
signingKeys[i] = key;
// The anyoneCanPay feature isn't used at the moment.
@@ -643,7 +645,7 @@ public class Transaction extends ChildMessage implements Serializable {
// output.
for (int i = 0; i < inputs.size(); i++) {
TransactionInput input = inputs.get(i);
assert input.getScriptBytes().length == 0;
Preconditions.checkState(input.getScriptBytes().length == 0);
ECKey key = signingKeys[i];
input.setScriptBytes(Script.createInputScript(signatures[i], key.getPubKey()));
}

View File

@@ -16,6 +16,8 @@
package com.google.bitcoin.core;
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
@@ -156,8 +158,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
// parameter is overloaded to be something totally different.
if (scriptSig == null) {
maybeParse();
assert scriptBytes != null;
scriptSig = new Script(params, scriptBytes, 0, scriptBytes.length);
scriptSig = new Script(params, Preconditions.checkNotNull(scriptBytes), 0, scriptBytes.length);
}
return scriptSig;
}

View File

@@ -21,6 +21,9 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
/**
* This message is a reference or pointer to an output of a different transaction.
*/
@@ -118,9 +121,8 @@ public class TransactionOutPoint extends ChildMessage implements Serializable {
* Returns the pubkey script from the connected output.
*/
byte[] getConnectedPubKeyScript() {
byte[] result = getConnectedOutput().getScriptBytes();
assert result != null;
assert result.length > 0;
byte[] result = checkNotNull(getConnectedOutput().getScriptBytes());
checkState(result.length > 0);
return result;
}

View File

@@ -25,6 +25,9 @@ import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigInteger;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
/**
* A TransactionOutput message contains a scriptPubKey that controls who is able to spend its value. It is a sub-part
* of the Transaction message.
@@ -132,7 +135,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
@Override
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
assert scriptBytes != null;
checkNotNull(scriptBytes);
Utils.uint64ToByteStreamLE(getValue(), stream);
// TODO: Move script serialization into the Script class, where it belongs.
stream.write(new VarInt(scriptBytes.length).encode());
@@ -149,7 +152,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
}
int getIndex() {
assert parentTransaction != null;
checkNotNull(parentTransaction);
for (int i = 0; i < parentTransaction.getOutputs().size(); i++) {
if (parentTransaction.getOutputs().get(i) == this)
return i;
@@ -163,7 +166,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
* If the input is null, it means this output was signed over to somebody else rather than one of our own keys.
*/
public void markAsSpent(TransactionInput input) {
assert availableForSpending;
checkState(availableForSpending);
availableForSpending = false;
spentBy = input;
}

View File

@@ -26,6 +26,8 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import static com.google.common.base.Preconditions.checkArgument;
/**
* A collection of various utility methods that are helpful for working with the BitCoin protocol.
* To enable debug logging from the library, run with -Dbitcoinj.logging=true on your command line.
@@ -55,7 +57,7 @@ public class Utils {
* Convert an amount expressed in the way humans are used to into nanocoins.
*/
public static BigInteger toNanoCoins(int coins, int cents) {
assert cents < 100;
checkArgument(cents < 100);
BigInteger bi = BigInteger.valueOf(coins).multiply(COIN);
bi = bi.add(BigInteger.valueOf(cents).multiply(CENT));
return bi;
@@ -216,8 +218,8 @@ public class Utils {
* @param trimLength trim output to this length. If positive, must be divisible by 4.
*/
public static byte[] reverseDwordBytes(byte[] bytes, int trimLength) {
assert bytes.length % 4 == 0;
assert trimLength < 0 || trimLength % 4 == 0;
checkArgument(bytes.length % 4 == 0);
checkArgument(trimLength < 0 || trimLength % 4 == 0);
byte[] rev = new byte[trimLength >= 0 && bytes.length > trimLength ? trimLength : bytes.length];

View File

@@ -18,6 +18,8 @@ package com.google.bitcoin.core;
import java.util.Arrays;
import static com.google.common.base.Preconditions.checkArgument;
/**
* <p>In Bitcoin the following format is often used to represent some type of key:</p>
* <p/>
@@ -38,7 +40,7 @@ public class VersionedChecksummedBytes {
}
protected VersionedChecksummedBytes(int version, byte[] bytes) {
assert version < 256 && version >= 0;
checkArgument(version < 256 && version >= 0);
this.version = version;
this.bytes = bytes;
}

View File

@@ -27,6 +27,7 @@ import java.util.*;
import java.util.concurrent.ExecutionException;
import static com.google.bitcoin.core.Utils.bitcoinValueToFriendlyString;
import static com.google.common.base.Preconditions.*;
/**
* A Wallet stores keys and a record of transactions that have not yet been spent. Thus, it is capable of
@@ -442,13 +443,13 @@ public class Wallet implements Serializable {
// There were no change transactions so this tx is fully spent.
log.info(" ->spent");
boolean alreadyPresent = spent.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "TX in both pending and spent pools";
checkState(!alreadyPresent, "TX in both pending and spent pools");
} else {
// There was change back to us, or this tx was purely a spend back to ourselves (perhaps for
// anonymization purposes).
log.info(" ->unspent");
boolean alreadyPresent = unspent.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "TX in both pending and unspent pools";
checkState(!alreadyPresent, "TX in both pending and unspent pools");
}
} else if (sideChain) {
// The transaction was accepted on an inactive side chain, but not yet by the best chain.
@@ -516,7 +517,7 @@ public class Wallet implements Serializable {
}
}
assert isConsistent();
checkState(isConsistent());
}
/**
@@ -531,12 +532,12 @@ public class Wallet implements Serializable {
// It's sending us coins.
log.info(" new tx ->unspent");
boolean alreadyPresent = unspent.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "TX was received twice";
checkState(!alreadyPresent, "TX was received twice");
} else if (!tx.getValueSentFromMe(this).equals(BigInteger.ZERO)) {
// It spent some of our coins and did not send us any.
log.info(" new tx ->spent");
boolean alreadyPresent = spent.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "TX was received twice";
checkState(!alreadyPresent, "TX was received twice");
} else {
// It didn't send us coins nor spend any of our coins. If we're processing it, that must be because it
// spends outpoints that are also spent by some pending transactions - maybe a double spend of somebody
@@ -591,13 +592,13 @@ public class Wallet implements Serializable {
// A -> spent by B [pending]
// \-> spent by C [chain]
Transaction doubleSpent = input.getOutpoint().fromTx; // == A
assert doubleSpent != null;
checkNotNull(doubleSpent);
int index = (int) input.getOutpoint().getIndex();
TransactionOutput output = doubleSpent.getOutputs().get(index);
TransactionInput spentBy = output.getSpentBy();
assert spentBy != null;
checkNotNull(spentBy);
Transaction connected = spentBy.getParentTransaction();
assert connected != null;
checkNotNull(connected);
if (fromChain) {
// This must have overridden a pending tx, or the block is bad (contains transactions
// that illegally double spend: should never occur if we are connected to an honest node).
@@ -677,7 +678,7 @@ public class Wallet implements Serializable {
* </ol>
*/
public synchronized void commitTx(Transaction tx) throws VerificationException {
assert !pending.containsKey(tx.getHash()) : "commitTx called on the same transaction twice";
checkArgument(!pending.containsKey(tx.getHash()), "commitTx called on the same transaction twice");
log.info("commitTx of {}", tx.getHashAsString());
BigInteger balance = getBalance();
tx.updatedAt = Utils.now();
@@ -703,7 +704,7 @@ public class Wallet implements Serializable {
throw new RuntimeException(e);
}
assert isConsistent();
checkState(isConsistent());
}
/**
@@ -798,7 +799,7 @@ public class Wallet implements Serializable {
* depending on how the wallet is implemented (eg if backed by a database).
*/
public synchronized List<Transaction> getRecentTransactions(int numTransactions, boolean includeDead) {
assert numTransactions >= 0;
checkArgument(numTransactions >= 0);
// Firstly, put all transactions into an array.
int size = getPoolSize(WalletTransaction.Pool.UNSPENT) +
getPoolSize(WalletTransaction.Pool.SPENT) +
@@ -1064,7 +1065,7 @@ public class Wallet implements Serializable {
// TODO: Should throw an exception here.
return false;
}
assert gathered.size() > 0;
checkState(gathered.size() > 0);
sendTx.getConfidence().setConfidenceType(TransactionConfidence.ConfidenceType.NOT_SEEN_IN_CHAIN);
BigInteger change = valueGathered.subtract(nanocoins);
if (change.compareTo(BigInteger.ZERO) > 0) {
@@ -1103,7 +1104,7 @@ public class Wallet implements Serializable {
synchronized Address getChangeAddress() {
// For now let's just pick the first key in our keychain. In future we might want to do something else to
// give the user better privacy here, eg in incognito mode.
assert keychain.size() > 0 : "Can't send value without an address to use for receiving change";
checkState(keychain.size() > 0, "Can't send value without an address to use for receiving change");
ECKey first = keychain.get(0);
return first.toAddress(params);
}
@@ -1112,7 +1113,7 @@ public class Wallet implements Serializable {
* Adds the given ECKey to the wallet. There is currently no way to delete keys (that would result in coin loss).
*/
public synchronized void addKey(ECKey key) {
assert !keychain.contains(key);
checkArgument(!keychain.contains(key), "Key already present");
keychain.add(key);
}
@@ -1204,7 +1205,7 @@ public class Wallet implements Serializable {
}
if (balanceType == BalanceType.AVAILABLE)
return available;
assert balanceType == BalanceType.ESTIMATED;
checkState(balanceType == BalanceType.ESTIMATED);
// Now add back all the pending outputs to assume the transaction goes through.
BigInteger estimated = available;
for (Transaction tx : pending.values()) {
@@ -1321,7 +1322,7 @@ public class Wallet implements Serializable {
all.putAll(inactive);
for (Transaction tx : all.values()) {
Collection<Sha256Hash> appearsIn = tx.getAppearsInHashes();
assert appearsIn != null;
checkNotNull(appearsIn);
// If the set of blocks this transaction appears in is disjoint with one of the chain segments it means
// the transaction was never incorporated by a miner into that side of the chain.
boolean inOldSection = !Collections.disjoint(appearsIn, oldBlockHashes);
@@ -1330,19 +1331,19 @@ public class Wallet implements Serializable {
if (inCommonSection) {
boolean alreadyPresent = commonChainTransactions.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "Transaction appears twice in common chain segment";
checkState(!alreadyPresent, "Transaction appears twice in common chain segment");
} else {
if (inOldSection) {
boolean alreadyPresent = oldChainTransactions.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "Transaction appears twice in old chain segment";
checkState(!alreadyPresent, "Transaction appears twice in old chain segment");
if (!inNewSection) {
alreadyPresent = onlyOldChainTransactions.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "Transaction appears twice in only-old map";
checkState(!alreadyPresent, "Transaction appears twice in only-old map");
}
}
if (inNewSection) {
boolean alreadyPresent = newChainTransactions.put(tx.getHash(), tx) != null;
assert !alreadyPresent : "Transaction appears twice in new chain segment";
checkState(!alreadyPresent, "Transaction appears twice in new chain segment");
}
}
}
@@ -1370,7 +1371,8 @@ public class Wallet implements Serializable {
// Reconnect the transactions in the common part of the chain.
for (Transaction tx : commonChainTransactions.values()) {
TransactionInput badInput = tx.connectForReorganize(all);
assert badInput == null : "Failed to connect " + tx.getHashAsString() + ", " + badInput.toString();
checkState(badInput == null, "Failed to connect %s, %s", tx.getHashAsString(),
badInput == null ? "" : badInput.toString());
}
// Recalculate the unspent/spent buckets for the transactions the re-org did not affect.
log.info("Moving transactions");
@@ -1458,7 +1460,7 @@ public class Wallet implements Serializable {
listener.onReorganize(Wallet.this);
}
});
assert isConsistent();
checkState(isConsistent());
}
private void reprocessTxAfterReorg(Map<Sha256Hash, Transaction> pool, Transaction tx) {

View File

@@ -17,6 +17,8 @@
package com.google.bitcoin.core;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A Transaction in a Wallet - includes the pool ID
*
@@ -68,9 +70,7 @@ public class WalletTransaction {
private Pool pool;
public WalletTransaction(Pool pool, Transaction transaction) {
assert pool != null;
this.pool = pool;
this.pool = checkNotNull(pool);
this.transaction = transaction;
}

View File

@@ -18,7 +18,6 @@ package com.google.bitcoin.store;
import com.google.bitcoin.core.*;
import com.google.bitcoin.utils.NamedSemaphores;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,6 +34,8 @@ import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkState;
/**
* Stores the block chain to disk.<p>
*
@@ -107,7 +108,7 @@ public class BoundedOverheadBlockStore implements BlockStore {
ByteBuffer buf = ByteBuffer.allocate(Record.SIZE);
buf.putInt(block.getHeight());
byte[] chainWorkBytes = block.getChainWork().toByteArray();
assert chainWorkBytes.length <= CHAIN_WORK_BYTES : "Ran out of space to store chain work!";
checkState(chainWorkBytes.length <= CHAIN_WORK_BYTES, "Ran out of space to store chain work!");
if (chainWorkBytes.length < CHAIN_WORK_BYTES) {
// Pad to the right size.
buf.put(EMPTY_BYTES, 0, CHAIN_WORK_BYTES - chainWorkBytes.length);
@@ -330,7 +331,7 @@ public class BoundedOverheadBlockStore implements BlockStore {
} else {
// Move backwards.
pos = pos - Record.SIZE;
assert pos >= 1 + 32 : pos;
checkState(pos >= 1 + 32, pos);
}
numMoves++;
} while (pos != startPos);

View File

@@ -18,7 +18,6 @@ package com.google.bitcoin.store;
import com.google.bitcoin.core.*;
import com.google.bitcoin.utils.NamedSemaphores;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,6 +31,8 @@ import java.nio.channels.OverlappingFileLockException;
import java.util.HashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkState;
/**
* Stores the block chain to disk but still holds it in memory. This is intended for desktop apps and tests.
* Constrained environments like mobile phones probably won't want to or be able to store all the block headers in RAM.
@@ -183,7 +184,7 @@ public class DiskBlockStore implements BlockStore {
ensureOpen();
try {
Sha256Hash hash = block.getHeader().getHash();
assert blockMap.get(hash) == null : "Attempt to insert duplicate";
checkState(blockMap.get(hash) == null, "Attempt to insert duplicate");
// Append to the end of the file. The other fields in StoredBlock will be recalculated when it's reloaded.
byte[] bytes = block.getHeader().bitcoinSerialize();
file.write(bytes);