org.bitcoinj.core.TransactionConfidence.ConfidenceType Java Examples

The following examples show how to use org.bitcoinj.core.TransactionConfidence.ConfidenceType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ElectrumMultiWallet.java    From java-stratum with Apache License 2.0 6 votes vote down vote up
@Override
public byte[] serializeWalletExtension() {
    Protos.Electrum.Builder extension = Protos.Electrum.newBuilder();
    for (Transaction tx : txs.values()) {
        TransactionConfidence confidence = tx.getConfidence();
        Protos.TransactionConfidence.Builder confidenceBuilder = Protos.TransactionConfidence.newBuilder();
        confidenceBuilder.setType(Protos.TransactionConfidence.Type.valueOf(confidence.getConfidenceType().getValue()));
        if (confidence.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
            confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
            confidenceBuilder.setDepth(confidence.getDepthInBlocks());
        }

        Protos.Transaction.Builder transaction =
                Protos.Transaction.newBuilder()
                        .setConfidence(confidenceBuilder)
                        .setTransaction(ByteString.copyFrom(tx.bitcoinSerialize()));
        if (tx.getUpdateTime() != null)
            transaction.setUpdatedAt(tx.getUpdateTime().getTime());
        extension.addTransactions(transaction.build());
    }
    return extension.build().toByteArray();
}
 
Example #2
Source File: ElectrumMultiWalletTest.java    From java-stratum with Apache License 2.0 6 votes vote down vote up
@Test
public void testPendingToConfirmed() throws Exception {
    ECKey key = new ECKey();
    String address = key.toAddress(params).toString();
    Transaction tx = new Transaction(params, Utils.HEX.decode(TEST_TX));
    supplyUnconfirmedTransactionForAddress(address, tx);
    supplyTransactionForAddress(address, tx);
    control.replay();
    multiWallet.retrieveAddressHistory(address);
    assertEquals(1, multiWallet.getTransactions().size());
    TransactionConfidence confidence = multiWallet.getTransactions().iterator().next().getConfidence();
    assertEquals(ConfidenceType.PENDING, confidence.getConfidenceType());

    multiWallet.retrieveAddressHistory(address);
    assertEquals(1, multiWallet.getTransactions().size());
    Transaction tx1 = multiWallet.getTransactions().iterator().next();
    assertEquals(ConfidenceType.BUILDING, tx1.getConfidence().getConfidenceType());
    assertEquals(params.getGenesisBlock().getTime(), tx1.getUpdateTime());
    control.verify();
}
 
Example #3
Source File: ChainSplitTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testForking4() throws Exception {
    // Check that we can handle external spends on an inactive chain becoming active. An external spend is where
    // we see a transaction that spends our own coins but we did not broadcast it ourselves. This happens when
    // keys are being shared between wallets.
    Block b1 = UNITTEST.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = LegacyAddress.fromKey(UNITTEST, new ECKey());
    Transaction spend = wallet.createSend(dest, FIFTY_COINS);
    // We do NOT confirm the spend here. That means it's not considered to be pending because createSend is
    // stateless. For our purposes it is as if some other program with our keys created the tx.
    //
    // genesis -> b1 (receive 50) --> b2
    //                            \-> b3 (external spend) -> b4
    Block b2 = b1.createNextBlock(someOtherGuy);
    chain.add(b2);
    Block b3 = b1.createNextBlock(someOtherGuy);
    b3.addTransaction(spend);
    b3.solve();
    chain.add(roundtrip(b3));
    // The external spend is now pending.
    assertEquals(ZERO, wallet.getBalance());
    Transaction tx = wallet.getTransaction(spend.getHash());
    assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType());
    Block b4 = b3.createNextBlock(someOtherGuy);
    chain.add(b4);
    // The external spend is now active.
    assertEquals(ZERO, wallet.getBalance());
    assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
}
 
