Skip to content

Commit

Permalink
Merge pull request lightninglabs#327 from lightninglabs/sidecar-crud-…
Browse files Browse the repository at this point in the history
…itest

itest: add test for sidecar cancellation
  • Loading branch information
guggero authored Sep 30, 2021
2 parents 16ee4b9 + e7d4094 commit 9a8eaa2
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 34 deletions.
11 changes: 10 additions & 1 deletion admin_rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net"
"sync"
"sync/atomic"
"time"

"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg"
Expand All @@ -33,6 +34,12 @@ import (
"google.golang.org/grpc"
)

var (
// defaultLeaseDuration is the default lease duration we use for locking
// additional inputs to our batch.
defaultLeaseDuration = time.Minute * 10
)

// adminRPCServer is a server that implements the admin server RPC interface and
// serves administrative and super user content.
type adminRPCServer struct {
Expand Down Expand Up @@ -1077,7 +1084,9 @@ func (s *adminRPCServer) MoveFunds(ctx context.Context,
}

for i, in := range io.Inputs {
_, err := s.wallet.LeaseOutput(ctx, s.lockID, in.PrevOutPoint)
_, err := s.wallet.LeaseOutput(
ctx, s.lockID, in.PrevOutPoint, defaultLeaseDuration,
)
if err != nil {
releaseOutputs(i)
return nil, fmt.Errorf("unable to lease output %v: %v",
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ require (
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/jessevdk/go-flags v1.4.0
github.com/lightninglabs/aperture v0.1.9-beta.0.20210730071214-beed396b0ef6
github.com/lightninglabs/lndclient v0.12.0-9
github.com/lightninglabs/pool v0.5.1-alpha
github.com/lightninglabs/lndclient v0.13.0-7
github.com/lightninglabs/pool v0.5.1-alpha.0.20210930001328-53df9a308491
github.com/lightninglabs/pool/auctioneerrpc v1.0.3
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210728112744-ebabda671786
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210802115842-44971f0c46c9
github.com/lightningnetwork/lnd/cert v1.0.3
github.com/lightningnetwork/lnd/ticker v1.0.0
github.com/prometheus/client_golang v1.11.0
Expand Down
11 changes: 6 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -400,16 +400,16 @@ github.com/lightninglabs/aperture v0.1.9-beta.0.20210730071214-beed396b0ef6/go.m
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc=
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
github.com/lightninglabs/lndclient v0.11.0-4/go.mod h1:8/cTKNwgL87NX123gmlv3Xh6p1a7pvzu+40Un3PhHiI=
github.com/lightninglabs/lndclient v0.12.0-8/go.mod h1:L0R2VOaLxMylGbxgnfiZGc0hMDIIgj91cfgwGuFz9kU=
github.com/lightninglabs/lndclient v0.12.0-9 h1:w5Ozl74o7hJElxSk4hRu2enCNzdJfshDbJsJzhBaI3I=
github.com/lightninglabs/lndclient v0.12.0-9/go.mod h1:L0R2VOaLxMylGbxgnfiZGc0hMDIIgj91cfgwGuFz9kU=
github.com/lightninglabs/lndclient v0.13.0-7 h1:diIMNzbe8pMF1jf6tysOLLkeo1Q6KzyQNsNvLs+g3xg=
github.com/lightninglabs/lndclient v0.13.0-7/go.mod h1:Ia/UARBUq9Y8CCegm/Nrdi/z+NZsH85JzxetAdnC37Q=
github.com/lightninglabs/neutrino v0.11.0/go.mod h1:CuhF0iuzg9Sp2HO6ZgXgayviFTn1QHdSTJlMncK80wg=
github.com/lightninglabs/neutrino v0.11.1-0.20200316235139-bffc52e8f200/go.mod h1:MlZmoKa7CJP3eR1s5yB7Rm5aSyadpKkxqAwLQmog7N0=
github.com/lightninglabs/neutrino v0.11.1-0.20201210023533-e1978372d15e/go.mod h1:KDWfQDKp+CFBxO1t2NRmWuagTY2sYIjpHB1k5vrojTI=
github.com/lightninglabs/neutrino v0.12.1 h1:9umzk5kKNc/l3bAyak8ClSRP1qSulnjc6kppLYDnuqk=
github.com/lightninglabs/neutrino v0.12.1/go.mod h1:GlKninWpRBbL7b8G0oQ36/8downfnFwKsr0hbRA6E/E=
github.com/lightninglabs/pool v0.5.1-alpha h1:9JpH5nclgqMgK6m03lkEakLhh/Q1kCgeFp+TtjmUuHc=
github.com/lightninglabs/pool v0.5.1-alpha/go.mod h1:eR+h308Vxf6UK5UbVJsnSYo7ygO6ouONCKg8rS4V2Ss=
github.com/lightninglabs/pool v0.5.1-alpha.0.20210930001328-53df9a308491 h1:Isx7ObvpmpqQPcEsx9P1Pro5csi1WjUaEPq8RkLluMs=
github.com/lightninglabs/pool v0.5.1-alpha.0.20210930001328-53df9a308491/go.mod h1:l8eNmAeT50mu6mzkvOMDZAztmoGpgEew06uqvxyoslg=
github.com/lightninglabs/protobuf-hex-display v1.3.3-0.20191212020323-b444784ce75d/go.mod h1:KDb67YMzoh4eudnzClmvs2FbiLG9vxISmLApUkCa4uI=
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display h1:RZJ8H4ueU/aQ9pFtx5wqsuD3B/DezrewJeVwDKKYY8E=
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display/go.mod h1:2oKOBU042GKFHrdbgGiKax4xVrFiZu51lhacUZQ9MnE=
Expand All @@ -419,8 +419,9 @@ github.com/lightningnetwork/lightning-onion v1.0.2-0.20210520211913-522b799e65b1
github.com/lightningnetwork/lnd v0.11.0-beta/go.mod h1:CzArvT7NFDLhVyW06+NJWSuWFmE6Ea+AjjA3txUBqTM=
github.com/lightningnetwork/lnd v0.11.1-beta/go.mod h1:PGIgxy8aH70Li33YVYkHSaCM8m8LjEevk5h1Dpldrr4=
github.com/lightningnetwork/lnd v0.12.0-beta/go.mod h1:2GyP1IG1kXV5Af/LOCxnXfux1OP3fAGr8zptS5PB2YI=
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210728112744-ebabda671786 h1:DOZ16XjuSJgmgV0jXYcagxg19fRgad3DbzpNNkWuOsk=
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210728112744-ebabda671786/go.mod h1:3cmukt9wR4PX1va9Q78gmqSPYd6yhV1wcFemM5F+kT8=
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210802115842-44971f0c46c9 h1:kFyyJRNFAUnQl5G7b3stUF2KIfdUJu/KCKXvPlBJqNA=
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210802115842-44971f0c46c9/go.mod h1:3cmukt9wR4PX1va9Q78gmqSPYd6yhV1wcFemM5F+kT8=
github.com/lightningnetwork/lnd/cert v1.0.2/go.mod h1:fmtemlSMf5t4hsQmcprSoOykypAPp+9c+0d0iqTScMo=
github.com/lightningnetwork/lnd/cert v1.0.3 h1:/K2gjzLgVI8we2IIPKc0ztWTEa85uds5sWXi1K6mOT0=
github.com/lightningnetwork/lnd/cert v1.0.3/go.mod h1:3MWXVLLPI0Mg0XETm9fT4N9Vyy/8qQLmaM5589bEggM=
Expand Down
2 changes: 1 addition & 1 deletion internal/test/walletkit_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (m *MockWalletKit) ListUnspent(context.Context, int32,
}

func (m *MockWalletKit) LeaseOutput(context.Context, wtxmgr.LockID,
wire.OutPoint) (time.Time, error) {
wire.OutPoint, time.Duration) (time.Time, error) {

return time.Now(), nil
}
Expand Down
3 changes: 1 addition & 2 deletions itest/self_chan_balance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ func testSelfChanBalance(t *harnessTest) {
t.lndHarness.SendCoins(ctx, t.t, 5_000_000, charlie)

// Create an account over 2M sats that is valid for the next 1000 blocks
// for both traders. To test the message multi-plexing between token IDs
// and accounts, we add a secondary account to the second trader.
// for both traders.
makerAccount := openAccountAndAssert(
t, t.trader, &poolrpc.InitAccountRequest{
AccountValue: defaultAccountValue,
Expand Down
186 changes: 169 additions & 17 deletions itest/sidecar_channels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"testing"

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
Expand Down Expand Up @@ -37,8 +38,7 @@ func sidecarChannelsHappyPath(ctx context.Context, t *harnessTest, auto bool) {
defer shutdownAndAssert(t, dave, recipientTrader)

// Create an account over 2M sats that is valid for the next 1000 blocks
// for both traders. To test the message multi-plexing between token IDs
// and accounts, we add a secondary account to the second trader.
// for both traders.
makerAccount := openAccountAndAssert(
t, t.trader, &poolrpc.InitAccountRequest{
AccountValue: defaultAccountValue,
Expand Down Expand Up @@ -73,7 +73,7 @@ func sidecarChannelsHappyPath(ctx context.Context, t *harnessTest, auto bool) {

// Create the sidecar channel ticket now, including the offer, order and
// channel expectation.
firstSidecarBid := makeSidecar(
firstSidecarBid, _ := makeSidecar(
t, providerTrader, recipientTrader, providerAccount.TraderKey,
orderFixedRate, askAmt, selfChanBalance, auto,
)
Expand Down Expand Up @@ -178,7 +178,7 @@ func sidecarChannelsHappyPath(ctx context.Context, t *harnessTest, auto bool) {

// Create the sidecar channel ticket now, including the offer, order and
// channel expectation.
secondSidecarBid := makeSidecar(
secondSidecarBid, _ := makeSidecar(
t, providerTrader, recipientTrader, providerAccount.TraderKey,
orderFixedRate, askAmt, 0, auto,
)
Expand Down Expand Up @@ -262,8 +262,7 @@ func testSidecarChannelsRejectNewNodesOnly(t *harnessTest) {
defer shutdownAndAssert(t, dave, recipientTrader)

// Create an account over 2M sats that is valid for the next 1000 blocks
// for both traders. To test the message multi-plexing between token IDs
// and accounts, we add a secondary account to the second trader.
// for both traders.
makerAccount := openAccountAndAssert(
t, t.trader, &poolrpc.InitAccountRequest{
AccountValue: defaultAccountValue,
Expand Down Expand Up @@ -307,7 +306,7 @@ func testSidecarChannelsRejectNewNodesOnly(t *harnessTest) {

// Create the sidecar channel ticket now, including the offer, order and
// channel expectation.
firstSidecarBid := makeSidecar(
firstSidecarBid, _ := makeSidecar(
t, providerTrader, recipientTrader, providerAccount.TraderKey,
orderFixedRate, askAmt, 0, false,
)
Expand Down Expand Up @@ -368,8 +367,7 @@ func testSidecarChannelsRejectMinChanSize(t *harnessTest) {
defer shutdownAndAssert(t, dave, recipientTrader)

// Create an account over 2M sats that is valid for the next 1000 blocks
// for both traders. To test the message multi-plexing between token IDs
// and accounts, we add a secondary account to the second trader.
// for both traders.
makerAccount := openAccountAndAssert(
t, t.trader, &poolrpc.InitAccountRequest{
AccountValue: defaultAccountValue,
Expand Down Expand Up @@ -424,13 +422,141 @@ func testSidecarChannelsRejectMinChanSize(t *harnessTest) {
_, _ = executeBatch(t, 0)
}

// testSidecarTicketCancellation makes sure sidecar tickets can be canceled in
// the various states they can be in during their lifecycle.
func testSidecarTicketCancellation(t *harnessTest) {
ctx := context.Background()

// We need a third and fourth lnd node for the additional participants.
// Charlie is the sidecar channel provider (has an account, submits the
// bid order) and Dave is the sidecar channel recipient (has no account
// and only receives the channel).
charlie := t.lndHarness.NewNode(t.t, "charlie", nil)
providerTrader := setupTraderHarness(
t.t, t.lndHarness.BackendCfg, charlie, t.auctioneer,
)
defer shutdownAndAssert(t, charlie, providerTrader)
t.lndHarness.SendCoins(ctx, t.t, 5_000_000, charlie)

dave := t.lndHarness.NewNode(t.t, "dave", nil)
recipientTrader := setupTraderHarness(
t.t, t.lndHarness.BackendCfg, dave, t.auctioneer,
)
defer shutdownAndAssert(t, dave, recipientTrader)

// Create an account over 2M sats that is valid for the next 1000 blocks
// for both traders.
makerAccount := openAccountAndAssert(
t, t.trader, &poolrpc.InitAccountRequest{
AccountValue: defaultAccountValue,
AccountExpiry: &poolrpc.InitAccountRequest_RelativeHeight{
RelativeHeight: 1_000,
},
},
)
providerAccount := openAccountAndAssert(
t, providerTrader, &poolrpc.InitAccountRequest{
AccountValue: defaultAccountValue,
AccountExpiry: &poolrpc.InitAccountRequest_RelativeHeight{
RelativeHeight: 1_000,
},
},
)

// Now that the accounts are confirmed, submit an ask order from our
// maker, selling 200 units (200k sats) of liquidity.
const (
orderFixedRate = 100
askAmt = 200_000
selfChanBalance = 100_000
)
_, err := submitAskOrder(
t.trader, makerAccount.TraderKey, orderFixedRate, askAmt,
func(ask *poolrpc.SubmitOrderRequest_Ask) {
ask.Ask.Version = uint32(orderT.VersionSidecarChannel)
},
)
require.NoError(t.t, err)

// Create an offer from the provider account.
offerResp, err := providerTrader.OfferSidecar(
ctx, &poolrpc.OfferSidecarRequest{
AutoNegotiate: false,
Bid: &poolrpc.Bid{
Details: &poolrpc.Order{
TraderKey: providerAccount.TraderKey,
Amt: uint64(askAmt),
},
SelfChanBalance: selfChanBalance,
LeaseDurationBlocks: defaultOrderDuration,
},
},
)
require.NoError(t.t, err)

offeredTicket, err := sidecar.DecodeString(offerResp.Ticket)
require.NoError(t.t, err)

// The offer should now be listed and in the correct state.
assertSidecarState(
t.t, providerTrader, 1, offeredTicket.ID[:],
offeredTicket.State,
)

// Let's cancel the ticket.
_, err = providerTrader.CancelSidecar(
ctx, &poolrpc.CancelSidecarRequest{
SidecarId: offeredTicket.ID[:],
},
)
require.NoError(t.t, err)

// Make sure the state is properly reflected.
assertSidecarState(
t.t, providerTrader, 1, offeredTicket.ID[:],
sidecar.StateCanceled,
)

// Create a full sidecar channel ticket now, including the offer, order
// and channel expectation. Then we cancel it on the offer side and
// check that the order is canceled as well.
sidecarBid, ticketID := makeSidecar(
t, providerTrader, recipientTrader, providerAccount.TraderKey,
orderFixedRate, askAmt, 0, true,
)
assertSidecarState(
t.t, providerTrader, 2, ticketID, sidecar.StateExpectingChannel,
)
assertSidecarState(
t.t, recipientTrader, 1, ticketID,
sidecar.StateExpectingChannel,
)

// Let's cancel the ticket.
_, err = providerTrader.CancelSidecar(
ctx, &poolrpc.CancelSidecarRequest{
SidecarId: ticketID,
},
)
require.NoError(t.t, err)
assertSidecarState(
t.t, providerTrader, 2, ticketID, sidecar.StateCanceled,
)

// The order should be canceled as well.
assertBidOrderState(
t, providerTrader, sidecarBid,
auctioneerrpc.OrderState_ORDER_CANCELED,
)
}

// makeSidecar creates a sidecar ticket with an offer on the provider node,
// registers the offer with the recipient node, creates a bid order for the
// provider and finally adds the channel expectation to the recipient's node.
func makeSidecar(t *harnessTest, providerTrader, recipientTrader *traderHarness,
providerAccountKey []byte, orderFixedRate uint32, // nolint:unparam
askAmt btcutil.Amount, selfChanBalance uint64, // nolint:unparam
auto bool) orderT.Nonce { // nolint:unparam
auto bool) (orderT.Nonce, []byte) {

ctx := context.Background()

Expand Down Expand Up @@ -479,6 +605,8 @@ func makeSidecar(t *harnessTest, providerTrader, recipientTrader *traderHarness,
},
)
require.NoError(t.t, err)
registeredTicket, err := sidecar.DecodeString(registerResp.Ticket)
require.NoError(t.t, err)

// If we're using automated negotiation, then the last two steps will
// be done automatically, so we can exit here.
Expand All @@ -488,18 +616,13 @@ func makeSidecar(t *harnessTest, providerTrader, recipientTrader *traderHarness,
if auto {
// If this is an auto negotiated sidecar ticket, then we'll
// wait for the sidecar responder to connect as a new trader.
registeredTicket, err := sidecar.DecodeString(
registerResp.Ticket,
)
require.NoError(t.t, err)

assertSidecarTraderSubscribed(
t, registeredTicket.Recipient.MultiSigPubKey,
)

var bidNonce orderT.Nonce
copy(bidNonce[:], registeredTicket.Order.BidNonce[:])
return bidNonce
return bidNonce, registeredTicket.ID[:]
}

// Step 3/4 is for the provider to submit a bid order referencing the
Expand Down Expand Up @@ -534,7 +657,7 @@ func makeSidecar(t *harnessTest, providerTrader, recipientTrader *traderHarness,
)
require.NoError(t.t, err)

return bidNonce
return bidNonce, registeredTicket.ID[:]
}

// assertSidecarLease makes sure that the leased sidecar channel can be found
Expand Down Expand Up @@ -629,3 +752,32 @@ func remoteActiveBalanceCheck(balance int64) activeChanCheck {
return nil
}
}

// assertSidecarState asserts the number of sidecar tickets and the state of a
// single ticket within the list.
func assertSidecarState(t *testing.T, trader *traderHarness, numTickets int,
id []byte, state sidecar.State) {

t.Helper()

sidecars, err := trader.ListSidecars(
context.Background(), &poolrpc.ListSidecarsRequest{},
)
require.NoError(t, err)
require.Len(t, sidecars.Tickets, numTickets)

found := false
for _, ticket := range sidecars.Tickets {
if !bytes.Equal(ticket.Id, id) {
continue
}

found = true
require.Equal(t, state.String(), ticket.State)
break
}

if !found {
require.Fail(t, "ticket with ID %x not found", id)
}
}
Loading

0 comments on commit 9a8eaa2

Please sign in to comment.