Java 类org.bitcoinj.core.TransactionConfidence.ConfidenceType 实例源码

项目:okwallet    文件:BlockchainServiceImpl.java   
@Override
public void onCoinsReceived(final Wallet wallet, final Transaction tx, final Coin prevBalance,
        final Coin newBalance) {
    transactionsReceived.incrementAndGet();

    final int bestChainHeight = blockChain.getBestChainHeight();

    final Address address = WalletUtils.getWalletAddressOfReceived(tx, wallet);
    final Coin amount = tx.getValue(wallet);
    final ConfidenceType confidenceType = tx.getConfidence().getConfidenceType();
    final Sha256Hash hash = tx.getHash();

    handler.post(new Runnable() {
        @Override
        public void run() {
            final boolean isReceived = amount.signum() > 0;
            final boolean replaying = bestChainHeight < config.getBestChainHeightEver();
            final boolean isReplayedTx = confidenceType == ConfidenceType.BUILDING && replaying;

            if (isReceived && !isReplayedTx)
                notifyCoinsReceived(address, amount, hash);
        }
    });
}
项目:java-stratum    文件:ElectrumMultiWallet.java   
@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();
}
项目:java-stratum    文件:ElectrumMultiWalletTest.java   
@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();
}
项目:ombuds-android    文件:BlockchainServiceImpl.java   
@Override
public void onCoinsReceived(final Wallet wallet, final Transaction tx, final Coin prevBalance, final Coin newBalance)
{
    transactionsReceived.incrementAndGet();

    final int bestChainHeight = blockChain.getBestChainHeight();

    final Address address = WalletUtils.getWalletAddressOfReceived(tx, wallet);
    final Coin amount = tx.getValue(wallet);
    final ConfidenceType confidenceType = tx.getConfidence().getConfidenceType();

    handler.post(new Runnable()
    {
        @Override
        public void run()
        {
            final boolean isReceived = amount.signum() > 0;
            final boolean replaying = bestChainHeight < config.getBestChainHeightEver();
            final boolean isReplayedTx = confidenceType == ConfidenceType.BUILDING && replaying;

            if (isReceived && !isReplayedTx)
                notifyCoinsReceived(address, amount);
        }
    });
}
项目:okwallet    文件:Transaction.java   
/**
 * 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();
}
项目:cryptwallet    文件:Transaction.java   
/**
 * 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();
}
项目:cryptwallet    文件:WalletTest.java   
@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());
}
项目:cryptwallet    文件:ChainSplitTest.java   
@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());
}
项目:cryptwallet    文件:ChainSplitTest.java   
@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());
}
项目:lbry-android    文件:WalletPocketProtobufSerializer.java   
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() == TransactionConfidence.ConfidenceType.BUILDING) {
                confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
                confidenceBuilder.setDepth(confidence.getDepthInBlocks());
            }
            // TODO deprecate overriding transactions
//            if (confidence.getConfidenceType() == TransactionConfidence.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 (ListIterator<PeerAddress> it = confidence.getBroadcastBy(); it.hasNext();) {
            PeerAddress address = it.next();
            Protos.PeerAddress proto = Protos.PeerAddress.newBuilder()
                    .setIpAddress(ByteString.copyFrom(address.getAddr().getAddress()))
                    .setPort(address.getPort())
                    .setServices(address.getServices().longValue())
                    .build();
            confidenceBuilder.addBroadcastBy(proto);
        }
        txBuilder.setConfidence(confidenceBuilder);
    }
项目:java-stratum    文件:ElectrumMultiWallet.java   
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());
    }
}
项目:java-stratum    文件:ElectrumMultiWallet.java   
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);
}
项目:namecoinj    文件:Transaction.java   
/**
 * 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();
}
项目:namecoinj    文件:Wallet.java   
/**
 * <p>Called by the {@link BlockChain} when a new block on the best chain is seen, AFTER relevant wallet
 * transactions are extracted and sent to us UNLESS the new block caused a re-org, in which case this will
 * not be called (the {@link Wallet#reorganize(StoredBlock, java.util.List, java.util.List)} method will
 * call this one in that case).</p>
 * <p/>
 * <p>Used to update confidence data in each transaction and last seen block hash. Triggers auto saving.
 * Invokes the onWalletChanged event listener if there were any affected transactions.</p>
 */
