Skip to content

Conversation

chappjc
Copy link
Member

@chappjc chappjc commented Mar 22, 2022

This PR contains three closely related updates to Swapper to improve the handling of matches around broadcast timeout and contract expiration.

server/swap: wait for init/redeem for full wait expiration bf2001c

In handleInit and handleRedeem, do not bother to limit the expiration
time of the processInit/processRedeem waiters by the broadcast timeout.
Both of the TryFuncs (processInit and processRedeem) will respond in
error if the match is revoked, so there is no need to tweak the waiter's
expire time.

This will prevent a client request timeout when the init or redeem is
submitted just before the Swapper revokes the match, when the waiter's
expire time could be set to the past despite the inaction checks having
not yet revoked the match.

server/swap: revoke when contracts are/would be expired 1be939f

This updates Swapper to proactively revoke matches where any known swap
contracts are expired, or in the case of MakerSwapCast where the
expected taker contract would be created with a lock time in the past.
These scenarios are possible if a transaction takes an extremely long
time to reach the required number of confirmations.

The new checks are done in checkInactionEventBased, which is called
on a ticker.

The (*Swapper).failMatch method is given a userFault bool input
argument to indicate if the actor should be penalized.

matchTracker is given an expiredBy method that returns true if the lock
time of either party's *known* swap is before the reference time.
Normally this will be called with the present time.

checkInactionBlockBased now consults expiredBy when calling failMatch
to determine if either of the swap contracts are expired, justifying
the inaction.

NOTE: client should be updated with similar logic to prevent attempting
to make expired contracts or contracts that are about to expire.

server/db: option to store forgiven revoked matches

When a match is revoked due to no fault of the user, it should be saved
in the DB with the forgiven flag set.

server/swap: do not accept expired contracts in processInit bbce25c

If the located contract transaction in processInit is found to have a
lock time that is in the past (already expired) revoke the match
immediately and respond to the user with an error.  No penalties are
assesed since processInit first verifies that the proper lock time has
been used.  This would be the case if the maker's swap took a very
long time to reach the required number of confirmations, and when
the taker's turn to publish their swap came around it was already
passed the expected lock time for their swap (matchTime + 8 hrs).

NOTE: client should be updated with similar logic to prevent attempting
to make expired contracts or contracts that are about to expire.

@chappjc chappjc force-pushed the negative-swapper-waiter branch from 5ffc955 to c7548ff Compare March 22, 2022 22:39
@chappjc chappjc linked an issue Mar 22, 2022 that may be closed by this pull request
@chappjc chappjc force-pushed the negative-swapper-waiter branch 2 times, most recently from fc30a4f to bbce25c Compare March 24, 2022 20:04
@chappjc chappjc marked this pull request as ready for review March 24, 2022 20:06
Comment on lines +1049 to +1054
expectedTakerLockTime := match.matchTime.Add(s.lockTimeTaker)
if expectedTakerLockTime.Before(now) {
log.Infof("Revoking match %v at %v because the expected taker swap locktime would be in the past (%v).",
match.ID(), match.Status, expectedTakerLockTime)
failMatch(false)
}
Copy link
Member

Choose a reason for hiding this comment

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

Could even add a minute or so? Taker can't be expected to react instantaneously.

Copy link
Member Author

Choose a reason for hiding this comment

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

Same thoughts here, but didn't do it because tests use arbitrary and often crazy short lock times.

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.

First pass on this looks good. I want to swing back on this tomorrow.

@chappjc
Copy link
Member Author

chappjc commented Mar 31, 2022

I actually still have to run the trade_simnet_test.go test, which I suspect might have issues with exceeded lock times. I'm confident these changes are appropriate, but the tests might need updating..

Also I'm not merging anything of mine until I give proper attention to #1510 and #1523 now that they've gotten reviews from the rest of the team.

chappjc added 3 commits April 6, 2022 15:46
In handleInit and handleRedeem, do not bother to limit the expiration
time of the processInit/processRedeem waiters by the broadcast timeout.
Both of the TryFuncs (processInit and processRedeem) will respond in
error if the match is revoked, so there is no need to tweak the waiter's
expire time.

This will prevent a client request timeout when the init or redeem is
submitted just before the Swapper revokes the match, when the waiter's
expire time could be set to the past despite the inaction checks having
not yet revoked the match.
This updates Swapper to proactively revoke matches where any known swap
contracts are expired, or in the case of MakerSwapCast where the
expected taker contract would be created with a lock time in the past.
These scenarios are possible if a transaction takes an extremely long
time to reach the required number of confirmations.

The new checks are done in checkInactionEventBased, which is called
on a ticker.

The (*Swapper).failMatch method is given a userFault bool input
argument to indicate if the actor should be penalized.

matchTracker is given an expiredBy method that returns true if the lock
time of either party's *known* swap is before the reference time.
Normally this will be called with the present time.

checkInactionBlockBased now consults expiredBy when calling failMatch
to determine if either of the swap contracts are expired, justifying
the inaction.

NOTE: client should be updated with similar logic to prevent attempting
to make expired contracts or contracts that are about to expire.

server/db: option to store forgiven revoked matches

When a match is revoked due to no fault of the user, it should be saved
in the DB with the forgiven flag set.
If the located contract transaction in processInit is found to have a
lock time that is in the past (already expired) revoke the match
immediately and respond to the user with an error.  No penalties are
assesed since processInit first verifies that the proper lock time has
been used.  This would be the case if the maker's swap took a very
long time to reach the required number of confirmations, and when
the taker's turn to publish their swap came around it was already
passed the expected lock time for their swap (matchTime + 8 hrs).

NOTE: client should be updated with similar logic to prevent attempting
to make expired contracts or contracts that are about to expire.
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.

server: Waiter given expiration before present.
3 participants