Files
atomic-swap/protocol/xmrtaker/claim.go
2023-04-26 15:55:46 -04:00

128 lines
2.7 KiB
Go

// Copyright 2023 The AthanorLabs/atomic-swap Authors
// SPDX-License-Identifier: LGPL-3.0-only
package xmrtaker
import (
"fmt"
"github.com/athanorlabs/atomic-swap/common/types"
mcrypto "github.com/athanorlabs/atomic-swap/crypto/monero"
contracts "github.com/athanorlabs/atomic-swap/ethereum"
pcommon "github.com/athanorlabs/atomic-swap/protocol"
eth "github.com/ethereum/go-ethereum"
ethcommon "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
func (s *swapState) tryClaim() error {
if !s.info.Status.IsOngoing() {
return nil
}
skA, err := s.filterForClaim()
if err != nil {
return err
}
addr, err := s.claimMonero(skA)
if err != nil {
return err
}
log.Infof("claimed monero: address=%s", addr)
s.clearNextExpectedEvent(types.CompletedSuccess)
return nil
}
func (s *swapState) filterForClaim() (*mcrypto.PrivateSpendKey, error) {
logs, err := s.ETHClient().Raw().FilterLogs(s.ctx, eth.FilterQuery{
Addresses: []ethcommon.Address{s.SwapCreatorAddr()},
Topics: [][]ethcommon.Hash{{claimedTopic}},
})
if err != nil {
return nil, fmt.Errorf("failed to filter logs: %w", err)
}
if len(logs) == 0 {
return nil, errNoClaimLogsFound
}
var (
foundLog ethtypes.Log
found bool
)
for _, log := range logs {
matches, err := contracts.CheckIfLogIDMatches(log, claimedTopic, s.contractSwapID) //nolint:govet
if err != nil {
continue
}
if matches {
foundLog = log
found = true
break
}
}
if !found {
return nil, errNoClaimLogsFound
}
sa, err := contracts.GetSecretFromLog(&foundLog, claimedTopic)
if err != nil {
return nil, fmt.Errorf("failed to get secret from log: %w", err)
}
return sa, nil
}
func (s *swapState) claimMonero(skB *mcrypto.PrivateSpendKey) (*mcrypto.Address, error) {
if !s.info.Status.IsOngoing() {
return nil, errSwapCompleted
}
// write counterparty swap privkey to disk in case something goes wrong
err := s.Backend.RecoveryDB().PutCounterpartySwapPrivateKey(s.OfferID(), skB)
if err != nil {
return nil, err
}
id := s.OfferID()
depositAddr := s.XMRDepositAddress(&id)
if s.noTransferBack {
depositAddr = nil
}
kpAB := pcommon.GetClaimKeypair(
skB, s.privkeys.SpendKey(),
s.xmrmakerPrivateViewKey, s.privkeys.ViewKey(),
)
err = pcommon.ClaimMonero(
s.ctx,
s.Env(),
s.info,
s.XMRClient(),
kpAB,
depositAddr,
s.noTransferBack,
s.Backend.SwapManager(),
)
if err != nil {
return nil, err
}
close(s.claimedCh)
log.Infof("monero claimed and swept to original account %s", depositAddr)
go func() {
err = s.Exit()
if err != nil {
log.Warnf("failed to exit: %v", err)
}
}()
return kpAB.PublicKeyPair().Address(s.Env()), nil
}