Example #4
Source File: ChainSplitTest.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testForking3() throws Exception {
    // Check that we can handle our own spends being rolled back by a fork.
    Block b1 = PARAMS.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(PARAMS);
    Transaction spend = wallet.createSend(dest, valueOf(10, 0));
    wallet.commitTx(spend);
    // Waiting for confirmation ... make it eligible for selection.
    assertEquals(Coin.ZERO, wallet.getBalance());
    spend.getConfidence().markBroadcastBy(new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
    spend.getConfidence().markBroadcastBy(new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[]{5,6,7,8})));
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
    assertEquals(valueOf(40, 0), wallet.getBalance());
    Block b2 = b1.createNextBlock(someOtherGuy);
    b2.addTransaction(spend);
    b2.solve();
    chain.add(roundtrip(b2));
    // We have 40 coins in change.
    assertEquals(ConfidenceType.BUILDING, spend.getConfidence().getConfidenceType());
    // genesis -> b1 (receive coins) -> b2 (spend coins)
    //                               \-> b3 -> b4
    Block b3 = b1.createNextBlock(someOtherGuy);
    Block b4 = b3.createNextBlock(someOtherGuy);
    chain.add(b3);
    chain.add(b4);
    // b4 causes a re-org that should make our spend go pending again.
    assertEquals(valueOf(40, 0), wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
 
Example #5
Source File: ChainSplitTest.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testForking4() throws Exception {
    // Check that we can handle external spends on an inactive chain becoming active. An external spend is where
    // we see a transaction that spends our own coins but we did not broadcast it ourselves. This happens when
    // keys are being shared between wallets.
    Block b1 = PARAMS.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(PARAMS);
    Transaction spend = wallet.createSend(dest, FIFTY_COINS);
    // We do NOT confirm the spend here. That means it's not considered to be pending because createSend is
    // stateless. For our purposes it is as if some other program with our keys created the tx.
    //
    // genesis -> b1 (receive 50) --> b2
    //                            \-> b3 (external spend) -> b4
    Block b2 = b1.createNextBlock(someOtherGuy);
    chain.add(b2);
    Block b3 = b1.createNextBlock(someOtherGuy);
    b3.addTransaction(spend);
    b3.solve();
    chain.add(roundtrip(b3));
    // The external spend is now pending.
    assertEquals(ZERO, wallet.getBalance());
    Transaction tx = wallet.getTransaction(spend.getHash());
    assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType());
    Block b4 = b3.createNextBlock(someOtherGuy);
    chain.add(b4);
    // The external spend is now active.
    assertEquals(ZERO, wallet.getBalance());
    assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
}
 
Example #6
Source File: ElectrumMultiWallet.java    From java-stratum with Apache License 2.0 5 votes vote down vote up
private void readConfidence(Transaction tx, Protos.TransactionConfidence confidenceProto,
                            TransactionConfidence confidence) throws UnreadableWalletException {
    // We are lenient here because tx confidence is not an essential part of the wallet.
    // If the tx has an unknown type of confidence, ignore.
    if (!confidenceProto.hasType()) {
        log.warn("Unknown confidence type for tx {}", tx.getHashAsString());
        return;
    }
    ConfidenceType confidenceType;
    switch (confidenceProto.getType()) {
        case BUILDING: confidenceType = ConfidenceType.BUILDING; break;
        case DEAD: confidenceType = ConfidenceType.DEAD; break;
        // These two are equivalent (must be able to read old wallets).
        case NOT_IN_BEST_CHAIN: confidenceType = ConfidenceType.PENDING; break;
        case PENDING: confidenceType = ConfidenceType.PENDING; break;
        case UNKNOWN:
            // Fall through.
        default:
            confidenceType = ConfidenceType.UNKNOWN; break;
    }
    confidence.setConfidenceType(confidenceType);
    if (confidenceProto.hasAppearedAtHeight()) {
        if (confidence.getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING) {
            log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
    }
    if (confidenceProto.hasDepth()) {
        if (confidence.getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING) {
            log.warn("Have depth but not BUILDING for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setDepthInBlocks(confidenceProto.getDepth());
    }
}
 
Example #7
Source File: ElectrumMultiWallet.java    From java-stratum with Apache License 2.0 5 votes vote down vote up
void receive(Transaction tx, int height) {
    // This is also a workaround to Context issue at Fetcher
    TransactionConfidence confidence = tx.getConfidence(confidenceTable);
    log.info("got tx {}", tx.getHashAsString());

    wallet.lock();
    try {
        boolean isNewCoin = !txs.containsKey(tx.getHash());
        if (height > 0) {
            Block block = store.get(height);
            if (block == null) {
                pendingBlock.add(new TransactionWithHeight(tx, height));
            } else {
                log.info("have block for {}", tx.getHash());
                pendingDownload.remove(tx.getHash()).set(tx);
                tx.setUpdateTime(block.getTime());
                confidence.setAppearedAtChainHeight(height);
                txs.put(tx.getHash(), tx);
                saveLater();
                notifyTransaction(tx, isNewCoin);
            }
        } else {
            log.info("unconfirmed {}", tx.getHash());
            pendingDownload.remove(tx.getHash()).set(tx);
            // Check if already processed pending tx.  If so, skip all processing.
            if (isNewCoin) {
                tx.setUpdateTime(new Date());
                confidence.setConfidenceType(ConfidenceType.PENDING);
                tx.getConfidence().markBroadcastBy(getPeerAddress());
                txs.put(tx.getHash(), tx);
                saveLater();
            }
            notifyTransaction(tx, isNewCoin);
        }
    } finally {
        wallet.unlock();
    }
    markKeysAsUsed(tx);
}
 
Example #8
Source File: WalletTest.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
@Test
@SuppressWarnings("deprecation")
// Having a test for deprecated method getFromAddress() is no evil so we suppress the warning here.
public void customTransactionSpending() throws Exception {
    // We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
    Coin v1 = valueOf(3, 0);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v1);
    assertEquals(v1, wallet.getBalance());
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(1, wallet.getTransactions(true).size());

    Coin v2 = valueOf(0, 50);
    Coin v3 = valueOf(0, 75);
    Coin v4 = valueOf(1, 25);

    Transaction t2 = new Transaction(PARAMS);
    t2.addOutput(v2, OTHER_ADDRESS);
    t2.addOutput(v3, OTHER_ADDRESS);
    t2.addOutput(v4, OTHER_ADDRESS);
    SendRequest req = SendRequest.forTx(t2);
    wallet.completeTx(req);

    // Do some basic sanity checks.
    assertEquals(1, t2.getInputs().size());
    assertEquals(myAddress, t2.getInput(0).getScriptSig().getFromAddress(PARAMS));
    assertEquals(TransactionConfidence.ConfidenceType.UNKNOWN, t2.getConfidence().getConfidenceType());

    // We have NOT proven that the signature is correct!
    wallet.commitTx(t2);
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.SPENT));
    assertEquals(2, wallet.getTransactions(true).size());
}
 
