mirror of
https://github.com/lightninglabs/loop
synced 2024-11-08 01:10:29 +00:00
185 lines
5.6 KiB
Go
185 lines
5.6 KiB
Go
|
package loop
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/btcsuite/btcd/btcutil"
|
||
|
"github.com/lightninglabs/lndclient"
|
||
|
"github.com/lightninglabs/loop/loopdb"
|
||
|
"github.com/lightninglabs/loop/test"
|
||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
// TestCalculateLoopOutCost tests the CalculateLoopOutCost function.
|
||
|
func TestCalculateLoopOutCost(t *testing.T) {
|
||
|
// Set up test context objects.
|
||
|
lnd := test.NewMockLnd()
|
||
|
server := newServerMock(lnd)
|
||
|
store := loopdb.NewStoreMock(t)
|
||
|
|
||
|
cfg := &swapConfig{
|
||
|
lnd: &lnd.LndServices,
|
||
|
store: store,
|
||
|
server: server,
|
||
|
}
|
||
|
|
||
|
height := int32(600)
|
||
|
req := *testRequest
|
||
|
initResult, err := newLoopOutSwap(
|
||
|
context.Background(), cfg, height, &req,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
swap, err := store.FetchLoopOutSwap(
|
||
|
context.Background(), initResult.swap.hash,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Override the chain cost so it's negative.
|
||
|
const expectedChainCost = btcutil.Amount(1000)
|
||
|
|
||
|
// Now we have the swap and prepay invoices so let's calculate the
|
||
|
// costs without providing the payments first, so we don't account for
|
||
|
// any routing fees.
|
||
|
paymentFees := make(map[lntypes.Hash]lnwire.MilliSatoshi)
|
||
|
_, err = CalculateLoopOutCost(lnd.ChainParams, swap, paymentFees)
|
||
|
|
||
|
// We expect that the call fails as the swap isn't finished yet.
|
||
|
require.Error(t, err)
|
||
|
|
||
|
// Override the swap state to make it look like the swap is finished
|
||
|
// and make the chain cost negative too, so we can test that it'll be
|
||
|
// corrected to be positive in the cost calculation.
|
||
|
swap.Events = append(
|
||
|
swap.Events, &loopdb.LoopEvent{
|
||
|
SwapStateData: loopdb.SwapStateData{
|
||
|
State: loopdb.StateSuccess,
|
||
|
Cost: loopdb.SwapCost{
|
||
|
Onchain: -expectedChainCost,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
)
|
||
|
costs, err := CalculateLoopOutCost(lnd.ChainParams, swap, paymentFees)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
expectedServerCost := server.swapInvoiceAmt + server.prepayInvoiceAmt -
|
||
|
swap.Contract.AmountRequested
|
||
|
require.Equal(t, expectedServerCost, costs.Server)
|
||
|
require.Equal(t, btcutil.Amount(0), costs.Offchain)
|
||
|
require.Equal(t, expectedChainCost, costs.Onchain)
|
||
|
|
||
|
// Now add the two payments to the payments map and calculate the costs
|
||
|
// again. We expect that the routng fees are now accounted for.
|
||
|
paymentFees[server.swapHash] = lnwire.NewMSatFromSatoshis(44)
|
||
|
paymentFees[server.prepayHash] = lnwire.NewMSatFromSatoshis(11)
|
||
|
|
||
|
costs, err = CalculateLoopOutCost(lnd.ChainParams, swap, paymentFees)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
expectedOffchainCost := btcutil.Amount(44 + 11)
|
||
|
require.Equal(t, expectedServerCost, costs.Server)
|
||
|
require.Equal(t, expectedOffchainCost, costs.Offchain)
|
||
|
require.Equal(t, expectedChainCost, costs.Onchain)
|
||
|
|
||
|
// Now override the last update to make the swap timed out at the HTLC
|
||
|
// sweep. We expect that the chain cost won't change, and only the
|
||
|
// prepay will be accounted for.
|
||
|
swap.Events[0] = &loopdb.LoopEvent{
|
||
|
SwapStateData: loopdb.SwapStateData{
|
||
|
State: loopdb.StateFailSweepTimeout,
|
||
|
Cost: loopdb.SwapCost{
|
||
|
Onchain: 0,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
costs, err = CalculateLoopOutCost(lnd.ChainParams, swap, paymentFees)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
expectedServerCost = server.prepayInvoiceAmt
|
||
|
expectedOffchainCost = btcutil.Amount(11)
|
||
|
require.Equal(t, expectedServerCost, costs.Server)
|
||
|
require.Equal(t, expectedOffchainCost, costs.Offchain)
|
||
|
require.Equal(t, btcutil.Amount(0), costs.Onchain)
|
||
|
}
|
||
|
|
||
|
// TestCostMigration tests the cost migration for loop out swaps.
|
||
|
func TestCostMigration(t *testing.T) {
|
||
|
// Set up test context objects.
|
||
|
lnd := test.NewMockLnd()
|
||
|
server := newServerMock(lnd)
|
||
|
store := loopdb.NewStoreMock(t)
|
||
|
|
||
|
cfg := &swapConfig{
|
||
|
lnd: &lnd.LndServices,
|
||
|
store: store,
|
||
|
server: server,
|
||
|
}
|
||
|
|
||
|
height := int32(600)
|
||
|
req := *testRequest
|
||
|
initResult, err := newLoopOutSwap(
|
||
|
context.Background(), cfg, height, &req,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Override the chain cost so it's negative.
|
||
|
const expectedChainCost = btcutil.Amount(1000)
|
||
|
|
||
|
// Override the swap state to make it look like the swap is finished
|
||
|
// and make the chain cost negative too, so we can test that it'll be
|
||
|
// corrected to be positive in the cost calculation.
|
||
|
err = store.UpdateLoopOut(
|
||
|
context.Background(), initResult.swap.hash, time.Now(),
|
||
|
loopdb.SwapStateData{
|
||
|
State: loopdb.StateSuccess,
|
||
|
Cost: loopdb.SwapCost{
|
||
|
Onchain: -expectedChainCost,
|
||
|
},
|
||
|
},
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Add the two mocked payment to LND. Note that we only care about the
|
||
|
// fees here, so we don't need to provide the full payment details.
|
||
|
lnd.Payments = []lndclient.Payment{
|
||
|
{
|
||
|
Hash: server.swapHash,
|
||
|
Fee: lnwire.NewMSatFromSatoshis(44),
|
||
|
},
|
||
|
{
|
||
|
Hash: server.prepayHash,
|
||
|
Fee: lnwire.NewMSatFromSatoshis(11),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// Now we can run the migration.
|
||
|
err = MigrateLoopOutCosts(context.Background(), lnd.LndServices, store)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Finally check that the swap cost has been updated correctly.
|
||
|
swap, err := store.FetchLoopOutSwap(
|
||
|
context.Background(), initResult.swap.hash,
|
||
|
)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
expectedServerCost := server.swapInvoiceAmt + server.prepayInvoiceAmt -
|
||
|
swap.Contract.AmountRequested
|
||
|
|
||
|
costs := swap.Events[0].Cost
|
||
|
expectedOffchainCost := btcutil.Amount(44 + 11)
|
||
|
require.Equal(t, expectedServerCost, costs.Server)
|
||
|
require.Equal(t, expectedOffchainCost, costs.Offchain)
|
||
|
require.Equal(t, expectedChainCost, costs.Onchain)
|
||
|
|
||
|
// Now run the migration again to make sure it doesn't fail. This also
|
||
|
// indicates that the migration did not run the second time as
|
||
|
// otherwise the store mocks SetMigration function would fail.
|
||
|
err = MigrateLoopOutCosts(context.Background(), lnd.LndServices, store)
|
||
|
require.NoError(t, err)
|
||
|
}
|