Skip to content
This repository has been archived by the owner on Jun 17, 2020. It is now read-only.

Fix broadcast issues #165

Merged
merged 5 commits into from Aug 21, 2018
Merged

Conversation

ManfredKarrer
Copy link
Member

- We handle the timeout by default with a call onSuccess to reduce
potential problems with delayed broadcasts.
We set the depositTx  at success handler before state change gets
triggered. In regtest mode the success handler might get called
immediately, so it could cause an error if client code triggered by
state change expecting the depositTx would see it not set.
- In case the tx broadcast did not completed in time we call the
onTimeout handler which logs a waring but optimistically assume that
the broadcast will still succeed later and call onSuccess.
This strategy has advantages over calling onFailure as it might be more
often the case that the broadcast was just slow but successful later
then that the broadcast fails at all.
Copy link
Member

@chirhonul chirhonul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left some review comments.

Nothing major, just nits.

private final Wallet wallet;

/**
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Optional) It's great that the docstring was added here, but maybe there could be some description, either here or in a class-level docstring, of what the TxBroadCastTimeoutException means semantically?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment in next PR.

"We optimistically assume that the tx broadcast succeeds later and call onSuccess on the " +
"callback handler. This behaviour carries less potential problems than if we would trigger " +
"a failure (e.g. which would cause a failed create offer attempt of failed take offer attempt).\n" +
"We have no guarantee how long it will take to get the information that sufficiently BTC " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Where we say sufficiently BTC nodes, it seems more clear to instead say sufficently many Bitcoin nodes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in next PR.

"In normal situations " +
"that's very fast but in some cases it can take minutes (mostly related to Tor connection " +
"issues). So if we just go on in the application logic and treat it as successful and the " +
"tx will be broadcasted successfully later all is fine.\n" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/broadcasted/broadcast

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in next PR.

"that's very fast but in some cases it can take minutes (mostly related to Tor connection " +
"issues). So if we just go on in the application logic and treat it as successful and the " +
"tx will be broadcasted successfully later all is fine.\n" +
"If it will fail to get broadcasted, " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/broadcasted/broadcast

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in next PR.

"If it will fail to get broadcasted, " +
"it will lead to a failure state, the same as if we would trigger a failure due the timeout." +
"So we can assume that this behaviour will lead to less problems as otherwise.\n" +
"Long term we should implement better monitoring for Tor and the provided Bitcoin nodes to " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Optional) I think the text of this log message is really useful to remember why we are doing this. But maybe it would be better to discuss future how we could make future improvements etc in the form of a TODO comment in the code, or a Github issue?

"find out why those delays happen and add some rollback behaviour to the app state in case " +
"the tx will never get broadcasted.",
exception.toString(),
txId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be three arguments after the main string given, but I only see one {} in the string itself. It seems that either there are some missing {} where txId and exception.getDelay() should be placed in the string, or those arguments should be dropped from log.warn().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in next PR.

// The commit is required in case the tx is spent by a follow up tx as otherwise there would be an
// InsufficientMoneyException thrown. But in some test scenarios we also got issues with wallet
// inconsistency if the tx was committed twice. It should be prevented by the maybeCommitTx methods but
// not 100% if that is always the case. Just added that comment to make clear that this might be a risky
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think the comment mentioning why the comment was added is a little too meta.. maybe instead of:

Just added that comment to make clear that this might be a risky strategy and might need improvement if we get problems.

We could say:

This might be risky and we should re-evalute the choices we made here if there's future issues.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah maybe there was a misunderstanding. It was meant: The wallet.maybeCommitTx() call is required...

// inconsistency if the tx was committed twice. It should be prevented by the maybeCommitTx methods but
// not 100% if that is always the case. Just added that comment to make clear that this might be a risky
// strategy and might need improvement if we get problems.
exception.getWallet().maybeCommitTx(tx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Optional) It feels a little odd to have the TxBroadcastTimeoutException class know about the Wallet.. I understand why we need that reference here, but it feels like it's not a concern that the exception class should need to handle.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes i know, did not find a better solution though...

@@ -94,8 +126,8 @@ public void onSuccess(@Nullable Transaction result) {
UserThread.execute(() -> callback.onSuccess(tx));
} else {
stopAndRemoveTimer(txId);
UserThread.execute(() -> callback.onFailure(new TxBroadcastException("We got an onSuccess callback for " +
"a broadcast which got already triggered the timeout.", txId)));
log.warn("We got an onSuccess callback for a broadcast which got already triggered " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Instead of for a broadcast which got already triggered the timeout it seems more clear to say for a broadcast which already triggered the timeout.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in next PR.

@@ -92,6 +92,7 @@ protected void run() {
@Override
public void onSuccess(Transaction transaction) {
if (!completed) {
trade.setDepositTx(transaction);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Optional) It looks surprising to find the transaction referenced in this onSuccess() handler, when we are in a context of creating the very same depositTx.. I understand from conversation with @ManfredKarrer that this edit was necessary when testing on regtest, where the onSuccess() handler would fire before the trade.setDepositTx(depositTx) line on L118. Maybe a comment could be added here to explain this, to help future maintainers understand?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add a comment

@ManfredKarrer ManfredKarrer merged commit f27f46b into bisq-network:master Aug 21, 2018
ManfredKarrer added a commit to ManfredKarrer/archived-bisq-core that referenced this pull request Aug 21, 2018
@ManfredKarrer
Copy link
Member Author

Issues fixed at: b3add47

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants