mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-08 21:58:07 -05:00
114 lines
3.9 KiB
Go
114 lines
3.9 KiB
Go
// Copyright 2023 Athanor Labs (ON)
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
package xmrtaker
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"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"
|
|
"github.com/athanorlabs/atomic-swap/ethereum/watcher"
|
|
"github.com/athanorlabs/atomic-swap/monero"
|
|
"github.com/athanorlabs/atomic-swap/net/message"
|
|
pcommon "github.com/athanorlabs/atomic-swap/protocol"
|
|
)
|
|
|
|
func lockXMRAndCheckForReadyLog(t *testing.T, s *swapState, xmrAddr *mcrypto.Address) {
|
|
// backend simulates the xmrmaker's instance
|
|
backend := newBackend(t)
|
|
monero.MineMinXMRBalance(t, backend.XMRClient(), coins.MoneroToPiconero(coins.StrToDecimal("1")))
|
|
|
|
amt := s.expectedPiconeroAmount()
|
|
amtu64, err := amt.Uint64()
|
|
require.NoError(t, err)
|
|
// lock xmr
|
|
transfer, err := backend.XMRClient().Transfer(s.ctx, xmrAddr, 0, amt, monero.MinSpendConfirmations)
|
|
require.NoError(t, err)
|
|
require.Equal(t, transfer.Amount, amtu64)
|
|
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)
|
|
|
|
// assert that ready() is called, setup contract watcher
|
|
ethHeader, err := backend.ETHClient().Raw().HeaderByNumber(backend.Ctx(), nil)
|
|
require.NoError(t, err)
|
|
logReadyCh := make(chan ethtypes.Log)
|
|
|
|
readyTopic := common.GetTopic(common.ReadyEventSignature)
|
|
readyWatcher := watcher.NewEventFilter(
|
|
s.Backend.Ctx(),
|
|
s.Backend.ETHClient().Raw(),
|
|
s.Backend.SwapCreatorAddr(),
|
|
ethHeader.Number,
|
|
readyTopic,
|
|
logReadyCh,
|
|
)
|
|
err = readyWatcher.Start()
|
|
require.NoError(t, err)
|
|
|
|
// 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 * 5):
|
|
t.Fatalf("didn't get ready logs in time")
|
|
}
|
|
}
|
|
|
|
func TestSwapState_handleEvent_EventETHClaimed(t *testing.T) {
|
|
s, net := newTestSwapStateAndNet(t)
|
|
defer s.cancel()
|
|
s.SetSwapTimeout(time.Minute * 2)
|
|
|
|
// invalid SendKeysMessage should result in an error
|
|
msg := &message.SendKeysMessage{}
|
|
err := s.HandleProtocolMessage(msg)
|
|
require.ErrorIs(t, err, errMissingProvidedAmount)
|
|
|
|
// handle valid SendKeysMessage
|
|
msg = s.SendKeysMessage().(*message.SendKeysMessage)
|
|
msg.PrivateViewKey = s.privkeys.ViewKey()
|
|
msg.EthAddress = s.ETHClient().Address()
|
|
msg.ProvidedAmount = s.providedAmount.AsStandard()
|
|
|
|
err = s.HandleProtocolMessage(msg)
|
|
require.NoError(t, err)
|
|
|
|
resp := net.LastSentMessage()
|
|
require.NotNil(t, resp)
|
|
require.Equal(t, message.NotifyETHLockedType, resp.Type())
|
|
require.Equal(t, time.Minute*2, s.t1.Sub(s.t0))
|
|
require.Equal(t, msg.PublicSpendKey.Hex(), s.xmrmakerPublicSpendKey.Hex())
|
|
require.Equal(t, msg.PrivateViewKey.Hex(), s.xmrmakerPrivateViewKey.Hex())
|
|
|
|
// simulate xmrmaker locking xmr
|
|
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
|
|
secret := s.privkeys.SpendKeyBytes()
|
|
sk, err := mcrypto.NewPrivateSpendKey(secret[:])
|
|
require.NoError(t, err)
|
|
|
|
// handled the claimed message should result in the monero wallet being created
|
|
event := newEventETHClaimed(sk)
|
|
s.eventCh <- event
|
|
err = <-event.errCh
|
|
require.NoError(t, err)
|
|
require.Equal(t, types.CompletedSuccess, s.info.Status)
|
|
}
|