@Override
public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
    // Check to see if this block has been seen before.
    Sha256Hash newBlockHash = block.getHeader().getHash();
    if (newBlockHash.equals(getLastBlockSeenHash()))
        return;
    lock.lock();
    try {
        // Store the new block hash.
        setLastBlockSeenHash(newBlockHash);
        setLastBlockSeenHeight(block.getHeight());
        setLastBlockSeenTimeSecs(block.getHeader().getTimeSeconds());
        // TODO: Clarify the code below.
        // Notify all the BUILDING transactions of the new block.
        // This is so that they can update their depth.
        Set<Transaction> transactions = getTransactions(true);
        for (Transaction tx : transactions) {
            if (ignoreNextNewBlock.contains(tx.getHash())) {
                // tx was already processed in receive() due to it appearing in this block, so we don't want to
                // increment the tx confidence depth twice, it'd result in miscounting.
                ignoreNextNewBlock.remove(tx.getHash());
            } else if (tx.getConfidence().getConfidenceType() == ConfidenceType.BUILDING) {
                tx.getConfidence().incrementDepthInBlocks();
                confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
            }
        }

        informConfidenceListenersIfNotReorganizing();
        maybeQueueOnWalletChanged();
        // Coalesce writes to avoid throttling on disk access when catching up with the chain.
        saveLater();
    } finally {
        lock.unlock();
    }
}
项目:namecoinj    文件:Wallet.java   
/**
 * Subtract the supplied depth from the given transactions.
 */
private void subtractDepth(int depthToSubtract, Collection<Transaction> transactions) {
    for (Transaction tx : transactions) {
        if (tx.getConfidence().getConfidenceType() == ConfidenceType.BUILDING) {
            tx.getConfidence().setDepthInBlocks(tx.getConfidence().getDepthInBlocks() - depthToSubtract);
            confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
        }
    }
}
项目:namecoinj    文件:Wallet.java   
/**
 * <p>Specifies that the given {@link TransactionBroadcaster}, typically a {@link PeerGroup}, should be used for
 * sending transactions to the Bitcoin network by default. Some sendCoins methods let you specify a broadcaster
 * explicitly, in that case, they don't use this broadcaster. If null is specified then the wallet won't attempt
 * to broadcast transactions itself.</p>
 *
 * <p>You don't normally need to call this. A {@link PeerGroup} will automatically set itself as the wallets
 * broadcaster when you use {@link PeerGroup#addWallet(Wallet)}. A wallet can use the broadcaster when you ask
 * it to send money, but in future also at other times to implement various features that may require asynchronous
 * re-organisation of the wallet contents on the block chain. For instance, in future the wallet may choose to
 * optimise itself to reduce fees or improve privacy.</p>
 */