Example #9
Source File: Transaction.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
/**
 * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required coinbase depth, or a non-coinbase tx.
 */
public boolean isMature() {
    if (!isCoinBase())
        return true;

    if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING)
        return false;

    return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth();
}
 
Example #10
Source File: Transaction.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
/**
 * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required coinbase depth, or a non-coinbase tx.
 */
public boolean isMature() {
    if (!isCoinBase())
        return true;

    if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING)
        return false;

    return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth();
}
 
Example #11
Source File: ChainSplitTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testForking3() throws Exception {
    // Check that we can handle our own spends being rolled back by a fork.
    Block b1 = UNITTEST.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = LegacyAddress.fromKey(UNITTEST, new ECKey());
    Transaction spend = wallet.createSend(dest, valueOf(10, 0));
    wallet.commitTx(spend);
    // Waiting for confirmation ... make it eligible for selection.
    assertEquals(Coin.ZERO, wallet.getBalance());
    spend.getConfidence().markBroadcastBy(new PeerAddress(UNITTEST, InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
    spend.getConfidence().markBroadcastBy(new PeerAddress(UNITTEST, InetAddress.getByAddress(new byte[]{5, 6, 7, 8})));
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
    assertEquals(valueOf(40, 0), wallet.getBalance());
    Block b2 = b1.createNextBlock(someOtherGuy);
    b2.addTransaction(spend);
    b2.solve();
    chain.add(roundtrip(b2));
    // We have 40 coins in change.
    assertEquals(ConfidenceType.BUILDING, spend.getConfidence().getConfidenceType());
    // genesis -> b1 (receive coins) -> b2 (spend coins)
    //                               \-> b3 -> b4
    Block b3 = b1.createNextBlock(someOtherGuy);
    Block b4 = b3.createNextBlock(someOtherGuy);
    chain.add(b3);
    chain.add(b4);
    // b4 causes a re-org that should make our spend go pending again.
    assertEquals(valueOf(40, 0), wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
 
Example #12
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
@SuppressWarnings("deprecation")
// Having a test for deprecated method getFromAddress() is no evil so we suppress the warning here.
public void customTransactionSpending() throws Exception {
    // We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
    Coin v1 = valueOf(3, 0);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v1);
    assertEquals(v1, wallet.getBalance());
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(1, wallet.getTransactions(true).size());

    Coin v2 = valueOf(0, 50);
    Coin v3 = valueOf(0, 75);
    Coin v4 = valueOf(1, 25);

    Transaction t2 = new Transaction(PARAMS);
    t2.addOutput(v2, OTHER_ADDRESS);
    t2.addOutput(v3, OTHER_ADDRESS);
    t2.addOutput(v4, OTHER_ADDRESS);
    SendRequest req = SendRequest.forTx(t2);
    wallet.completeTx(req);

    // Do some basic sanity checks.
    assertEquals(1, t2.getInputs().size());
    assertEquals(myAddress, t2.getInput(0).getScriptSig().getFromAddress(PARAMS));
    assertEquals(TransactionConfidence.ConfidenceType.UNKNOWN, t2.getConfidence().getConfidenceType());

    // We have NOT proven that the signature is correct!
    wallet.commitTx(t2);
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.SPENT));
    assertEquals(2, wallet.getTransactions(true).size());
}
 
Example #13
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void customTransactionSpending() throws Exception {
    // We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
    Coin v1 = valueOf(3, 0);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v1);
    assertEquals(v1, wallet.getBalance());
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(1, wallet.getTransactions(true).size());

    Coin v2 = valueOf(0, 50);
    Coin v3 = valueOf(0, 75);
    Coin v4 = valueOf(1, 25);

    Transaction t2 = new Transaction(UNITTEST);
    t2.addOutput(v2, OTHER_ADDRESS);
    t2.addOutput(v3, OTHER_ADDRESS);
    t2.addOutput(v4, OTHER_ADDRESS);
    SendRequest req = SendRequest.forTx(t2);
    wallet.completeTx(req);

    // Do some basic sanity checks.
    assertEquals(1, t2.getInputs().size());
    List<ScriptChunk> scriptSigChunks = t2.getInput(0).getScriptSig().getChunks();
    // check 'from address' -- in a unit test this is fine
    assertEquals(2, scriptSigChunks.size());
    assertEquals(myAddress, LegacyAddress.fromPubKeyHash(UNITTEST, Utils.sha256hash160(scriptSigChunks.get(1).data)));
    assertEquals(TransactionConfidence.ConfidenceType.UNKNOWN, t2.getConfidence().getConfidenceType());

    // We have NOT proven that the signature is correct!
    wallet.commitTx(t2);
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.SPENT));
    assertEquals(2, wallet.getTransactions(true).size());
}
 
