3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Add a notion of an event horizon to the context. This is intended to unify the various places in the library where we want to throw data away after a tx is buried so deep it will probably never be re-orged, but which presently use different constants. The wallet will use the event horizon in future as well.

This commit is contained in:
Mike Hearn 2015-03-01 21:23:46 +01:00
parent aae60d8391
commit 1a70f05ca7
4 changed files with 30 additions and 5 deletions

View File

@ -16,10 +16,13 @@ public class Context {
private TxConfidenceTable confidenceTable; private TxConfidenceTable confidenceTable;
private NetworkParameters params; private NetworkParameters params;
private int eventHorizon = 100;
/** /**
* Creates a new context object. For now, this will be done for you by the framework. Eventually you will be * Creates a new context object. For now, this will be done for you by the framework. Eventually you will be
* expected to do this yourself in the same manner as fetching a NetworkParameters object (at the start of your app). * expected to do this yourself in the same manner as fetching a NetworkParameters object (at the start of your app).
*
* @param params The network parameters that will be associated with this context.
*/ */
public Context(NetworkParameters params) { public Context(NetworkParameters params) {
this.confidenceTable = new TxConfidenceTable(); this.confidenceTable = new TxConfidenceTable();
@ -29,6 +32,18 @@ public class Context {
slot.set(this); slot.set(this);
} }
/**
* Creates a new context object. For now, this will be done for you by the framework. Eventually you will be
* expected to do this yourself in the same manner as fetching a NetworkParameters object (at the start of your app).
*
* @param params The network parameters that will be associated with this context.
* @param eventHorizon Number of blocks after which the library will delete data and be unable to always process reorgs (see {@link #getEventHorizon()}.
*/
public Context(NetworkParameters params, int eventHorizon) {
this(params);
this.eventHorizon = eventHorizon;
}
private static volatile Context lastConstructed; private static volatile Context lastConstructed;
private static final ThreadLocal<Context> slot = new ThreadLocal<Context>(); private static final ThreadLocal<Context> slot = new ThreadLocal<Context>();
@ -106,4 +121,13 @@ public class Context {
public NetworkParameters getParams() { public NetworkParameters getParams() {
return params; return params;
} }
/**
* The event horizon is the number of blocks after which various bits of the library consider a transaction to be
* so confirmed that it's safe to delete data. Re-orgs larger than the event horizon will not be correctly
* processed, so the default value is high (100).
*/
public int getEventHorizon() {
return eventHorizon;
}
} }

View File

@ -1914,7 +1914,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
// included once again. We could have a separate was-in-chain-and-now-isn't confidence type // 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 // but this way is backwards compatible with existing software, and the new state probably
// wouldn't mean anything different to just remembering peers anyway. // wouldn't mean anything different to just remembering peers anyway.
if (confidence.incrementDepthInBlocks() > 100) if (confidence.incrementDepthInBlocks() > context.getEventHorizon())
confidence.clearBroadcastBy(); confidence.clearBroadcastBy();
confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH); confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.DEPTH);
} }

View File

@ -69,7 +69,6 @@ import static com.google.common.base.Preconditions.*;
*/ */
public class PaymentChannelClientState { public class PaymentChannelClientState {
private static final Logger log = LoggerFactory.getLogger(PaymentChannelClientState.class); private static final Logger log = LoggerFactory.getLogger(PaymentChannelClientState.class);
private static final int CONFIRMATIONS_FOR_DELETE = 3;
private final Wallet wallet; private final Wallet wallet;
// Both sides need a key (private in our case, public for the server) in order to manage the multisig contract // Both sides need a key (private in our case, public for the server) in order to manage the multisig contract
@ -193,11 +192,12 @@ public class PaymentChannelClientState {
} }
private void watchCloseConfirmations() { private void watchCloseConfirmations() {
// When we see the close transaction get a few confirmations, we can just delete the record // When we see the close transaction get enough confirmations, we can just delete the record
// 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<TransactionConfidence> future = confidence.getDepthFuture(CONFIRMATIONS_FOR_DELETE, Threading.SAME_THREAD); int numConfirms = Context.get().getEventHorizon();
ListenableFuture<TransactionConfidence> future = confidence.getDepthFuture(numConfirms, Threading.SAME_THREAD);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() { Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@Override @Override
public void onSuccess(TransactionConfidence result) { public void onSuccess(TransactionConfidence result) {

View File

@ -71,7 +71,8 @@ public class ChannelConnectionTest extends TestWithWallet {
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN); sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN); sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster)); wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster));
serverWallet = new Wallet(params); Context context = new Context(params, 3); // Shorter event horizon for unit tests.
serverWallet = new Wallet(context);
serverWallet.addExtension(new StoredPaymentChannelServerStates(serverWallet, failBroadcaster)); serverWallet.addExtension(new StoredPaymentChannelServerStates(serverWallet, failBroadcaster));
serverWallet.freshReceiveKey(); serverWallet.freshReceiveKey();
// Use an atomic boolean to indicate failure because fail()/assert*() dont work in network threads // Use an atomic boolean to indicate failure because fail()/assert*() dont work in network threads