pool/clientdb/sidecar_test.go
2021-09-29 15:41:34 +02:00

208 lines
5.8 KiB
Go

package clientdb
import (
"testing"
"github.com/lightninglabs/pool/order"
"github.com/lightninglabs/pool/sidecar"
"github.com/stretchr/testify/require"
)
func assertSidecarExists(t *testing.T, db *DB, expected *sidecar.Ticket) {
t.Helper()
found, err := db.Sidecar(expected.ID, expected.Offer.SignPubKey)
require.NoError(t, err)
require.Equal(t, expected, found)
}
// TestSidecars ensures that all database operations involving sidecars run as
// expected.
func TestSidecars(t *testing.T) {
t.Parallel()
db, cleanup := newTestDB(t)
defer cleanup()
// Create a test sidecar we'll use to interact with the database.
s := &sidecar.Ticket{
ID: [8]byte{12, 34, 56},
State: sidecar.StateRegistered,
Offer: sidecar.Offer{
Capacity: 1000000,
PushAmt: 200000,
SignPubKey: testTraderKey,
LeaseDurationBlocks: 2016,
},
Recipient: &sidecar.Recipient{
MultiSigPubKey: testTraderKey,
MultiSigKeyIndex: 7,
},
}
// First, we'll add it to the database. We should be able to retrieve
// after.
err := db.AddSidecar(s)
require.NoError(t, err)
assertSidecarExists(t, db, s)
// Transition the sidecar state from SidecarInitialized to
// SidecarExpectingChannel and add the required information for that
// state.
s.State = sidecar.StateExpectingChannel
s.Order = &sidecar.Order{
BidNonce: order.Nonce{1, 2, 3},
}
err = db.UpdateSidecar(s)
require.NoError(t, err)
assertSidecarExists(t, db, s)
// Retrieving all sidecars should show that we only have one sidecar,
// the same one.
sidecars, err := db.Sidecars()
require.NoError(t, err)
require.Len(t, sidecars, 1)
require.Contains(t, sidecars, s)
// Make sure we can query a sidecar ticket by its ID and offer pubkey.
updatedTicket, err := db.Sidecar([8]byte{12, 34, 56}, testTraderKey)
require.NoError(t, err)
require.Equal(t, s, updatedTicket)
}
// TestSidecarsWithOrder tests that we're able to properly insert a new order
// into a sidecar sub-bucket along with the ticket, as well as retrieve it again
// in the future.
func TestSidecarsWithOrder(t *testing.T) {
t.Parallel()
db, cleanup := newTestDB(t)
defer cleanup()
// First, we'll make a new order that'll be matched along with a ticket
// we'll create below.
bid := &order.Bid{
Kit: *dummyOrder(500000, 1337),
MinNodeTier: 2,
SelfChanBalance: 123,
SidecarTicket: &sidecar.Ticket{
ID: [8]byte{11, 22, 33, 44, 55, 66, 77},
State: sidecar.StateRegistered,
Offer: sidecar.Offer{
Capacity: 1000000,
PushAmt: 200000,
LeaseDurationBlocks: 2016,
},
Recipient: &sidecar.Recipient{
MultiSigPubKey: testTraderKey,
MultiSigKeyIndex: 7,
},
},
}
bid.Details().MinUnitsMatch = 10
// Next we'll craft a new ticket that we'll use to bind to the base
// order.
ticket := &sidecar.Ticket{
ID: [8]byte{12, 34, 56},
State: sidecar.StateRegistered,
Offer: sidecar.Offer{
Capacity: 1000000,
PushAmt: 200000,
SignPubKey: testTraderKey,
LeaseDurationBlocks: 2016,
},
Recipient: &sidecar.Recipient{
MultiSigPubKey: testTraderKey,
MultiSigKeyIndex: 7,
},
}
err := db.AddSidecarWithBid(ticket, bid)
require.NoError(t, err)
assertSidecarExists(t, db, ticket)
// We should be able to retrieve the bid again given the original
// ticket.
diskBid, err := db.SidecarBidTemplate(ticket)
require.NoError(t, err)
// This bid should match the one we inserted earlier exactly.
require.Equal(t, diskBid, bid)
// Once we put the ticket into a final state, the bid template for it
// should be deleted.
ticket.State = sidecar.StateCanceled
err = db.UpdateSidecar(ticket)
require.NoError(t, err)
_, err = db.SidecarBidTemplate(ticket)
require.Equal(t, ErrNoOrder, err)
}
// TestSidecarsWithSameID makes sure that sidecar tickets with the same ID but
// different offer public keys can be stored and retrieved separately.
func TestSidecarsWithSameID(t *testing.T) {
t.Parallel()
db, cleanup := newTestDB(t)
defer cleanup()
// Create a test sidecar we'll use to interact with the database.
s := &sidecar.Ticket{
ID: [8]byte{12, 34, 56},
State: sidecar.StateRegistered,
Offer: sidecar.Offer{
Capacity: 1000000,
PushAmt: 200000,
SignPubKey: testTraderKey,
LeaseDurationBlocks: 2016,
},
Recipient: &sidecar.Recipient{
MultiSigPubKey: testTraderKey,
MultiSigKeyIndex: 7,
},
}
// First, we'll add it to the database. We should be able to retrieve
// after.
require.NoError(t, db.AddSidecar(s))
assertSidecarExists(t, db, s)
// Now we'll just store it again with the same ID but with a different
// offer public key. It shouldn't overwrite the original one but add a
// second ticket.
s.Offer.SignPubKey = testBatchKey
require.NoError(t, db.AddSidecar(s))
assertSidecarExists(t, db, s)
// Just to make sure the seek of the cursor works correctly, we also add
// two more tickets, both with different IDs.
s.ID = [8]byte{99, 88, 77}
require.NoError(t, db.AddSidecar(s))
assertSidecarExists(t, db, s)
s.ID = [8]byte{55, 44, 33}
require.NoError(t, db.AddSidecar(s))
assertSidecarExists(t, db, s)
// All four should be retrievable now, but just the first two when
// querying by the ID.
all, err := db.Sidecars()
require.NoError(t, err)
require.Len(t, all, 4)
byID, err := db.SidecarsByID([8]byte{12, 34, 56})
require.NoError(t, err)
require.Len(t, byID, 2)
for _, tkt := range byID {
require.Equal(t, [8]byte{12, 34, 56}, tkt.ID)
}
// The first ticket should be the one with the test batch public key
// that we added as the second ticket since its public key is lower than
// the test public key we used for the first ticket (because of the way
// the bbolt cursor works).
require.Equal(t, testBatchKey, byID[0].Offer.SignPubKey)
require.Equal(t, testTraderKey, byID[1].Offer.SignPubKey)
}