public void setTransactionBroadcaster(@Nullable org.bitcoinj.core.TransactionBroadcaster broadcaster) {
    Transaction[] toBroadcast = {};
    lock.lock();
    try {
        if (vTransactionBroadcaster == broadcaster)
            return;
        vTransactionBroadcaster = broadcaster;
        if (broadcaster == null)
            return;
        toBroadcast = pending.values().toArray(toBroadcast);
    } finally {
        lock.unlock();
    }
    // Now use it to upload any pending transactions we have that are marked as not being seen by any peers yet.
    // Don't hold the wallet lock whilst doing this, so if the broadcaster accesses the wallet at some point there
    // is no inversion.
    for (Transaction tx : toBroadcast) {
        checkState(tx.getConfidence().getConfidenceType() == ConfidenceType.PENDING);
        // Re-broadcast even if it's marked as already seen for two reasons
        // 1) Old wallets may have transactions marked as broadcast by 1 peer when in reality the network
        //    never saw it, due to bugs.
        // 2) It can't really hurt.
        log.info("New broadcaster so uploading waiting tx {}", tx.getHash());
        broadcaster.broadcastTransaction(tx);
    }
}
项目:namecoinj    文件:WalletProtobufSerializer.java   
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 (ListIterator<PeerAddress> it = confidence.getBroadcastBy(); it.hasNext();) {
        PeerAddress address = it.next();
        Protos.PeerAddress proto = Protos.PeerAddress.newBuilder()
                .setIpAddress(ByteString.copyFrom(address.getAddr().getAddress()))
                .setPort(address.getPort())
                .setServices(address.getServices().longValue())
                .build();
        confidenceBuilder.addBroadcastBy(proto);
    }
    txBuilder.setConfidence(confidenceBuilder);
}
项目:namecoinj    文件:ChainSplitTest.java   
@Test
public void testForking3() throws Exception {
    // Check that we can handle our own spends being rolled back by a fork.
    Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(unitTestParams);
    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(InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
    spend.getConfidence().markBroadcastBy(new PeerAddress(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());
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
项目:namecoinj    文件:ChainSplitTest.java   
@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 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(unitTestParams);
    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());
}
项目:CoinJoin    文件:Transaction.java   
/**
 * 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();
}
项目:CoinJoin    文件:Wallet.java   
/**
 * <p>Called by the {@link BlockChain} when a new block on the best chain is seen, AFTER relevant wallet
 * transactions are extracted and sent to us UNLESS the new block caused a re-org, in which case this will
 * not be called (the {@link Wallet#reorganize(StoredBlock, java.util.List, java.util.List)} method will
 * call this one in that case).</p>
 * <p/>
 * <p>Used to update confidence data in each transaction and last seen block hash. Triggers auto saving.
 * Invokes the onWalletChanged event listener if there were any affected transactions.</p>
 */
@Override
public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
    // Check to see if this block has been seen before.
    Sha256Hash newBlockHash = block.getHeader().getHash();
    if (newBlockHash.equals(getLastBlockSeenHash()))
        return;
    lock.lock();
    try {
        // Store the new block hash.
        setLastBlockSeenHash(newBlockHash);
        setLastBlockSeenHeight(block.getHeight());
        setLastBlockSeenTimeSecs(block.getHeader().getTimeSeconds());
        // TODO: Clarify the code below.
        // Notify all the BUILDING transactions of the new block.
        // This is so that they can update their depth.
        Set<Transaction> transactions = getTransactions(true);
        for (Transaction tx : transactions) {
            if (ignoreNextNewBlock.contains(tx.getHash())) {
                // tx was already processed in receive() due to it appearing in this block, so we don't want to
                // increment the tx confidence depth twice, it'd result in miscounting.
                ignoreNextNewBlock.remove(tx.getHash());
            } else if (tx.getConfidence().getConfidenceType() == ConfidenceType.BUILDING) {
                tx.getConfidence().incrementDepthInBlocks();
                confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
            }
        }

        informConfidenceListenersIfNotReorganizing();
        maybeQueueOnWalletChanged();
        // Coalesce writes to avoid throttling on disk access when catching up with the chain.
        saveLater();
    } finally {
        lock.unlock();
    }
}
项目:CoinJoin    文件:Wallet.java   
/**
 * Subtract the supplied depth from the given transactions.
 */
private void subtractDepth(int depthToSubtract, Collection<Transaction> transactions) {
    for (Transaction tx : transactions) {
        if (tx.getConfidence().getConfidenceType() == ConfidenceType.BUILDING) {
            tx.getConfidence().setDepthInBlocks(tx.getConfidence().getDepthInBlocks() - depthToSubtract);
            confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
        }
    }
}
项目:CoinJoin    文件:Wallet.java   
/**
 * <p>Specifies that the given {@link TransactionBroadcaster}, typically a {@link PeerGroup}, should be used for
 * sending transactions to the Bitcoin network by default. Some sendCoins methods let you specify a broadcaster
 * explicitly, in that case, they don't use this broadcaster. If null is specified then the wallet won't attempt
 * to broadcast transactions itself.</p>
 *
 * <p>You don't normally need to call this. A {@link PeerGroup} will automatically set itself as the wallets
 * broadcaster when you use {@link PeerGroup#addWallet(Wallet)}. A wallet can use the broadcaster when you ask
 * it to send money, but in future also at other times to implement various features that may require asynchronous
 * re-organisation of the wallet contents on the block chain. For instance, in future the wallet may choose to
 * optimise itself to reduce fees or improve privacy.</p>
 */
