mirror of
				https://github.com/Qortal/altcoinj.git
				synced 2025-11-03 05:57:21 +00:00 
			
		
		
		
	Replace all asserts with Preconditions, which are always enabled. Updates issue 132.
This commit is contained in:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
@@ -115,7 +117,10 @@ public abstract class Message implements Serializable {
 | 
			
		||||
            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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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()));
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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];
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user