Skip to content

Commit

Permalink
loopout: add asset accounting
Browse files Browse the repository at this point in the history
  • Loading branch information
sputn1ck committed Jan 21, 2025
1 parent d7a05fb commit 0c599fc
Show file tree
Hide file tree
Showing 6 changed files with 921 additions and 682 deletions.
4 changes: 4 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ func (s *Client) FetchSwaps(ctx context.Context) ([]*SwapInfo, error) {
return nil, swap.ErrInvalidOutputType
}

if swp.Contract.AssetSwapInfo != nil {
swapInfo.AssetSwapInfo = swp.Contract.AssetSwapInfo
}

swaps = append(swaps, swapInfo)
}

Expand Down
39 changes: 32 additions & 7 deletions loopd/swapclient_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ func toWalletAddrType(addrType looprpc.AddressType) (walletrpc.AddressType,
}
}

func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
*looprpc.SwapStatus, error) {
func (s *swapClientServer) marshallSwap(ctx context.Context,
loopSwap *loop.SwapInfo) (*looprpc.SwapStatus, error) {

var (
state looprpc.SwapState
Expand Down Expand Up @@ -383,6 +383,7 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
)
var outGoingChanSet []uint64
var lastHop []byte
var assetInfo *looprpc.AssetLoopOutInfo

switch loopSwap.SwapType {
case swap.TypeIn:
Expand Down Expand Up @@ -413,6 +414,23 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (

outGoingChanSet = loopSwap.OutgoingChanSet

if loopSwap.AssetSwapInfo != nil {
assetName, err := s.assetClient.GetAssetName(
ctx, loopSwap.AssetSwapInfo.AssetId,
)
if err != nil {
return nil, err
}

assetInfo = &looprpc.AssetLoopOutInfo{
AssetId: hex.EncodeToString(loopSwap.AssetSwapInfo.AssetId), // nolint:lll
AssetCostOffchain: uint64(
loopSwap.AssetSwapInfo.PrepayPaidAmt +
loopSwap.AssetSwapInfo.SwapPaidAmt), // nolint:lll
AssetName: assetName,
}
}

default:
return nil, errors.New("unknown swap type")
}
Expand All @@ -435,6 +453,7 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
Label: loopSwap.Label,
LastHop: lastHop,
OutgoingChanSet: outGoingChanSet,
AssetInfo: assetInfo,
}, nil
}

Expand All @@ -445,7 +464,7 @@ func (s *swapClientServer) Monitor(in *looprpc.MonitorRequest,
log.Infof("Monitor request received")

send := func(info loop.SwapInfo) error {
rpcSwap, err := s.marshallSwap(&info)
rpcSwap, err := s.marshallSwap(server.Context(), &info)
if err != nil {
return err
}
Expand Down Expand Up @@ -540,7 +559,7 @@ func (s *swapClientServer) Monitor(in *looprpc.MonitorRequest,

// ListSwaps returns a list of all currently known swaps and their current
// status.
func (s *swapClientServer) ListSwaps(_ context.Context,
func (s *swapClientServer) ListSwaps(ctx context.Context,
req *looprpc.ListSwapsRequest) (*looprpc.ListSwapsResponse, error) {

var (
Expand All @@ -563,7 +582,7 @@ func (s *swapClientServer) ListSwaps(_ context.Context,
continue
}

rpcSwap, err := s.marshallSwap(&swp)
rpcSwap, err := s.marshallSwap(ctx, &swp)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -641,11 +660,17 @@ func filterSwap(swapInfo *loop.SwapInfo, filter *looprpc.ListSwapsFilter) bool {
}
}

// If we only want to return asset swaps, we only return swaps that have
// an asset id set.
if filter.AssetSwapOnly && swapInfo.AssetSwapInfo == nil {
return false
}

return true
}

// SwapInfo returns all known details about a single swap.
func (s *swapClientServer) SwapInfo(_ context.Context,
func (s *swapClientServer) SwapInfo(ctx context.Context,
req *looprpc.SwapInfoRequest) (*looprpc.SwapStatus, error) {

swapHash, err := lntypes.MakeHash(req.Id)
Expand All @@ -659,7 +684,7 @@ func (s *swapClientServer) SwapInfo(_ context.Context,
if !ok {
return nil, fmt.Errorf("swap with hash %s not found", req.Id)
}
return s.marshallSwap(&swp)
return s.marshallSwap(ctx, &swp)
}

// AbandonSwap requests the server to abandon a swap with the given hash.
Expand Down
56 changes: 50 additions & 6 deletions loopout.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"crypto/rand"
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
"math"
Expand Down Expand Up @@ -355,6 +356,10 @@ func (s *loopOutSwap) sendUpdate(ctx context.Context) error {
info.OutgoingChanSet = outgoingChanSet
}

if s.isAssetSwap() {
info.AssetSwapInfo = s.AssetSwapInfo
}

select {
case s.statusChan <- *info:
case <-ctx.Done():
Expand Down Expand Up @@ -436,7 +441,7 @@ func (s *loopOutSwap) executeAndFinalize(globalCtx context.Context) error {
case result := <-s.swapPaymentChan:
s.swapPaymentChan = nil

err := s.handlePaymentResult(result, true)
err := s.handlePaymentResult(globalCtx, result, true)
if err != nil {
return err
}
Expand All @@ -452,7 +457,7 @@ func (s *loopOutSwap) executeAndFinalize(globalCtx context.Context) error {
case result := <-s.prePaymentChan:
s.prePaymentChan = nil

err := s.handlePaymentResult(result, false)
err := s.handlePaymentResult(globalCtx, result, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -485,8 +490,8 @@ func (s *loopOutSwap) executeAndFinalize(globalCtx context.Context) error {
// handlePaymentResult processes the result of a payment attempt. If the
// payment was successful and this is the main swap payment, the cost of the
// swap is updated.
func (s *loopOutSwap) handlePaymentResult(result paymentResult,
swapPayment bool) error {
func (s *loopOutSwap) handlePaymentResult(ctx context.Context,
result paymentResult, swapPayment bool) error {

switch {
// If our result has a non-nil error, our status will be nil. In this
Expand All @@ -513,6 +518,17 @@ func (s *loopOutSwap) handlePaymentResult(result paymentResult,
// the swap payment and the prepay.
s.cost.Offchain += result.status.Fee.ToSatoshis()

// If this is an asset payment, we'll write the asset amounts
// to the swap.
if s.isAssetSwap() {
err := s.fillAssetOffchainPaymentResult(
ctx, result, swapPayment,
)
if err != nil {
return err
}
}

return nil

case result.status.State == lnrpc.Payment_FAILED:
Expand Down Expand Up @@ -1033,7 +1049,7 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
case result := <-s.swapPaymentChan:
s.swapPaymentChan = nil

err := s.handlePaymentResult(result, true)
err := s.handlePaymentResult(ctx, result, true)
if err != nil {
return nil, err
}
Expand All @@ -1055,7 +1071,7 @@ func (s *loopOutSwap) waitForConfirmedHtlc(globalCtx context.Context) (
case result := <-s.prePaymentChan:
s.prePaymentChan = nil

err := s.handlePaymentResult(result, false)
err := s.handlePaymentResult(ctx, result, false)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1456,6 +1472,34 @@ func (s *loopOutSwap) canSweep() bool {
return true
}

func (s *loopOutSwap) fillAssetOffchainPaymentResult(ctx context.Context,
result paymentResult, isSwapPayment bool) error {

if len(result.status.Htlcs) == 0 {
return fmt.Errorf("no htlcs in payment result")
}

// We only expect one htlc in the result.
htlc := result.status.Htlcs[0]

var assetData rfqmsg.JsonHtlc

err := json.Unmarshal(htlc.Route.CustomChannelData, &assetData)
if err != nil {
return err
}

assetSendAmt := btcutil.Amount(assetData.Balances[0].Amount)
if isSwapPayment {
s.AssetSwapInfo.SwapPaidAmt = assetSendAmt
log.Debugf("Asset off-chain payment success: %v", assetSendAmt)
} else {
s.AssetSwapInfo.PrepayPaidAmt = assetSendAmt
}

return s.store.UpdateLoopOutAssetInfo(ctx, s.hash, s.AssetSwapInfo)
}

// isAssetSwap returns true if the swap is an asset swap.
func (s *loopOutSwap) isAssetSwap() bool {
return s.AssetSwapInfo != nil
Expand Down
Loading

0 comments on commit 0c599fc

Please sign in to comment.