Example #14
Source File: Transaction.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
/**
 * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required coinbase depth, or a non-coinbase tx.
 */
public boolean isMature() {
    if (!isCoinBase())
        return true;

    if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING)
        return false;

    return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth();
}
 
Example #15
Source File: ChainSplitTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testForking3() throws Exception {
    // Check that we can handle our own spends being rolled back by a fork.
    Block b1 = PARAMS.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(PARAMS);
    Transaction spend = wallet.createSend(dest, valueOf(10, 0));
    wallet.commitTx(spend);
    // Waiting for confirmation ... make it eligible for selection.
    assertEquals(Coin.ZERO, wallet.getBalance());
    spend.getConfidence().markBroadcastBy(new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
    spend.getConfidence().markBroadcastBy(new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[]{5,6,7,8})));
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
    assertEquals(valueOf(40, 0), wallet.getBalance());
    Block b2 = b1.createNextBlock(someOtherGuy);
    b2.addTransaction(spend);
    b2.solve();
    chain.add(roundtrip(b2));
    // We have 40 coins in change.
    assertEquals(ConfidenceType.BUILDING, spend.getConfidence().getConfidenceType());
    // genesis -> b1 (receive coins) -> b2 (spend coins)
    //                               \-> b3 -> b4
    Block b3 = b1.createNextBlock(someOtherGuy);
    Block b4 = b3.createNextBlock(someOtherGuy);
    chain.add(b3);
    chain.add(b4);
    // b4 causes a re-org that should make our spend go pending again.
    assertEquals(valueOf(40, 0), wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
 
Example #16
Source File: ChainSplitTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testForking4() throws Exception {
    // Check that we can handle external spends on an inactive chain becoming active. An external spend is where
    // we see a transaction that spends our own coins but we did not broadcast it ourselves. This happens when
    // keys are being shared between wallets.
    Block b1 = PARAMS.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(PARAMS);
    Transaction spend = wallet.createSend(dest, FIFTY_COINS);
    // We do NOT confirm the spend here. That means it's not considered to be pending because createSend is
    // stateless. For our purposes it is as if some other program with our keys created the tx.
    //
    // genesis -> b1 (receive 50) --> b2
    //                            \-> b3 (external spend) -> b4
    Block b2 = b1.createNextBlock(someOtherGuy);
    chain.add(b2);
    Block b3 = b1.createNextBlock(someOtherGuy);
    b3.addTransaction(spend);
    b3.solve();
    chain.add(roundtrip(b3));
    // The external spend is now pending.
    assertEquals(ZERO, wallet.getBalance());
    Transaction tx = wallet.getTransaction(spend.getHash());
    assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType());
    Block b4 = b3.createNextBlock(someOtherGuy);
    chain.add(b4);
    // The external spend is now active.
    assertEquals(ZERO, wallet.getBalance());
    assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
}
 
