Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clone transaction before adding to wallet #18

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions core/src/main/java/org/bitcoinj/core/TransactionConfidence.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ public enum ConfidenceType {
* If a transaction hasn't been broadcast yet, or there's no record of it, its confidence is UNKNOWN.
*/
UNKNOWN(0);

private int value;
ConfidenceType(int value) {
this.value = value;
}

public int getValue() {
return value;
}
Expand Down Expand Up @@ -262,7 +262,7 @@ public synchronized ConfidenceType getConfidenceType() {
}

/**
* Called by other objects in the system, like a {@link Wallet}, when new information about the confidence of a
* Called by other objects in the system, like a {@link Wallet}, when new information about the confidence of a
* transaction becomes available.
*/
public synchronized void setConfidenceType(ConfidenceType confidenceType) {
Expand Down Expand Up @@ -368,11 +368,8 @@ public synchronized String toString() {
*
* @return the new depth
*/
public synchronized int incrementDepthInBlocks(int height) {
if (getAppearedAtChainHeight() != -1)
this.depth = height - getAppearedAtChainHeight() + 1;

return this.depth;
public synchronized int incrementDepthInBlocks() {
return ++this.depth;
}

/**
Expand All @@ -381,7 +378,7 @@ public synchronized int incrementDepthInBlocks(int height) {
* considers a transaction impractical to reverse after 6 blocks, but as of EOY 2011 network
* security is high enough that often only one block is considered enough even for high value transactions. For low
* value transactions like songs, or other cheap items, no blocks at all may be necessary.</p>
*
*
* <p>If the transaction appears in the top block, the depth is one. If it's anything else (pending, dead, unknown)
* the depth is zero.</p>
*/
Expand Down
20 changes: 12 additions & 8 deletions core/src/main/java/org/bitcoinj/wallet/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ public DeterministicKeyChain getActiveKeyChain() {
public DeterministicKeyChain getActiveKeychain() {
return keyChainGroup.getActiveKeyChain();
}

/**
* <p>Adds given transaction signer to the list of signers. It will be added to the end of the signers list, so if
* this wallet already has some signers added, given signer will be executed after all of them.</p>
Expand Down Expand Up @@ -823,7 +823,7 @@ public DeterministicKey getWatchingKey() {
/**
* Returns whether this wallet consists entirely of watching keys (unencrypted keys with no private part). Mixed
* wallets are forbidden.
*
*
* @throws IllegalStateException
* if there are no keys, or if there is a mix between watching and non-watching keys.
*/
Expand Down Expand Up @@ -1683,6 +1683,11 @@ public void receivePending(Transaction tx, @Nullable List<Transaction> dependenc
// returned true, so we already know by this point that it sends coins to or from our wallet, or is a double
// spend against one of our other pending transactions.
lock.lock();

// Clone transaction to avoid multiple wallets pointing to the same transaction. This can happen when
// two wallets depend on the same transaction.
tx = tx.getParams().getDefaultSerializer().makeTransaction(tx.bitcoinSerialize());

try {
tx.verify();
// Ignore it if we already know about this transaction. Receiving a pending transaction never moves it
Expand Down Expand Up @@ -2118,8 +2123,7 @@ public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
try {
// Store the new block hash.
setLastBlockSeenHash(newBlockHash);
final int blockHeight = block.getHeight();
setLastBlockSeenHeight(blockHeight);
setLastBlockSeenHeight(block.getHeight());
setLastBlockSeenTimeSecs(block.getHeader().getTimeSeconds());
// Notify all the BUILDING transactions of the new block.
// This is so that they can update their depth.
Expand All @@ -2139,7 +2143,7 @@ public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
// included once again. We could have a separate was-in-chain-and-now-isn't confidence type
// but this way is backwards compatible with existing software, and the new state probably
// wouldn't mean anything different to just remembering peers anyway.
if (confidence.incrementDepthInBlocks(blockHeight) > context.getEventHorizon())
if (confidence.incrementDepthInBlocks() > context.getEventHorizon())
confidence.clearBroadcastBy();
confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
}
Expand Down Expand Up @@ -4665,10 +4669,10 @@ public BloomFilter getBloomFilter(double falsePositiveRate) {
* <p>Gets a bloom filter that contains all of the public keys from this wallet, and which will provide the given
* false-positive rate if it has size elements. Keep in mind that you will get 2 elements in the bloom filter for
* each key in the wallet, for the public key and the hash of the public key (address form).</p>
*
*
* <p>This is used to generate a BloomFilter which can be {@link BloomFilter#merge(BloomFilter)}d with another.
* It could also be used if you have a specific target for the filter's size.</p>
*
*
* <p>See the docs for {@link BloomFilter(int, double)} for a brief explanation of anonymity when using bloom
* filters.</p>
*/
Expand Down Expand Up @@ -4862,7 +4866,7 @@ public FeeCalculation calculateFee(SendRequest req, Coin value, List<Transaction
} else {
fees = fees.add(req.feePerKb); // First time around the loop.
}

if (needAtLeastReferenceFee && fees.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
fees = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;

Expand Down