public void setTransactionBroadcaster(@Nullable org.bitcoinj.core.TransactionBroadcaster broadcaster) {
    Transaction[] toBroadcast = {};
    lock.lock();
    try {
        if (vTransactionBroadcaster == broadcaster)
            return;
        vTransactionBroadcaster = broadcaster;
        if (broadcaster == null)
            return;
        toBroadcast = pending.values().toArray(toBroadcast);
    } finally {
        lock.unlock();
    }
    // Now use it to upload any pending transactions we have that are marked as not being seen by any peers yet.
    // Don't hold the wallet lock whilst doing this, so if the broadcaster accesses the wallet at some point there
    // is no inversion.
    for (Transaction tx : toBroadcast) {
        checkState(tx.getConfidence().getConfidenceType() == ConfidenceType.PENDING);
        // Re-broadcast even if it's marked as already seen for two reasons
        // 1) Old wallets may have transactions marked as broadcast by 1 peer when in reality the network
        //    never saw it, due to bugs.
        // 2) It can't really hurt.
        log.info("New broadcaster so uploading waiting tx {}", tx.getHash());
        broadcaster.broadcastTransaction(tx);
    }
}
项目:CoinJoin    文件:WalletProtobufSerializer.java   
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 (ListIterator<PeerAddress> it = confidence.getBroadcastBy(); it.hasNext();) {
        PeerAddress address = it.next();
        Protos.PeerAddress proto = Protos.PeerAddress.newBuilder()
                .setIpAddress(ByteString.copyFrom(address.getAddr().getAddress()))
                .setPort(address.getPort())
                .setServices(address.getServices().longValue())
                .build();
        confidenceBuilder.addBroadcastBy(proto);
    }
    txBuilder.setConfidence(confidenceBuilder);
}
项目:CoinJoin    文件:ChainSplitTest.java   
@Test
public void testForking3() throws Exception {
    // Check that we can handle our own spends being rolled back by a fork.
    Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(unitTestParams);
    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(InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
    spend.getConfidence().markBroadcastBy(new PeerAddress(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());
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
项目:CoinJoin    文件:ChainSplitTest.java   
@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 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(unitTestParams);
    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());
}
项目:digibytej-alice    文件:Transaction.java   
/**
 * 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();
}
项目:digibytej-alice    文件:Wallet.java   
/**
 * <p>Called by the {@link BlockChain} when a new block on the best chain is seen, AFTER relevant wallet
 * transactions are extracted and sent to us UNLESS the new block caused a re-org, in which case this will
 * not be called (the {@link Wallet#reorganize(StoredBlock, java.util.List, java.util.List)} method will
 * call this one in that case).</p>
 * <p/>
 * <p>Used to update confidence data in each transaction and last seen block hash. Triggers auto saving.
 * Invokes the onWalletChanged event listener if there were any affected transactions.</p>
 */
@Override
public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
    // Check to see if this block has been seen before.
    Sha256Hash newBlockHash = block.getHeader().getHash();
    if (newBlockHash.equals(getLastBlockSeenHash()))
        return;
    lock.lock();
    try {
        // Store the new block hash.
        setLastBlockSeenHash(newBlockHash);
        setLastBlockSeenHeight(block.getHeight());
        setLastBlockSeenTimeSecs(block.getHeader().getTimeSeconds());
        // TODO: Clarify the code below.
        // Notify all the BUILDING transactions of the new block.
        // This is so that they can update their depth.
        Set<Transaction> transactions = getTransactions(true);
        for (Transaction tx : transactions) {
            if (ignoreNextNewBlock.contains(tx.getHash())) {
                // tx was already processed in receive() due to it appearing in this block, so we don't want to
                // increment the tx confidence depth twice, it'd result in miscounting.
                ignoreNextNewBlock.remove(tx.getHash());
            } else if (tx.getConfidence().getConfidenceType() == ConfidenceType.BUILDING) {
                tx.getConfidence().incrementDepthInBlocks();
                confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
            }
        }

        informConfidenceListenersIfNotReorganizing();
        maybeQueueOnWalletChanged();
        // Coalesce writes to avoid throttling on disk access when catching up with the chain.
        saveLater();
    } finally {
        lock.unlock();
    }
}
项目:digibytej-alice    文件:Wallet.java   
/**
 * Subtract the supplied depth from the given transactions.
 */