Example #17
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
@Test
public void doubleSpends() throws Exception {
    // Test the case where two semantically identical but bitwise different transactions double spend each other.
    // We call the second transaction a "mutant" of the first.
    //
    // This can (and has!) happened when a wallet is cloned between devices, and both devices decide to make the
    // same spend simultaneously - for example due a re-keying operation. It can also happen if there are malicious
    // nodes in the P2P network that are mutating transactions on the fly as occurred during Feb 2014.
    final Coin value = COIN;
    final Coin value2 = valueOf(2, 0);
    // Give us three coins and make sure we have some change.
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, value.add(value2));
    Transaction send1 = checkNotNull(wallet.createSend(OTHER_ADDRESS, value2));
    Transaction send2 = checkNotNull(wallet.createSend(OTHER_ADDRESS, value2));
    byte[] buf = send1.bitcoinSerialize();
    buf[43] = 0;  // Break the signature: bitcoinj won't check in SPV mode and this is easier than other mutations.
    send1 = PARAMS.getDefaultSerializer().makeTransaction(buf);
    wallet.commitTx(send2);
    wallet.allowSpendingUnconfirmedTransactions();
    assertEquals(value, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    // Now spend the change. This transaction should die permanently when the mutant appears in the chain.
    Transaction send3 = checkNotNull(wallet.createSend(OTHER_ADDRESS, value));
    wallet.commitTx(send3);
    assertEquals(ZERO, wallet.getBalance());
    final LinkedList<TransactionConfidence> dead = new LinkedList<>();
    final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
        @Override
        public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
            final TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
            if (reason == ChangeReason.TYPE && type == TransactionConfidence.ConfidenceType.DEAD)
                dead.add(confidence);
        }
    };
    send2.getConfidence().addEventListener(Threading.SAME_THREAD, listener);
    send3.getConfidence().addEventListener(Threading.SAME_THREAD, listener);
    // Double spend!
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, send1);
    // Back to having one coin.
    assertEquals(value, wallet.getBalance());
    assertEquals(send2.getHash(), dead.poll().getTransactionHash());
    assertEquals(send3.getHash(), dead.poll().getTransactionHash());
}
 
Example #18
Source File: WalletTest.java    From green_android with GNU General Public License v3.0 4 votes vote down vote up
private void assertSpent(Transaction tx) {
    assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
    assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, tx.getHash()));
}
 
Example #19
Source File: Transaction.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
/** Check if the transaction has a known confidence */
public boolean hasConfidence() {
    return getConfidence().getConfidenceType() != TransactionConfidence.ConfidenceType.UNKNOWN;
}
 
Example #20
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private void assertInConflict(Transaction tx) {
    assertEquals(ConfidenceType.IN_CONFLICT, tx.getConfidence().getConfidenceType());
    assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, tx.getHash()));
}
 
Example #21
Source File: WalletProtobufSerializer.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private void readConfidence(final NetworkParameters params, final Transaction tx,
                            final Protos.TransactionConfidence confidenceProto,
                            final TransactionConfidence confidence) throws UnreadableWalletException {
    // We are lenient here because tx confidence is not an essential part of the wallet.
    // If the tx has an unknown type of confidence, ignore.
    if (!confidenceProto.hasType()) {
        log.warn("Unknown confidence type for tx {}", tx.getHashAsString());
        return;
    }
    ConfidenceType confidenceType;
    switch (confidenceProto.getType()) {
        case BUILDING: confidenceType = ConfidenceType.BUILDING; break;
        case DEAD: confidenceType = ConfidenceType.DEAD; break;
        // These two are equivalent (must be able to read old wallets).
        case NOT_IN_BEST_CHAIN: confidenceType = ConfidenceType.PENDING; break;
        case PENDING: confidenceType = ConfidenceType.PENDING; break;
        case IN_CONFLICT: confidenceType = ConfidenceType.IN_CONFLICT; break;
        case UNKNOWN:
            // Fall through.
        default:
            confidenceType = ConfidenceType.UNKNOWN; break;
    }
    confidence.setConfidenceType(confidenceType);
    if (confidenceProto.hasAppearedAtHeight()) {
        if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
            log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
    }
    if (confidenceProto.hasDepth()) {
        if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
            log.warn("Have depth but not BUILDING for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setDepthInBlocks(confidenceProto.getDepth());
    }
    if (confidenceProto.hasOverridingTransaction()) {
        if (confidence.getConfidenceType() != ConfidenceType.DEAD) {
            log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", tx.getHashAsString());
            return;
        }
        Transaction overridingTransaction =
            txMap.get(confidenceProto.getOverridingTransaction());
        if (overridingTransaction == null) {
            log.warn("Have overridingTransaction that is not in wallet for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setOverridingTransaction(overridingTransaction);
    }
    for (Protos.PeerAddress proto : confidenceProto.getBroadcastByList()) {
        InetAddress ip;
        try {
            ip = InetAddress.getByAddress(proto.getIpAddress().toByteArray());
        } catch (UnknownHostException e) {
            throw new UnreadableWalletException("Peer IP address does not have the right length", e);
        }
        int port = proto.getPort();
        int protocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.CURRENT);
        BigInteger services = BigInteger.valueOf(proto.getServices());
        PeerAddress address = new PeerAddress(params, ip, port, protocolVersion, services);
        confidence.markBroadcastBy(address);
    }
    if (confidenceProto.hasLastBroadcastedAt())
        confidence.setLastBroadcastedAt(new Date(confidenceProto.getLastBroadcastedAt()));
    switch (confidenceProto.getSource()) {
        case SOURCE_SELF: confidence.setSource(TransactionConfidence.Source.SELF); break;
        case SOURCE_NETWORK: confidence.setSource(TransactionConfidence.Source.NETWORK); break;
        case SOURCE_UNKNOWN:
            // Fall through.
        default: confidence.setSource(TransactionConfidence.Source.UNKNOWN); break;
    }
}
 
Example #22
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private void assertPending(Transaction tx) {
    assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType());
    assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, tx.getHash()));
}
 
Example #23
Source File: WalletProtobufSerializer.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private static void writeConfidence(Protos.Transaction.Builder txBuilder,
                                    TransactionConfidence confidence,
                                    Protos.TransactionConfidence.Builder confidenceBuilder) {
    synchronized (confidence) {
        confidenceBuilder.setType(Protos.TransactionConfidence.Type.valueOf(confidence.getConfidenceType().getValue()));
        if (confidence.getConfidenceType() == ConfidenceType.BUILDING) {
            confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
            confidenceBuilder.setDepth(confidence.getDepthInBlocks());
        }
        if (confidence.getConfidenceType() == ConfidenceType.DEAD) {
            // Copy in the overriding transaction, if available.
            // (A dead coinbase transaction has no overriding transaction).
            if (confidence.getOverridingTransaction() != null) {
                Sha256Hash overridingHash = confidence.getOverridingTransaction().getHash();
                confidenceBuilder.setOverridingTransaction(hashToByteString(overridingHash));
            }
        }
        TransactionConfidence.Source source = confidence.getSource();
        switch (source) {
            case SELF: confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_SELF); break;
            case NETWORK: confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_NETWORK); break;
            case UNKNOWN:
                // Fall through.
            default:
                confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_UNKNOWN); break;
        }
    }

    for (PeerAddress address : confidence.getBroadcastBy()) {
        Protos.PeerAddress proto = Protos.PeerAddress.newBuilder()
                .setIpAddress(ByteString.copyFrom(address.getAddr().getAddress()))
                .setPort(address.getPort())
                .setServices(address.getServices().longValue())
                .build();
        confidenceBuilder.addBroadcastBy(proto);
    }
    Date lastBroadcastedAt = confidence.getLastBroadcastedAt();
    if (lastBroadcastedAt != null)
        confidenceBuilder.setLastBroadcastedAt(lastBroadcastedAt.getTime());
    txBuilder.setConfidence(confidenceBuilder);
}
 
