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

processAudit runs txn search async, redo match res. locking #819

Merged
merged 9 commits into from
Nov 11, 2020

Conversation

chappjc
Copy link
Member

@chappjc chappjc commented Nov 6, 2020

This prevents contract auditing from blocking all incoming messages (and pretty much any other activities for the trade in question).

Instead of expiring the coin waiter after broadcast timeout, it just goes until it finds the contract or the match is revoked.

The trackedTrade locking is also changed a great deal in match status resolution, no longer locking a trackedTrade unless and until needed.

@chappjc chappjc added this to the 0.1.2 milestone Nov 6, 2020
Comment on lines 1847 to 1910
if t.MatchIsRevoked(match) {
errChan <- ExpirationErr(fmt.Sprintf("match revoked while waiting to find counterparty contract coin %v (%s). "+
"Check your internet and wallet connections!", contractID, contractSymb))
return wait.DontTryAgain
}
if tries > 2 {
t.dc.log.Infof("Still searching for contract coin %v (%s) for match %v. "+
Copy link
Member Author

@chappjc chappjc Nov 6, 2020

Choose a reason for hiding this comment

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

Still considering if it should still try at least a couple times even if it is revoked, or is being revoked a good indicator that the audit is now irrelevant...

Copy link
Member Author

Choose a reason for hiding this comment

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

Audit is only useful for the normal swap negotiation path, so I've concluded no, the audit is not needed for a revoked match, which will go to refund. However, I believe there is an opportunity for an improvement that would require more work: #829

@chappjc chappjc marked this pull request as ready for review November 6, 2020 20:49
@chappjc
Copy link
Member Author

chappjc commented Nov 6, 2020

Working as intended, although I'm uncertain about the audit timeout during resolution.

@chappjc chappjc force-pushed the async-audit branch 2 times, most recently from bfcd652 to a67bef5 Compare November 10, 2020 17:07
Comment on lines +1487 to +1484
// With updated swap data, attempt match status resolution.
if needsResolution {
Copy link
Member Author

Choose a reason for hiding this comment

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

Now making sure match status and proof data updates happen before firing off the resolution goroutine.

Copy link
Member

@buck54321 buck54321 left a comment

Choose a reason for hiding this comment

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

Tests well.

I do feel like there is some new added complexity around lock handling in status.go that could have been avoided. For example, the new (exported?) getter methods in trackedTrade are only needed because we're not locking for all of resolveConflictWithServerData anymore. But there were only two paths (I think) that had the potential for long delays from mutex locking, and you've already stated that the correct solution is to run auditContract in a goroutine and unlock. New pattern seems racier.

client/core/trade.go Outdated Show resolved Hide resolved
client/core/trade.go Outdated Show resolved Hide resolved
client/core/trade.go Outdated Show resolved Hide resolved
@chappjc
Copy link
Member Author

chappjc commented Nov 11, 2020

I also snuck in a notification with the last commit yesterday. It's not pretty because the IDs are too long, but I think it needs at least the coin ID (utxo)

image

@chappjc
Copy link
Member Author

chappjc commented Nov 11, 2020

I discovered a very similar issue to the one addressed by this PR, which is the client's 'init' and 'redeem' requests are also blocking as finalizeSwapAction and finalizeRedeemAction wait until the server responds. A server response requires the server to search for the txn, so we have a similar failure mode as we saw with the audits. We should address this without delay.

return wait.TryAgain
}
errChan <- err
if err == nil {
Copy link
Member Author

@chappjc chappjc Nov 11, 2020

Choose a reason for hiding this comment

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

@buck54321 The hack I was using to simulate slow wallet AuditContract discovery of the coin is the following right after AuditContract:

if tries < 14 {
	err = asset.CoinNotFoundError
}

@chappjc
Copy link
Member Author

chappjc commented Nov 11, 2020

With that rebase, I added one commit (703767f) that adapts the recheck interval to the recently raised default broadcast timeout so that periodic ticks are every 90 seconds (12 minutes / 8 divisions) instead of every 4 minutes (12 minutes / 3 divisions).

The commit also tweaks the checkTrades flow so that the tradeMtx is never locked while a trackedTrade is locked. We don't want the trade map held unnecessarily, especially given the possibility for a trade to remain locked for a significant duration (e.g. finalizeSwapAction). This is fine in checkTrades since once a trade is declared inactive, there's no way it can become active again, so the map access and trade checks do not need to be atomic.

client/core/core_test.go Outdated Show resolved Hide resolved
client/core/trade.go Show resolved Hide resolved
@chappjc chappjc merged commit 938905e into decred:master Nov 11, 2020
@chappjc chappjc deleted the async-audit branch November 11, 2020 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants