From f7862219a8b387cfa2e86467a1e17635f45db465 Mon Sep 17 00:00:00 2001 From: noot <36753753+noot@users.noreply.github.com> Date: Wed, 3 May 2023 14:09:27 -0400 Subject: [PATCH] fix: start timeout watchers for xmrtaker when restarting ongoing swap (#456) --- protocol/common_test.go | 3 +++ protocol/xmrtaker/message_handler.go | 5 +++++ protocol/xmrtaker/swap_state.go | 18 +++++++++++------- protocol/xmrtaker/swap_state_test.go | 12 ++++++------ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/protocol/common_test.go b/protocol/common_test.go index efa317cf..773c6899 100644 --- a/protocol/common_test.go +++ b/protocol/common_test.go @@ -6,6 +6,8 @@ package protocol import ( "testing" + "github.com/athanorlabs/atomic-swap/common" + "github.com/stretchr/testify/require" ) @@ -21,4 +23,5 @@ func TestKeysAndProof(t *testing.T) { require.NoError(t, err) require.Equal(t, kp.Secp256k1PublicKey.String(), res.Secp256k1PublicKey.String()) require.Equal(t, kp.PublicKeyPair.SpendKey().String(), res.Ed25519PublicKey.String()) + require.Equal(t, [32]byte(common.Reverse(kp.PrivateKeyPair.SpendKey().Bytes())), kp.DLEqProof.Secret()) } diff --git a/protocol/xmrtaker/message_handler.go b/protocol/xmrtaker/message_handler.go index 9f061f5a..5b01d0d1 100644 --- a/protocol/xmrtaker/message_handler.go +++ b/protocol/xmrtaker/message_handler.go @@ -188,6 +188,11 @@ func (s *swapState) checkForXMRLock() { func (s *swapState) runT1ExpirationHandler() { defer log.Debugf("returning from runT1ExpirationHandler") + if time.Until(s.t1) <= 0 { + log.Debugf("T1 already passed, not starting T1 expiration handler") + return + } + // TODO: this variable is so that we definitely refund before t1. // Current algorithm is to trigger the timeout when only 15% of the allotted // time is remaining. If the block interval is 1 second on a test network and diff --git a/protocol/xmrtaker/swap_state.go b/protocol/xmrtaker/swap_state.go index 6de7ded0..3cb1f0ae 100644 --- a/protocol/xmrtaker/swap_state.go +++ b/protocol/xmrtaker/swap_state.go @@ -203,6 +203,9 @@ func newSwapStateFromOngoing( if info.Status == types.ETHLocked { go s.checkForXMRLock() } + + go s.runT1ExpirationHandler() + go s.runT2ExpirationHandler() return s, nil } @@ -540,12 +543,14 @@ func (s *swapState) setTimeouts(t1, t2 *big.Int) { s.info.Timeout2 = &s.t2 } +// generateAndSetKeys generates and sets the XMRTaker's monero spend and view keys (S_b, V_b), a secp256k1 public key, +// and a DLEq proof proving that the two keys correspond. func (s *swapState) generateAndSetKeys() error { if s.privkeys != nil { panic("generateAndSetKeys should only be called once") } - keysAndProof, err := generateKeys() + keysAndProof, err := pcommon.GenerateKeysAndProof() if err != nil { return err } @@ -560,6 +565,11 @@ func (s *swapState) generateAndSetKeys() error { // getSecret secrets returns the current secret scalar used to unlock funds from the contract. func (s *swapState) getSecret() [32]byte { + if s.dleqProof == nil { + // the EVM expects the bytes to be big endian, and the ed25519 lib uses little endian + return [32]byte(common.Reverse(s.privkeys.SpendKey().Bytes())) + } + secret := s.dleqProof.Secret() var sc [32]byte copy(sc[:], secret[:]) @@ -721,9 +731,3 @@ func (s *swapState) refund() (*ethtypes.Receipt, error) { s.clearNextExpectedEvent(types.CompletedRefund) return receipt, nil } - -// generateKeys generates XMRTaker's monero spend and view keys (S_b, V_b), a secp256k1 public key, -// and a DLEq proof proving that the two keys correspond. -func generateKeys() (*pcommon.KeysAndProof, error) { - return pcommon.GenerateKeysAndProof() -} diff --git a/protocol/xmrtaker/swap_state_test.go b/protocol/xmrtaker/swap_state_test.go index 3f46143d..7a39bccf 100644 --- a/protocol/xmrtaker/swap_state_test.go +++ b/protocol/xmrtaker/swap_state_test.go @@ -289,7 +289,7 @@ func TestSwapState_NotifyXMRLock(t *testing.T) { defer s.cancel() s.nextExpectedEvent = EventXMRLockedType - xmrmakerKeysAndProof, err := generateKeys() + xmrmakerKeysAndProof, err := pcommon.GenerateKeysAndProof() require.NoError(t, err) err = s.setXMRMakerKeys( @@ -322,7 +322,7 @@ func TestSwapState_NotifyXMRLock_Refund(t *testing.T) { s.nextExpectedEvent = EventXMRLockedType s.SetSwapTimeout(time.Second * 3) - xmrmakerKeysAndProof, err := generateKeys() + xmrmakerKeysAndProof, err := pcommon.GenerateKeysAndProof() require.NoError(t, err) err = s.setXMRMakerKeys( @@ -378,7 +378,7 @@ func TestExit_afterNotifyXMRLock(t *testing.T) { defer s.cancel() s.nextExpectedEvent = EventXMRLockedType - xmrmakerKeysAndProof, err := generateKeys() + xmrmakerKeysAndProof, err := pcommon.GenerateKeysAndProof() require.NoError(t, err) err = s.setXMRMakerKeys( @@ -405,7 +405,7 @@ func TestExit_afterNotifyClaimed(t *testing.T) { defer s.cancel() s.nextExpectedEvent = EventETHClaimedType - xmrmakerKeysAndProof, err := generateKeys() + xmrmakerKeysAndProof, err := pcommon.GenerateKeysAndProof() require.NoError(t, err) err = s.setXMRMakerKeys( @@ -433,7 +433,7 @@ func TestExit_invalidNextMessageType(t *testing.T) { defer s.cancel() s.nextExpectedEvent = EventExitType - xmrmakerKeysAndProof, err := generateKeys() + xmrmakerKeysAndProof, err := pcommon.GenerateKeysAndProof() require.NoError(t, err) err = s.setXMRMakerKeys( @@ -461,7 +461,7 @@ func TestSwapState_ApproveToken(t *testing.T) { s, contract := newTestSwapStateWithERC20(t, providesAmt) - xmrmakerKeysAndProof, err := generateKeys() + xmrmakerKeysAndProof, err := pcommon.GenerateKeysAndProof() require.NoError(t, err) err = s.setXMRMakerKeys(