Example #24
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private void assertSpent(Transaction tx) {
    assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
    assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, tx.getHash()));
}
 
Example #25
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private void assertUnspent(Transaction tx) {
    assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
    assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.UNSPENT, tx.getHash()));
}
 
Example #26
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private void assertDead(Transaction tx) {
    assertEquals(ConfidenceType.DEAD, tx.getConfidence().getConfidenceType());
    assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.DEAD, tx.getHash()));
}
 
Example #27
Source File: WalletProtobufSerializer.java    From green_android with GNU General Public License v3.0 4 votes vote down vote up
private static void writeConfidence(Protos.Transaction.Builder txBuilder,
                                    TransactionConfidence confidence,
                                    Protos.TransactionConfidence.Builder confidenceBuilder) {
    synchronized (confidence) {
        confidenceBuilder.setType(Protos.TransactionConfidence.Type.valueOf(confidence.getConfidenceType().getValue()));
        if (confidence.getConfidenceType() == ConfidenceType.BUILDING) {
            confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
            confidenceBuilder.setDepth(confidence.getDepthInBlocks());
        }
        if (confidence.getConfidenceType() == ConfidenceType.DEAD) {
            // Copy in the overriding transaction, if available.
            // (A dead coinbase transaction has no overriding transaction).
            if (confidence.getOverridingTransaction() != null) {
                Sha256Hash overridingHash = confidence.getOverridingTransaction().getHash();
                confidenceBuilder.setOverridingTransaction(hashToByteString(overridingHash));
            }
        }
        TransactionConfidence.Source source = confidence.getSource();
        switch (source) {
            case SELF: confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_SELF); break;
            case NETWORK: confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_NETWORK); break;
            case UNKNOWN:
                // Fall through.
            default:
                confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_UNKNOWN); break;
        }
    }

    for (PeerAddress address : confidence.getBroadcastBy()) {
        Protos.PeerAddress proto = Protos.PeerAddress.newBuilder()
                .setIpAddress(ByteString.copyFrom(address.getAddr().getAddress()))
                .setPort(address.getPort())
                .setServices(address.getServices().longValue())
                .build();
        confidenceBuilder.addBroadcastBy(proto);
    }
    Date lastBroadcastedAt = confidence.getLastBroadcastedAt();
    if (lastBroadcastedAt != null)
        confidenceBuilder.setLastBroadcastedAt(lastBroadcastedAt.getTime());
    txBuilder.setConfidence(confidenceBuilder);
}
 