private void subtractDepth(int depthToSubtract, Collection<Transaction> transactions) {
    for (Transaction tx : transactions) {
        if (tx.getConfidence().getConfidenceType() == ConfidenceType.BUILDING) {
            tx.getConfidence().setDepthInBlocks(tx.getConfidence().getDepthInBlocks() - depthToSubtract);
            confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
        }
    }
}
项目:digibytej-alice    文件:Wallet.java   
/**
 * <p>Specifies that the given {@link TransactionBroadcaster}, typically a {@link PeerGroup}, should be used for
 * sending transactions to the Bitcoin network by default. Some sendCoins methods let you specify a broadcaster
 * explicitly, in that case, they don't use this broadcaster. If null is specified then the wallet won't attempt
 * to broadcast transactions itself.</p>
 *
 * <p>You don't normally need to call this. A {@link PeerGroup} will automatically set itself as the wallets
 * broadcaster when you use {@link PeerGroup#addWallet(Wallet)}. A wallet can use the broadcaster when you ask
 * it to send money, but in future also at other times to implement various features that may require asynchronous
 * re-organisation of the wallet contents on the block chain. For instance, in future the wallet may choose to
 * optimise itself to reduce fees or improve privacy.</p>
 */
public void setTransactionBroadcaster(@Nullable org.bitcoinj.core.TransactionBroadcaster broadcaster) {
    Transaction[] toBroadcast = {};
    lock.lock();
    try {
        if (vTransactionBroadcaster == broadcaster)
            return;
        vTransactionBroadcaster = broadcaster;
        if (broadcaster == null)
            return;
        toBroadcast = pending.values().toArray(toBroadcast);
    } finally {
        lock.unlock();
    }
    // Now use it to upload any pending transactions we have that are marked as not being seen by any peers yet.
    // Don't hold the wallet lock whilst doing this, so if the broadcaster accesses the wallet at some point there
    // is no inversion.
    for (Transaction tx : toBroadcast) {
        checkState(tx.getConfidence().getConfidenceType() == ConfidenceType.PENDING);
        // Re-broadcast even if it's marked as already seen for two reasons
        // 1) Old wallets may have transactions marked as broadcast by 1 peer when in reality the network
        //    never saw it, due to bugs.
        // 2) It can't really hurt.
        log.info("New broadcaster so uploading waiting tx {}", tx.getHash());
        broadcaster.broadcastTransaction(tx);
    }
}
项目:digibytej-alice    文件:WalletProtobufSerializer.java   
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);
    }
    txBuilder.setConfidence(confidenceBuilder);
}
项目:digibytej-alice    文件:ChainSplitTest.java   
@Test
public void testForking3() throws Exception {
    // Check that we can handle our own spends being rolled back by a fork.
    Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(unitTestParams);
    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(InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
    spend.getConfidence().markBroadcastBy(new PeerAddress(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());
    assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
项目:digibytej-alice    文件:ChainSplitTest.java   
@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 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
    chain.add(b1);
    assertEquals(FIFTY_COINS, wallet.getBalance());
    Address dest = new ECKey().toAddress(unitTestParams);
    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());
}
项目:Wallet    文件:WalletOperation.java   
public void sendNotificationToAuthenticatorWhenCoinsReceived() {
    if(eventsAdapterForCoinsReceivedNotificaiton == null) {
        eventsAdapterForCoinsReceivedNotificaiton = new BAGeneralEventsAdapter() {
            @Override
            public void onBalanceChanged(Transaction tx, HowBalanceChanged howBalanceChanged, ConfidenceType confidence) {
                if(CoinsReceivedNotificationSender.checkIfNotificationShouldBeSentToPairedDeviceOnReceivedCoins(WalletOperation.this, tx))
                { // send
                    CoinsReceivedNotificationSender.send(WalletOperation.this, tx, howBalanceChanged);
                }
            }
        };
        Authenticator.addGeneralEventsListener(eventsAdapterForCoinsReceivedNotificaiton);
    }
}
项目:dashj    文件:Transaction.java   
/**
 * 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();
}
项目:dashj    文件:WalletTest.java   
@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());
}
项目:dashj    文件:ChainSplitTest.java   
@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());
}
项目:dashj    文件:ChainSplitTest.java   
@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());
}
项目:bitcoinj    文件:Transaction.java   
/**
 * 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();
}
项目:bitcoinj    文件:WalletTest.java   
@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());
}