diff --git a/net/message/message.go b/net/message/message.go index 79825c3d..692fc621 100644 --- a/net/message/message.go +++ b/net/message/message.go @@ -22,7 +22,6 @@ const ( QueryResponseType byte = iota SendKeysType NotifyETHLockedType - NotifyXMRLockType ) // TypeToString converts a message type into a string. @@ -34,8 +33,6 @@ func TypeToString(t byte) string { return "SendKeysMessage" case NotifyETHLockedType: return "NotifyETHLocked" - case NotifyXMRLockType: - return "NotifyXMRLock" default: return "unknown" } @@ -59,8 +56,6 @@ func DecodeMessage(b []byte) (common.Message, error) { msg = &SendKeysMessage{} case NotifyETHLockedType: msg = &NotifyETHLocked{} - case NotifyXMRLockType: - msg = &NotifyXMRLock{} default: return nil, fmt.Errorf("invalid message type=%d", msgType) } @@ -173,29 +168,3 @@ func (m *NotifyETHLocked) Encode() ([]byte, error) { func (m *NotifyETHLocked) Type() byte { return NotifyETHLockedType } - -// NotifyXMRLock is sent by XMRMaker to XMRTaker after locking his XMR. -type NotifyXMRLock struct { - Address *mcrypto.Address `json:"address" validate:"required"` // address the monero was sent to - TxID types.Hash `json:"txID" validate:"required"` // Monero transaction ID (transaction hash in hex) -} - -// String ... -func (m *NotifyXMRLock) String() string { - return "NotifyXMRLock" -} - -// Encode ... -func (m *NotifyXMRLock) Encode() ([]byte, error) { - b, err := vjson.MarshalStruct(m) - if err != nil { - return nil, err - } - - return append([]byte{NotifyXMRLockType}, b...), nil -} - -// Type ... -func (m *NotifyXMRLock) Type() byte { - return NotifyXMRLockType -} diff --git a/protocol/xmrmaker/event.go b/protocol/xmrmaker/event.go index 1907f299..d0e909c9 100644 --- a/protocol/xmrmaker/event.go +++ b/protocol/xmrmaker/event.go @@ -190,7 +190,7 @@ func (s *swapState) handleEvent(event Event) { return } - err := s.handleEventETHLocked(e) + err := s.handleNotifyETHLocked(e.message) if err != nil { e.errCh <- fmt.Errorf("failed to handle EventETHLocked: %w", err) if !s.fundsLocked { @@ -250,15 +250,6 @@ func (s *swapState) handleEvent(event Event) { } } -func (s *swapState) handleEventETHLocked(e *EventETHLocked) error { - resp, err := s.handleNotifyETHLocked(e.message) - if err != nil { - return err - } - - return s.SendSwapMessage(resp, s.ID()) -} - func (s *swapState) handleEventContractReady() error { log.Debug("contract ready, attempting to claim funds...") close(s.readyCh) diff --git a/protocol/xmrmaker/event_test.go b/protocol/xmrmaker/event_test.go index cd875ec1..b0e00f0d 100644 --- a/protocol/xmrmaker/event_test.go +++ b/protocol/xmrmaker/event_test.go @@ -58,7 +58,7 @@ func TestSwapState_handleEvent_EventETHRefunded(t *testing.T) { newSwap(t, s, [32]byte{}, refundKey, desiredAmount.BigInt(), duration) // lock XMR - _, err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) + err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) require.NoError(t, err) // call refund w/ XMRTaker's secret diff --git a/protocol/xmrmaker/instance_test.go b/protocol/xmrmaker/instance_test.go index 6725506f..459d1cf5 100644 --- a/protocol/xmrmaker/instance_test.go +++ b/protocol/xmrmaker/instance_test.go @@ -146,11 +146,6 @@ func newTestInstanceAndDB(t *testing.T) (*Instance, *offers.MockDatabase) { return inst, db } -func newTestInstanceAndNet(t *testing.T) (*Instance, *mockNet) { - inst, _, net := newTestInstanceAndDBAndNet(t) - return inst, net -} - func TestInstance_createOngoingSwap(t *testing.T) { inst, offerDB := newTestInstanceAndDB(t) rdb := inst.backend.RecoveryDB().(*backend.MockRecoveryDB) diff --git a/protocol/xmrmaker/message_handler.go b/protocol/xmrmaker/message_handler.go index e66a5ec5..27da2a4f 100644 --- a/protocol/xmrmaker/message_handler.go +++ b/protocol/xmrmaker/message_handler.go @@ -86,20 +86,20 @@ func (s *swapState) setNextExpectedEvent(event EventType) error { return nil } -func (s *swapState) handleNotifyETHLocked(msg *message.NotifyETHLocked) (common.Message, error) { +func (s *swapState) handleNotifyETHLocked(msg *message.NotifyETHLocked) error { if msg.Address == (ethcommon.Address{}) { - return nil, errMissingAddress + return errMissingAddress } if types.IsHashZero(msg.ContractSwapID) { - return nil, errNilContractSwapID + return errNilContractSwapID } log.Infof("got NotifyETHLocked; address=%s contract swap ID=%s", msg.Address, msg.ContractSwapID) // validate that swap ID == keccak256(swap struct) if err := checkContractSwapID(msg); err != nil { - return nil, err + return err } s.contractSwapID = msg.ContractSwapID @@ -107,7 +107,7 @@ func (s *swapState) handleNotifyETHLocked(msg *message.NotifyETHLocked) (common. receipt, err := s.Backend.ETHClient().Raw().TransactionReceipt(s.ctx, msg.TxHash) if err != nil { - return nil, err + return err } contractAddr := msg.Address @@ -116,11 +116,11 @@ func (s *swapState) handleNotifyETHLocked(msg *message.NotifyETHLocked) (common. // doesn't hurt though I suppose. _, err = contracts.CheckSwapFactoryContractCode(s.ctx, s.Backend.ETHClient().Raw(), contractAddr) if err != nil { - return nil, err + return err } if err = s.setContract(contractAddr); err != nil { - return nil, fmt.Errorf("failed to instantiate contract instance: %w", err) + return fmt.Errorf("failed to instantiate contract instance: %w", err) } ethInfo := &db.EthereumSwapInfo{ @@ -131,25 +131,25 @@ func (s *swapState) handleNotifyETHLocked(msg *message.NotifyETHLocked) (common. } if err = s.Backend.RecoveryDB().PutContractSwapInfo(s.ID(), ethInfo); err != nil { - return nil, err + return err } if err = s.checkContract(msg.TxHash); err != nil { - return nil, err + return err } err = s.checkAndSetTimeouts(msg.ContractSwap.Timeout0, msg.ContractSwap.Timeout1) if err != nil { - return nil, err + return err } - notifyXMRLocked, err := s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) + err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) if err != nil { - return nil, fmt.Errorf("failed to lock funds: %w", err) + return fmt.Errorf("failed to lock funds: %w", err) } go s.runT0ExpirationHandler() - return notifyXMRLocked, nil + return nil } func (s *swapState) runT0ExpirationHandler() { diff --git a/protocol/xmrmaker/swap_state.go b/protocol/xmrmaker/swap_state.go index 8614fd11..9e56ad6e 100644 --- a/protocol/xmrmaker/swap_state.go +++ b/protocol/xmrmaker/swap_state.go @@ -510,14 +510,14 @@ func (s *swapState) setContract(address ethcommon.Address) error { // lockFunds locks XMRMaker's funds in the monero account specified by public key // (S_a + S_b), viewable with (V_a + V_b) // It accepts the amount to lock as the input -func (s *swapState) lockFunds(amount *coins.PiconeroAmount) (*message.NotifyXMRLock, error) { +func (s *swapState) lockFunds(amount *coins.PiconeroAmount) error { xmrtakerPublicKeys := mcrypto.NewPublicKeyPair(s.xmrtakerPublicSpendKey, s.xmrtakerPrivateViewKey.Public()) swapDestAddr := mcrypto.SumSpendAndViewKeys(xmrtakerPublicKeys, s.pubkeys).Address(s.Env()) log.Infof("going to lock XMR funds, amount=%s XMR", amount.AsMoneroString()) balance, err := s.XMRClient().GetBalance(0) if err != nil { - return nil, err + return err } log.Debug("total XMR balance: ", coins.FmtPiconeroAmtAsXMR(balance.Balance)) @@ -526,19 +526,11 @@ func (s *swapState) lockFunds(amount *coins.PiconeroAmount) (*message.NotifyXMRL log.Infof("Starting lock of %s XMR in address %s", amount.AsMoneroString(), swapDestAddr) transfer, err := s.XMRClient().Transfer(s.ctx, swapDestAddr, 0, amount, monero.MinSpendConfirmations) if err != nil { - return nil, err + return err } + log.Infof("Successfully locked XMR funds: txID=%s address=%s block=%d", transfer.TxID, swapDestAddr, transfer.Height) s.fundsLocked = true - - txID, err := types.HexToHash(transfer.TxID) - if err != nil { - return nil, err - } - - return &message.NotifyXMRLock{ - Address: swapDestAddr, - TxID: txID, - }, nil + return nil } diff --git a/protocol/xmrmaker/swap_state_ongoing_test.go b/protocol/xmrmaker/swap_state_ongoing_test.go index 7df2c53c..01356603 100644 --- a/protocol/xmrmaker/swap_state_ongoing_test.go +++ b/protocol/xmrmaker/swap_state_ongoing_test.go @@ -86,7 +86,7 @@ func TestSwapStateOngoing_Refund(t *testing.T) { newSwap(t, s, [32]byte{}, refundKey, desiredAmount.BigInt(), duration) // lock XMR - _, err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) + err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) require.NoError(t, err) s.cancel() diff --git a/protocol/xmrmaker/swap_state_test.go b/protocol/xmrmaker/swap_state_test.go index 2ae30577..9f52df2e 100644 --- a/protocol/xmrmaker/swap_state_test.go +++ b/protocol/xmrmaker/swap_state_test.go @@ -45,27 +45,6 @@ func newTestSwapStateAndDB(t *testing.T) (*Instance, *swapState, *offers.MockDat return xmrmaker, swapState, db } -func newTestSwapStateAndNet(t *testing.T) (*Instance, *swapState, *mockNet) { - xmrmaker, net := newTestInstanceAndNet(t) - - swapState, err := newSwapStateFromStart( - xmrmaker.backend, - types.NewOffer( - coins.ProvidesXMR, - coins.StrToDecimal("0.1"), - coins.StrToDecimal("1"), - coins.StrToExchangeRate("0.1"), - types.EthAssetETH, - ), - &types.OfferExtra{}, - xmrmaker.offerManager, - coins.MoneroToPiconero(coins.StrToDecimal("0.1")), - desiredAmount, - ) - require.NoError(t, err) - return xmrmaker, swapState, net -} - func newTestSwapState(t *testing.T) (*Instance, *swapState) { xmrmaker, swapState, _ := newTestSwapStateAndDB(t) return xmrmaker, swapState @@ -177,7 +156,7 @@ func TestSwapState_handleSendKeysMessage(t *testing.T) { } func TestSwapState_HandleProtocolMessage_NotifyETHLocked_ok(t *testing.T) { - _, s, net := newTestSwapStateAndNet(t) + _, s := newTestSwapState(t) defer s.cancel() s.nextExpectedEvent = EventETHLockedType @@ -208,12 +187,6 @@ func TestSwapState_HandleProtocolMessage_NotifyETHLocked_ok(t *testing.T) { err = s.HandleProtocolMessage(msg) require.NoError(t, err) - resp := net.LastSentMessage() - require.NotNil(t, resp) - require.Equal(t, message.NotifyXMRLockType, resp.Type()) - require.Equal(t, duration, s.t1.Sub(s.t0)) - require.Equal(t, EventContractReadyType, s.nextExpectedEvent) - require.True(t, s.info.Status.IsOngoing()) } func TestSwapState_HandleProtocolMessage_NotifyETHLocked_timeout(t *testing.T) { @@ -279,7 +252,7 @@ func TestSwapState_handleRefund(t *testing.T) { newSwap(t, s, [32]byte{}, refundKey, desiredAmount.BigInt(), duration) // lock XMR - _, err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) + err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) require.NoError(t, err) // call refund w/ XMRTaker's spend key @@ -327,7 +300,7 @@ func TestSwapState_Exit_Reclaim(t *testing.T) { newSwap(t, s, [32]byte{}, refundKey, desiredAmount.BigInt(), duration) // lock XMR - _, err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) + err = s.lockFunds(coins.MoneroToPiconero(s.info.ProvidedAmount)) require.NoError(t, err) balAfterLock, err := s.XMRClient().GetBalance(0) diff --git a/protocol/xmrtaker/errors.go b/protocol/xmrtaker/errors.go index 44e50e19..002e3367 100644 --- a/protocol/xmrtaker/errors.go +++ b/protocol/xmrtaker/errors.go @@ -18,7 +18,6 @@ var ( errCannotRefund = errors.New("swap is not at a stage where it can refund") errRefundInvalid = errors.New("cannot refund, swap does not exist") errRefundSwapCompleted = fmt.Errorf("cannot refund, %w", errSwapCompleted) - errNoLockedXMRAddress = errors.New("got empty address for locked XMR") errCounterpartyKeysNotSet = errors.New("counterparty's keys aren't set") errSwapInstantiationNoLogs = errors.New("expected 1 log, got 0") errSwapCompleted = errors.New("swap is already completed") diff --git a/protocol/xmrtaker/event.go b/protocol/xmrtaker/event.go index 0dff98b7..5f4a6380 100644 --- a/protocol/xmrtaker/event.go +++ b/protocol/xmrtaker/event.go @@ -131,8 +131,7 @@ func newEventKeysReceived(msg *message.SendKeysMessage) *EventKeysReceived { // EventXMRLocked is the second expected event. It represents XMR being locked // on-chain. type EventXMRLocked struct { - message *message.NotifyXMRLock - errCh chan error + errCh chan error } // Type ... @@ -140,10 +139,9 @@ func (*EventXMRLocked) Type() EventType { return EventXMRLockedType } -func newEventXMRLocked(msg *message.NotifyXMRLock) *EventXMRLocked { +func newEventXMRLocked() *EventXMRLocked { return &EventXMRLocked{ - message: msg, - errCh: make(chan error), + errCh: make(chan error), } } @@ -248,7 +246,7 @@ func (s *swapState) handleEvent(event Event) { return } - err := s.handleEventXMRLocked(e) + err := s.handleNotifyXMRLock() if err != nil { e.errCh <- fmt.Errorf("failed to handle %s: %w", e.Type(), err) return @@ -311,10 +309,6 @@ func (s *swapState) handleEventKeysReceived(event *EventKeysReceived) error { return s.SendSwapMessage(resp, s.ID()) } -func (s *swapState) handleEventXMRLocked(event *EventXMRLocked) error { - return s.handleNotifyXMRLock(event.message) -} - func (s *swapState) handleEventETHClaimed(event *EventETHClaimed) error { _, err := s.claimMonero(event.sk) if err != nil { diff --git a/protocol/xmrtaker/event_test.go b/protocol/xmrtaker/event_test.go index 6f6f3e62..737a21f5 100644 --- a/protocol/xmrtaker/event_test.go +++ b/protocol/xmrtaker/event_test.go @@ -32,15 +32,6 @@ func lockXMRAndCheckForReadyLog(t *testing.T, s *swapState, xmrAddr *mcrypto.Add t.Logf("Transferred %d pico XMR (fees %d) to account %s", transfer.Amount, transfer.Fee, xmrAddr) t.Logf("Transfer was mined at block=%d with %d confirmations", transfer.Height, transfer.Confirmations) - txID, err := types.HexToHash(transfer.TxID) - require.NoError(t, err) - - // send notification that monero was locked - lmsg := &message.NotifyXMRLock{ - Address: xmrAddr, - TxID: txID, - } - // assert that ready() is called, setup contract watcher ethHeader, err := backend.ETHClient().Raw().HeaderByNumber(backend.Ctx(), nil) require.NoError(t, err) @@ -58,17 +49,12 @@ func lockXMRAndCheckForReadyLog(t *testing.T, s *swapState, xmrAddr *mcrypto.Add err = readyWatcher.Start() require.NoError(t, err) - // now handle the NotifyXMRLock message - err = s.HandleProtocolMessage(lmsg) - require.NoError(t, err) - require.Equal(t, s.nextExpectedEvent, EventETHClaimedType) - require.Equal(t, types.ContractReady, s.info.Status) - + // goroutine in SendKeysMessage handler should handle the NotifyXMRLock message select { case log := <-logReadyCh: err = pcommon.CheckSwapID(&log, readyTopic, s.contractSwapID) require.NoError(t, err) - case <-time.After(time.Second * 2): + case <-time.After(time.Second * 5): t.Fatalf("didn't get ready logs in time") } } @@ -106,6 +92,11 @@ func TestSwapState_handleEvent_EventETHClaimed(t *testing.T) { kp := mcrypto.SumSpendAndViewKeys(s.pubkeys, s.pubkeys) xmrAddr := kp.Address(common.Mainnet) lockXMRAndCheckForReadyLog(t, s, xmrAddr) + // give handleNotifyXMRLock some time to return, since the event watcher + // sees the Ready event before swapState.ready() returns + time.Sleep(time.Second * 2) + require.Equal(t, EventETHClaimedType, s.nextExpectedEvent) + require.Equal(t, types.ContractReady, s.info.Status) // simulate xmrmaker calling claim // call swap.Swap.Claim() w/ b.privkeys.sk, revealing XMRMaker's secret spend key diff --git a/protocol/xmrtaker/message_handler.go b/protocol/xmrtaker/message_handler.go index 4fbb07b3..8119bc2e 100644 --- a/protocol/xmrtaker/message_handler.go +++ b/protocol/xmrtaker/message_handler.go @@ -5,7 +5,6 @@ import ( "fmt" "time" - "github.com/athanorlabs/atomic-swap/coins" "github.com/athanorlabs/atomic-swap/common" "github.com/athanorlabs/atomic-swap/common/types" mcrypto "github.com/athanorlabs/atomic-swap/crypto/monero" @@ -29,13 +28,6 @@ func (s *swapState) HandleProtocolMessage(msg common.Message) error { if err != nil { return err } - case *message.NotifyXMRLock: - event := newEventXMRLocked(msg) - s.eventCh <- event - err := <-event.errCh - if err != nil { - return err - } default: return errUnexpectedMessageType } @@ -138,6 +130,9 @@ func (s *swapState) handleSendKeysMessage(msg *message.SendKeysMessage) (common. // start goroutine to check that XMRMaker locks before t_0 go s.runT0ExpirationHandler() + // start goroutine to check for xmr being locked + go s.checkForXMRLock() + out := &message.NotifyETHLocked{ Address: s.ContractAddr(), TxHash: txHash, @@ -148,6 +143,57 @@ func (s *swapState) handleSendKeysMessage(msg *message.SendKeysMessage) (common. return out, nil } +func (s *swapState) checkForXMRLock() { + var checkForXMRLockInterval time.Duration + if s.Env() == common.Development { + checkForXMRLockInterval = time.Second + } else { + // monero block time is >1 minute, so this should be fine + checkForXMRLockInterval = time.Minute + } + + // check that XMR was locked in expected account, and confirm amount + lockedAddr, vk := s.expectedXMRLockAccount() + + conf := s.XMRClient().CreateWalletConf("xmrtaker-swap-wallet-verify-funds") + abViewCli, err := monero.CreateViewOnlyWalletFromKeys(conf, vk, lockedAddr, s.walletScanHeight) + if err != nil { + log.Errorf("failed to generate view-only wallet to verify locked XMR: %s", err) + return + } + defer abViewCli.CloseAndRemoveWallet() + + log.Debugf("generated view-only wallet to check funds: %s", abViewCli.WalletName()) + + timer := time.NewTicker(checkForXMRLockInterval) + for { + select { + case <-s.ctx.Done(): + return + case <-timer.C: + balance, err := abViewCli.GetBalance(0) + if err != nil { + log.Errorf("failed to get balance: %s", err) + continue + } + + log.Debugf("checking locked wallet, address=%s balance=%d blocks-to-unlock=%d", + lockedAddr, balance.Balance, balance.BlocksToUnlock) + + if s.expectedPiconeroAmount().CmpU64(balance.UnlockedBalance) <= 0 { + event := newEventXMRLocked() + s.eventCh <- event + err := <-event.errCh + if err != nil { + log.Errorf("eventXMRLocked errored: %s", err) + } + + return + } + } + } +} + func (s *swapState) runT0ExpirationHandler() { defer log.Debugf("returning from runT0ExpirationHandler") @@ -189,51 +235,7 @@ func (s *swapState) expectedXMRLockAccount() (*mcrypto.Address, *mcrypto.Private return mcrypto.NewPublicKeyPair(sk, vk.Public()).Address(s.Env()), vk } -func (s *swapState) handleNotifyXMRLock(msg *message.NotifyXMRLock) error { - if msg.Address == nil { - return errNoLockedXMRAddress - } - - // check that XMR was locked in expected account, and confirm amount - lockedAddr, vk := s.expectedXMRLockAccount() - if !msg.Address.Equal(lockedAddr) { - return fmt.Errorf("address received in message does not match expected address") - } - - conf := s.XMRClient().CreateWalletConf("xmrtaker-swap-wallet-verify-funds") - abViewCli, err := monero.CreateViewOnlyWalletFromKeys(conf, vk, lockedAddr, s.walletScanHeight) - if err != nil { - return fmt.Errorf("failed to generate view-only wallet to verify locked XMR: %w", err) - } - defer abViewCli.CloseAndRemoveWallet() - - log.Debugf("generated view-only wallet to check funds: %s", abViewCli.WalletName()) - - balance, err := abViewCli.GetBalance(0) - if err != nil { - return fmt.Errorf("failed to get balance: %w", err) - } - - log.Debugf("checking locked wallet, address=%s balance=%d blocks-to-unlock=%d", - lockedAddr, balance.Balance, balance.BlocksToUnlock) - - if s.expectedPiconeroAmount().CmpU64(balance.Balance) > 0 { - return fmt.Errorf("locked XMR amount is less than expected: got %s, expected %s", - coins.FmtPiconeroAmtAsXMR(balance.Balance), s.ExpectedAmount().Text('f')) - } - - // Monero received from a transfer is locked for a minimum of 10 confirmations before - // it can be spent again. The maker is required to wait for 10 confirmations before - // notifying us that the XMR is locked and should not be adding additional wait - // requirements. We give one block of leniency, in case the taker's node is not fully - // synced. Our goal is to prevent double spends, issues due to block reorgs, and - // prevent the maker from locking our funds until close to the heat death of the - // universe (https://github.com/monero-project/research-lab/issues/78). - if balance.BlocksToUnlock > 1 { - return fmt.Errorf("received XMR funds are not unlocked as required (blocks-to-unlock=%d)", - balance.BlocksToUnlock) - } - +func (s *swapState) handleNotifyXMRLock() error { close(s.xmrLockedCh) log.Info("XMR was locked successfully, setting contract to ready...") diff --git a/protocol/xmrtaker/swap_state.go b/protocol/xmrtaker/swap_state.go index 59cacaf4..47fff83a 100644 --- a/protocol/xmrtaker/swap_state.go +++ b/protocol/xmrtaker/swap_state.go @@ -189,6 +189,10 @@ func newSwapStateFromOngoing( s.contractSwap = ethSwapInfo.Swap s.xmrmakerPublicSpendKey = makerSk s.xmrmakerPrivateViewKey = makerVk + + if info.Status == types.ETHLocked { + go s.checkForXMRLock() + } return s, nil } diff --git a/protocol/xmrtaker/swap_state_test.go b/protocol/xmrtaker/swap_state_test.go index 20cfe31d..ef8bb76a 100644 --- a/protocol/xmrtaker/swap_state_test.go +++ b/protocol/xmrtaker/swap_state_test.go @@ -239,15 +239,10 @@ func lockXMRFunds( wc monero.WalletClient, destAddr *mcrypto.Address, amount *coins.PiconeroAmount, -) types.Hash { +) { monero.MineMinXMRBalance(t, wc, amount) - transfer, err := wc.Transfer(ctx, destAddr, 0, amount, monero.MinSpendConfirmations) + _, err := wc.Transfer(ctx, destAddr, 0, amount, monero.MinSpendConfirmations) require.NoError(t, err) - - txID, err := types.HexToHash(transfer.TxID) - require.NoError(t, err) - - return txID } func TestSwapState_NotifyXMRLock(t *testing.T) { @@ -271,12 +266,10 @@ func TestSwapState_NotifyXMRLock(t *testing.T) { kp := mcrypto.SumSpendAndViewKeys(xmrmakerKeysAndProof.PublicKeyPair, s.pubkeys) xmrAddr := kp.Address(common.Development) - msg := &message.NotifyXMRLock{ - Address: xmrAddr, - TxID: lockXMRFunds(t, s.ctx, s.XMRClient(), xmrAddr, s.expectedPiconeroAmount()), - } - - err = s.HandleProtocolMessage(msg) + lockXMRFunds(t, s.ctx, s.XMRClient(), xmrAddr, s.expectedPiconeroAmount()) + event := newEventXMRLocked() + s.eventCh <- event + err = <-event.errCh require.NoError(t, err) require.Equal(t, EventETHClaimedType, s.nextExpectedEvent) } @@ -305,12 +298,10 @@ func TestSwapState_NotifyXMRLock_Refund(t *testing.T) { kp := mcrypto.SumSpendAndViewKeys(xmrmakerKeysAndProof.PublicKeyPair, s.pubkeys) xmrAddr := kp.Address(common.Development) - msg := &message.NotifyXMRLock{ - Address: xmrAddr, - TxID: lockXMRFunds(t, s.ctx, s.XMRClient(), xmrAddr, s.expectedPiconeroAmount()), - } - - err = s.HandleProtocolMessage(msg) + lockXMRFunds(t, s.ctx, s.XMRClient(), xmrAddr, s.expectedPiconeroAmount()) + event := newEventXMRLocked() + s.eventCh <- event + err = <-event.errCh require.NoError(t, err) require.Equal(t, EventETHClaimedType, s.nextExpectedEvent)