mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-31 07:12:17 +00:00
Remove tx from TransactionConfidence
This commit is contained in:
parent
ec7cec67a7
commit
b9bca58f26
@ -1127,7 +1127,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
|
|
||||||
public synchronized TransactionConfidence getConfidence() {
|
public synchronized TransactionConfidence getConfidence() {
|
||||||
if (confidence == null) {
|
if (confidence == null) {
|
||||||
confidence = new TransactionConfidence(this);
|
confidence = new TransactionConfidence(getHash());
|
||||||
}
|
}
|
||||||
return confidence;
|
return confidence;
|
||||||
}
|
}
|
||||||
|
@ -143,9 +143,8 @@ public class TransactionBroadcast {
|
|||||||
|
|
||||||
private class ConfidenceChange implements TransactionConfidence.Listener {
|
private class ConfidenceChange implements TransactionConfidence.Listener {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
public void onConfidenceChanged(TransactionConfidence conf, ChangeReason reason) {
|
||||||
// The number of peers that announced this tx has gone up.
|
// The number of peers that announced this tx has gone up.
|
||||||
final TransactionConfidence conf = tx.getConfidence();
|
|
||||||
int numSeenPeers = conf.numBroadcastPeers();
|
int numSeenPeers = conf.numBroadcastPeers();
|
||||||
boolean mined = tx.getAppearsInHashes() != null;
|
boolean mined = tx.getAppearsInHashes() != null;
|
||||||
log.info("broadcastTransaction: {}: TX {} seen by {} peers{}", reason, pinnedTx.getHashAsString(),
|
log.info("broadcastTransaction: {}: TX {} seen by {} peers{}", reason, pinnedTx.getHashAsString(),
|
||||||
@ -165,8 +164,8 @@ public class TransactionBroadcast {
|
|||||||
// We're done! It's important that the PeerGroup lock is not held (by this thread) at this
|
// We're done! It's important that the PeerGroup lock is not held (by this thread) at this
|
||||||
// point to avoid triggering inversions when the Future completes.
|
// point to avoid triggering inversions when the Future completes.
|
||||||
log.info("broadcastTransaction: {} complete", pinnedTx.getHashAsString());
|
log.info("broadcastTransaction: {} complete", pinnedTx.getHashAsString());
|
||||||
tx.getConfidence().removeEventListener(this);
|
|
||||||
peerGroup.removeEventListener(rejectionListener);
|
peerGroup.removeEventListener(rejectionListener);
|
||||||
|
conf.removeEventListener(this);
|
||||||
future.set(pinnedTx); // RE-ENTRANCY POINT
|
future.set(pinnedTx); // RE-ENTRANCY POINT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ public class TransactionConfidence implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private CopyOnWriteArrayList<PeerAddress> broadcastBy;
|
private CopyOnWriteArrayList<PeerAddress> broadcastBy;
|
||||||
/** The Transaction that this confidence object is associated with. */
|
/** The Transaction that this confidence object is associated with. */
|
||||||
private final Transaction transaction;
|
private final Sha256Hash hash;
|
||||||
// Lazily created listeners array.
|
// Lazily created listeners array.
|
||||||
private transient CopyOnWriteArrayList<ListenerRegistration<Listener>> listeners;
|
private transient CopyOnWriteArrayList<ListenerRegistration<Listener>> listeners;
|
||||||
|
|
||||||
@ -135,11 +135,11 @@ public class TransactionConfidence implements Serializable {
|
|||||||
}
|
}
|
||||||
private Source source = Source.UNKNOWN;
|
private Source source = Source.UNKNOWN;
|
||||||
|
|
||||||
public TransactionConfidence(Transaction tx) {
|
public TransactionConfidence(Sha256Hash hash) {
|
||||||
// Assume a default number of peers for our set.
|
// Assume a default number of peers for our set.
|
||||||
broadcastBy = new CopyOnWriteArrayList<PeerAddress>();
|
broadcastBy = new CopyOnWriteArrayList<PeerAddress>();
|
||||||
listeners = new CopyOnWriteArrayList<ListenerRegistration<Listener>>();
|
listeners = new CopyOnWriteArrayList<ListenerRegistration<Listener>>();
|
||||||
transaction = tx;
|
this.hash = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +175,7 @@ public class TransactionConfidence implements Serializable {
|
|||||||
*/
|
*/
|
||||||
SEEN_PEERS,
|
SEEN_PEERS,
|
||||||
}
|
}
|
||||||
public void onConfidenceChanged(Transaction tx, ChangeReason reason);
|
public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -382,7 +382,7 @@ public class TransactionConfidence implements Serializable {
|
|||||||
|
|
||||||
/** Returns a copy of this object. Event listeners are not duplicated. */
|
/** Returns a copy of this object. Event listeners are not duplicated. */
|
||||||
public synchronized TransactionConfidence duplicate() {
|
public synchronized TransactionConfidence duplicate() {
|
||||||
TransactionConfidence c = new TransactionConfidence(transaction);
|
TransactionConfidence c = new TransactionConfidence(hash);
|
||||||
// There is no point in this sync block, it's just to help FindBugs.
|
// There is no point in this sync block, it's just to help FindBugs.
|
||||||
synchronized (c) {
|
synchronized (c) {
|
||||||
c.broadcastBy.addAll(broadcastBy);
|
c.broadcastBy.addAll(broadcastBy);
|
||||||
@ -404,7 +404,7 @@ public class TransactionConfidence implements Serializable {
|
|||||||
registration.executor.execute(new Runnable() {
|
registration.executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
registration.listener.onConfidenceChanged(transaction, reason);
|
registration.listener.onConfidenceChanged(TransactionConfidence.this, reason);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -435,23 +435,27 @@ public class TransactionConfidence implements Serializable {
|
|||||||
* depth to one will wait until it appears in a block on the best chain, and zero will wait until it has been seen
|
* depth to one will wait until it appears in a block on the best chain, and zero will wait until it has been seen
|
||||||
* on the network.
|
* on the network.
|
||||||
*/
|
*/
|
||||||
public synchronized ListenableFuture<Transaction> getDepthFuture(final int depth, Executor executor) {
|
public synchronized ListenableFuture<TransactionConfidence> getDepthFuture(final int depth, Executor executor) {
|
||||||
final SettableFuture<Transaction> result = SettableFuture.create();
|
final SettableFuture<TransactionConfidence> result = SettableFuture.create();
|
||||||
if (getDepthInBlocks() >= depth) {
|
if (getDepthInBlocks() >= depth) {
|
||||||
result.set(transaction);
|
result.set(this);
|
||||||
}
|
}
|
||||||
addEventListener(new Listener() {
|
addEventListener(new Listener() {
|
||||||
@Override public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
@Override public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
|
||||||
if (getDepthInBlocks() >= depth) {
|
if (getDepthInBlocks() >= depth) {
|
||||||
removeEventListener(this);
|
removeEventListener(this);
|
||||||
result.set(transaction);
|
result.set(confidence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, executor);
|
}, executor);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ListenableFuture<Transaction> getDepthFuture(final int depth) {
|
public synchronized ListenableFuture<TransactionConfidence> getDepthFuture(final int depth) {
|
||||||
return getDepthFuture(depth, Threading.USER_THREAD);
|
return getDepthFuture(depth, Threading.USER_THREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Sha256Hash getTransactionHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
ignoreNextNewBlock = new HashSet<Sha256Hash>();
|
ignoreNextNewBlock = new HashSet<Sha256Hash>();
|
||||||
txConfidenceListener = new TransactionConfidence.Listener() {
|
txConfidenceListener = new TransactionConfidence.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, TransactionConfidence.Listener.ChangeReason reason) {
|
public void onConfidenceChanged(TransactionConfidence confidence, TransactionConfidence.Listener.ChangeReason reason) {
|
||||||
// This will run on the user code thread so we shouldn't do anything too complicated here.
|
// This will run on the user code thread so we shouldn't do anything too complicated here.
|
||||||
// We only want to queue a wallet changed event and auto-save if the number of peers announcing
|
// We only want to queue a wallet changed event and auto-save if the number of peers announcing
|
||||||
// the transaction has changed, as that confidence change is made by the networking code which
|
// the transaction has changed, as that confidence change is made by the networking code which
|
||||||
@ -282,6 +282,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkBalanceFuturesLocked(null);
|
checkBalanceFuturesLocked(null);
|
||||||
|
Transaction tx = getTransaction(confidence.getTransactionHash());
|
||||||
queueOnTransactionConfidenceChanged(tx);
|
queueOnTransactionConfidenceChanged(tx);
|
||||||
maybeQueueOnWalletChanged();
|
maybeQueueOnWalletChanged();
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.bitcoinj.jni;
|
package org.bitcoinj.jni;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Sha256Hash;
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
import org.bitcoinj.core.TransactionConfidence;
|
||||||
|
|
||||||
@ -28,5 +29,5 @@ public class NativeTransactionConfidenceListener implements TransactionConfidenc
|
|||||||
public long ptr;
|
public long ptr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public native void onConfidenceChanged(Transaction tx, ChangeReason reason);
|
public native void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason);
|
||||||
}
|
}
|
||||||
|
@ -197,10 +197,10 @@ public class PaymentChannelClientState {
|
|||||||
// of this channel along with the refund tx from the wallet, because we're not going to need
|
// of this channel along with the refund tx from the wallet, because we're not going to need
|
||||||
// any of that any more.
|
// any of that any more.
|
||||||
final TransactionConfidence confidence = storedChannel.close.getConfidence();
|
final TransactionConfidence confidence = storedChannel.close.getConfidence();
|
||||||
ListenableFuture<Transaction> future = confidence.getDepthFuture(CONFIRMATIONS_FOR_DELETE, Threading.SAME_THREAD);
|
ListenableFuture<TransactionConfidence> future = confidence.getDepthFuture(CONFIRMATIONS_FOR_DELETE, Threading.SAME_THREAD);
|
||||||
Futures.addCallback(future, new FutureCallback<Transaction>() {
|
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Transaction result) {
|
public void onSuccess(TransactionConfidence result) {
|
||||||
deleteChannelFromWallet();
|
deleteChannelFromWallet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,8 +604,8 @@ public class ChainSplitTest {
|
|||||||
final AtomicBoolean fodderIsDead = new AtomicBoolean(false);
|
final AtomicBoolean fodderIsDead = new AtomicBoolean(false);
|
||||||
fodder.getConfidence().addEventListener(new TransactionConfidence.Listener() {
|
fodder.getConfidence().addEventListener(new TransactionConfidence.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
|
||||||
fodderIsDead.set(tx.getConfidence().getConfidenceType() == ConfidenceType.DEAD);
|
fodderIsDead.set(confidence.getConfidenceType() == ConfidenceType.DEAD);
|
||||||
}
|
}
|
||||||
}, Threading.SAME_THREAD);
|
}, Threading.SAME_THREAD);
|
||||||
|
|
||||||
|
@ -355,7 +355,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
// its trustworthyness assuming an untampered with internet connection.
|
// its trustworthyness assuming an untampered with internet connection.
|
||||||
peerGroup.start();
|
peerGroup.start();
|
||||||
|
|
||||||
final Transaction[] event = new Transaction[2];
|
final Transaction[] event = new Transaction[1];
|
||||||
|
final TransactionConfidence[] confEvent = new TransactionConfidence[1];
|
||||||
peerGroup.addEventListener(new AbstractPeerEventListener() {
|
peerGroup.addEventListener(new AbstractPeerEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onTransaction(Peer peer, Transaction t) {
|
public void onTransaction(Peer peer, Transaction t) {
|
||||||
@ -397,15 +398,15 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
|
|
||||||
tx.getConfidence().addEventListener(new TransactionConfidence.Listener() {
|
tx.getConfidence().addEventListener(new TransactionConfidence.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, TransactionConfidence.Listener.ChangeReason reason) {
|
public void onConfidenceChanged(TransactionConfidence confidence, TransactionConfidence.Listener.ChangeReason reason) {
|
||||||
event[1] = tx;
|
confEvent[0] = confidence;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// A straggler reports in.
|
// A straggler reports in.
|
||||||
inbound(p3, inv);
|
inbound(p3, inv);
|
||||||
pingAndWait(p3);
|
pingAndWait(p3);
|
||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
assertEquals(tx, event[1]);
|
assertEquals(tx.getHash(), confEvent[0].getTransactionHash());
|
||||||
assertEquals(3, tx.getConfidence().numBroadcastPeers());
|
assertEquals(3, tx.getConfidence().numBroadcastPeers());
|
||||||
assertTrue(tx.getConfidence().wasBroadcastBy(peerOf(p3).getAddress()));
|
assertTrue(tx.getConfidence().wasBroadcastBy(peerOf(p3).getAddress()));
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Send some pending coins to the wallet.
|
// Send some pending coins to the wallet.
|
||||||
Transaction t1 = sendMoneyToWallet(wallet, amount, toAddress, null);
|
Transaction t1 = sendMoneyToWallet(wallet, amount, toAddress, null);
|
||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
final ListenableFuture<Transaction> depthFuture = t1.getConfidence().getDepthFuture(1);
|
final ListenableFuture<TransactionConfidence> depthFuture = t1.getConfidence().getDepthFuture(1);
|
||||||
assertFalse(depthFuture.isDone());
|
assertFalse(depthFuture.isDone());
|
||||||
assertEquals(ZERO, wallet.getBalance());
|
assertEquals(ZERO, wallet.getBalance());
|
||||||
assertEquals(amount, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
assertEquals(amount, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||||
@ -764,13 +764,13 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Transaction send3 = checkNotNull(wallet.createSend(address, value));
|
Transaction send3 = checkNotNull(wallet.createSend(address, value));
|
||||||
wallet.commitTx(send3);
|
wallet.commitTx(send3);
|
||||||
assertEquals(ZERO, wallet.getBalance());
|
assertEquals(ZERO, wallet.getBalance());
|
||||||
final LinkedList<Transaction> dead = new LinkedList<Transaction>();
|
final LinkedList<TransactionConfidence> dead = new LinkedList<TransactionConfidence>();
|
||||||
final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
|
final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
|
public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
|
||||||
final TransactionConfidence.ConfidenceType type = tx.getConfidence().getConfidenceType();
|
final TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
|
||||||
if (reason == ChangeReason.TYPE && type == TransactionConfidence.ConfidenceType.DEAD)
|
if (reason == ChangeReason.TYPE && type == TransactionConfidence.ConfidenceType.DEAD)
|
||||||
dead.add(tx);
|
dead.add(confidence);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
send2.getConfidence().addEventListener(listener, Threading.SAME_THREAD);
|
send2.getConfidence().addEventListener(listener, Threading.SAME_THREAD);
|
||||||
@ -779,8 +779,8 @@ public class WalletTest extends TestWithWallet {
|
|||||||
sendMoneyToWallet(send1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(send1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// Back to having one coin.
|
// Back to having one coin.
|
||||||
assertEquals(value, wallet.getBalance());
|
assertEquals(value, wallet.getBalance());
|
||||||
assertEquals(send2, dead.poll());
|
assertEquals(send2.getHash(), dead.poll().getTransactionHash());
|
||||||
assertEquals(send3, dead.poll());
|
assertEquals(send3.getHash(), dead.poll().getTransactionHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -892,7 +892,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
final TransactionConfidence.Listener.ChangeReason[] reasons = new TransactionConfidence.Listener.ChangeReason[1];
|
final TransactionConfidence.Listener.ChangeReason[] reasons = new TransactionConfidence.Listener.ChangeReason[1];
|
||||||
notifiedTx[0].getConfidence().addEventListener(new TransactionConfidence.Listener() {
|
notifiedTx[0].getConfidence().addEventListener(new TransactionConfidence.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConfidenceChanged(Transaction tx, TransactionConfidence.Listener.ChangeReason reason) {
|
public void onConfidenceChanged(TransactionConfidence confidence, TransactionConfidence.Listener.ChangeReason reason) {
|
||||||
flags[1] = true;
|
flags[1] = true;
|
||||||
reasons[0] = reason;
|
reasons[0] = reason;
|
||||||
}
|
}
|
||||||
|
@ -93,11 +93,10 @@ public class ForwardingService {
|
|||||||
// to be double spent, no harm done. Wallet.allowSpendingUnconfirmedTransactions() would have to
|
// to be double spent, no harm done. Wallet.allowSpendingUnconfirmedTransactions() would have to
|
||||||
// be called in onSetupCompleted() above. But we don't do that here to demonstrate the more common
|
// be called in onSetupCompleted() above. But we don't do that here to demonstrate the more common
|
||||||
// case of waiting for a block.
|
// case of waiting for a block.
|
||||||
Futures.addCallback(tx.getConfidence().getDepthFuture(1), new FutureCallback<Transaction>() {
|
Futures.addCallback(tx.getConfidence().getDepthFuture(1), new FutureCallback<TransactionConfidence>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Transaction result) {
|
public void onSuccess(TransactionConfidence result) {
|
||||||
// "result" here is the same as "tx" above, but we use it anyway for clarity.
|
forwardCoins(tx);
|
||||||
forwardCoins(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user