Example #28
Source File: WalletProtobufSerializer.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
private void readConfidence(final NetworkParameters params, final Transaction tx,
                            final Protos.TransactionConfidence confidenceProto,
                            final TransactionConfidence confidence) throws UnreadableWalletException {
    // We are lenient here because tx confidence is not an essential part of the wallet.
    // If the tx has an unknown type of confidence, ignore.
    if (!confidenceProto.hasType()) {
        log.warn("Unknown confidence type for tx {}", tx.getHashAsString());
        return;
    }
    ConfidenceType confidenceType;
    switch (confidenceProto.getType()) {
        case BUILDING:
            confidenceType = ConfidenceType.BUILDING;
            break;
        case DEAD:
            confidenceType = ConfidenceType.DEAD;
            break;
        // These two are equivalent (must be able to read old wallets).
        case NOT_IN_BEST_CHAIN:
            confidenceType = ConfidenceType.PENDING;
            break;
        case PENDING:
            confidenceType = ConfidenceType.PENDING;
            break;
        case IN_CONFLICT:
            confidenceType = ConfidenceType.IN_CONFLICT;
            break;
        case UNKNOWN:
            // Fall through.
        default:
            confidenceType = ConfidenceType.UNKNOWN;
            break;
    }
    confidence.setConfidenceType(confidenceType);
    if (confidenceProto.hasAppearedAtHeight()) {
        if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
            log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
    }
    if (confidenceProto.hasDepth()) {
        if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
            log.warn("Have depth but not BUILDING for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setDepthInBlocks(confidenceProto.getDepth());
    }
    if (confidenceProto.hasOverridingTransaction()) {
        if (confidence.getConfidenceType() != ConfidenceType.DEAD) {
            log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", tx.getHashAsString());
            return;
        }
        Transaction overridingTransaction =
                txMap.get(confidenceProto.getOverridingTransaction());
        if (overridingTransaction == null) {
            log.warn("Have overridingTransaction that is not in wallet for tx {}", tx.getHashAsString());
            return;
        }
        confidence.setOverridingTransaction(overridingTransaction);
    }
    for (Protos.PeerAddress proto : confidenceProto.getBroadcastByList()) {
        InetAddress ip;
        try {
            ip = InetAddress.getByAddress(proto.getIpAddress().toByteArray());
        } catch (UnknownHostException e) {
            throw new UnreadableWalletException("Peer IP address does not have the right length", e);
        }
        int port = proto.getPort();
        int protocolVersion = params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.CURRENT);
        BigInteger services = BigInteger.valueOf(proto.getServices());
        PeerAddress address = new PeerAddress(params, ip, port, protocolVersion, services);
        confidence.markBroadcastBy(address);
    }
    if (confidenceProto.hasLastBroadcastedAt())
        confidence.setLastBroadcastedAt(new Date(confidenceProto.getLastBroadcastedAt()));
    switch (confidenceProto.getSource()) {
        case SOURCE_SELF:
            confidence.setSource(TransactionConfidence.Source.SELF);
            break;
        case SOURCE_NETWORK:
            confidence.setSource(TransactionConfidence.Source.NETWORK);
            break;
        case SOURCE_UNKNOWN:
            // Fall through.
        default:
            confidence.setSource(TransactionConfidence.Source.UNKNOWN);
            break;
    }
}
 
Example #29
Source File: Transaction.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Check if the transaction has a known confidence
 */
public boolean hasConfidence() {
    return getConfidence().getConfidenceType() != TransactionConfidence.ConfidenceType.UNKNOWN;
}
 
Example #30
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
@Test
public void doubleSpends() throws Exception {
    // Test the case where two semantically identical but bitwise different transactions double spend each other.
    // We call the second transaction a "mutant" of the first.
    //
    // This can (and has!) happened when a wallet is cloned between devices, and both devices decide to make the
    // same spend simultaneously - for example due a re-keying operation. It can also happen if there are malicious
    // nodes in the P2P network that are mutating transactions on the fly as occurred during Feb 2014.
    final Coin value = COIN;
    final Coin value2 = valueOf(2, 0);
    // Give us three coins and make sure we have some change.
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, value.add(value2));
    Transaction send1 = checkNotNull(wallet.createSend(OTHER_ADDRESS, value2));
    Transaction send2 = checkNotNull(wallet.createSend(OTHER_ADDRESS, value2));
    byte[] buf = send1.bitcoinSerialize();
    buf[43] = 0;  // Break the signature: bitcoinj won't check in SPV mode and this is easier than other mutations.
    send1 = UNITTEST.getDefaultSerializer().makeTransaction(buf);
    wallet.commitTx(send2);
    wallet.allowSpendingUnconfirmedTransactions();
    assertEquals(value, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    // Now spend the change. This transaction should die permanently when the mutant appears in the chain.
    Transaction send3 = checkNotNull(wallet.createSend(OTHER_ADDRESS, value));
    wallet.commitTx(send3);
    assertEquals(ZERO, wallet.getBalance());
    final LinkedList<TransactionConfidence> dead = new LinkedList<>();
    final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
        @Override
        public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
            final TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
            if (reason == ChangeReason.TYPE && type == TransactionConfidence.ConfidenceType.DEAD)
                dead.add(confidence);
        }
    };
    send2.getConfidence().addEventListener(Threading.SAME_THREAD, listener);
    send3.getConfidence().addEventListener(Threading.SAME_THREAD, listener);
    // Double spend!
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, send1);
    // Back to having one coin.
    assertEquals(value, wallet.getBalance());
    assertEquals(send2.getHash(), dead.poll().getTransactionHash());
    assertEquals(send3.getHash(), dead.poll().getTransactionHash());
}