mirror of
https://github.com/lightninglabs/loop
synced 2024-11-16 00:12:52 +00:00
435238ac03
We need the newer version of lndclient to get our synced to chain state. This requires changes to our test mock, so it is separated into a different commit. Since lndclient is expanding to be used in projects other than loop, the client interface is embedded in our mock rather than implementing functions we do not need. Functions that we already use in tests are updated accordingly. Note that while this commit bumps us to a version of lndclient that defaults to requiring lnd 0.11, we do not bump our required version yet because we are not using any new endpoints.
238 lines
6.0 KiB
Go
238 lines
6.0 KiB
Go
package test
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/btcsuite/btcutil"
|
|
"github.com/lightninglabs/lndclient"
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
|
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
"github.com/lightningnetwork/lnd/zpay32"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
type mockLightningClient struct {
|
|
lnd *LndMockServices
|
|
wg sync.WaitGroup
|
|
|
|
// Embed lndclient's interface so that lndclient can be expanded
|
|
// without the need to implement unused functions on the mock.
|
|
lndclient.LightningClient
|
|
}
|
|
|
|
// PayInvoice pays an invoice.
|
|
func (h *mockLightningClient) PayInvoice(ctx context.Context, invoice string,
|
|
maxFee btcutil.Amount,
|
|
outgoingChannel *uint64) chan lndclient.PaymentResult {
|
|
|
|
done := make(chan lndclient.PaymentResult, 1)
|
|
|
|
h.lnd.SendPaymentChannel <- PaymentChannelMessage{
|
|
PaymentRequest: invoice,
|
|
Done: done,
|
|
}
|
|
|
|
return done
|
|
}
|
|
|
|
func (h *mockLightningClient) WaitForFinished() {
|
|
h.wg.Wait()
|
|
}
|
|
|
|
func (h *mockLightningClient) ConfirmedWalletBalance(ctx context.Context) (
|
|
btcutil.Amount, error) {
|
|
|
|
return 1000000, nil
|
|
}
|
|
|
|
func (h *mockLightningClient) GetInfo(ctx context.Context) (*lndclient.Info,
|
|
error) {
|
|
|
|
pubKeyBytes, err := hex.DecodeString(h.lnd.NodePubkey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var pubKey [33]byte
|
|
copy(pubKey[:], pubKeyBytes)
|
|
return &lndclient.Info{
|
|
BlockHeight: 600,
|
|
IdentityPubkey: pubKey,
|
|
Uris: []string{h.lnd.NodePubkey + "@127.0.0.1:9735"},
|
|
}, nil
|
|
}
|
|
|
|
func (h *mockLightningClient) EstimateFeeToP2WSH(ctx context.Context,
|
|
amt btcutil.Amount, confTarget int32) (btcutil.Amount,
|
|
error) {
|
|
|
|
return 3000, nil
|
|
}
|
|
|
|
func (h *mockLightningClient) AddInvoice(ctx context.Context,
|
|
in *invoicesrpc.AddInvoiceData) (lntypes.Hash, string, error) {
|
|
|
|
h.lnd.lock.Lock()
|
|
defer h.lnd.lock.Unlock()
|
|
|
|
var hash lntypes.Hash
|
|
switch {
|
|
case in.Hash != nil:
|
|
hash = *in.Hash
|
|
case in.Preimage != nil:
|
|
hash = (*in.Preimage).Hash()
|
|
default:
|
|
if _, err := rand.Read(hash[:]); err != nil {
|
|
return lntypes.Hash{}, "", err
|
|
}
|
|
}
|
|
|
|
// Create and encode the payment request as a bech32 (zpay32) string.
|
|
creationDate := time.Now()
|
|
|
|
payReq, err := zpay32.NewInvoice(
|
|
h.lnd.ChainParams, hash, creationDate,
|
|
zpay32.Description(in.Memo),
|
|
zpay32.CLTVExpiry(in.CltvExpiry),
|
|
zpay32.Amount(in.Value),
|
|
)
|
|
if err != nil {
|
|
return lntypes.Hash{}, "", err
|
|
}
|
|
|
|
privKey, err := btcec.NewPrivateKey(btcec.S256())
|
|
if err != nil {
|
|
return lntypes.Hash{}, "", err
|
|
}
|
|
|
|
payReqString, err := payReq.Encode(
|
|
zpay32.MessageSigner{
|
|
SignCompact: func(hash []byte) ([]byte, error) {
|
|
// btcec.SignCompact returns a pubkey-recoverable signature
|
|
sig, err := btcec.SignCompact(
|
|
btcec.S256(), privKey, hash, true,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("can't sign the hash: %v", err)
|
|
}
|
|
|
|
return sig, nil
|
|
},
|
|
},
|
|
)
|
|
if err != nil {
|
|
return lntypes.Hash{}, "", err
|
|
}
|
|
|
|
// Add the invoice we have created to our mock's set of invoices.
|
|
h.lnd.Invoices[hash] = &lndclient.Invoice{
|
|
Preimage: nil,
|
|
Hash: hash,
|
|
PaymentRequest: payReqString,
|
|
Amount: in.Value,
|
|
CreationDate: creationDate,
|
|
State: channeldb.ContractOpen,
|
|
IsKeysend: false,
|
|
}
|
|
|
|
return hash, payReqString, nil
|
|
}
|
|
|
|
// LookupInvoice looks up an invoice in the mock's set of stored invoices.
|
|
// If it is not found, this call will fail. Note that these invoices should
|
|
// be settled using settleInvoice to have a preimage, settled state and settled
|
|
// date set.
|
|
func (h *mockLightningClient) LookupInvoice(_ context.Context,
|
|
hash lntypes.Hash) (*lndclient.Invoice, error) {
|
|
|
|
h.lnd.lock.Lock()
|
|
defer h.lnd.lock.Unlock()
|
|
|
|
inv, ok := h.lnd.Invoices[hash]
|
|
if !ok {
|
|
return nil, fmt.Errorf("invoice: %x not found", hash)
|
|
}
|
|
|
|
return inv, nil
|
|
}
|
|
|
|
// ListTransactions returns all known transactions of the backing lnd node.
|
|
func (h *mockLightningClient) ListTransactions(
|
|
_ context.Context, _, _ int32) ([]lndclient.Transaction, error) {
|
|
|
|
h.lnd.lock.Lock()
|
|
txs := h.lnd.Transactions
|
|
h.lnd.lock.Unlock()
|
|
|
|
return txs, nil
|
|
}
|
|
|
|
// ListChannels retrieves all channels of the backing lnd node.
|
|
func (h *mockLightningClient) ListChannels(ctx context.Context) (
|
|
[]lndclient.ChannelInfo, error) {
|
|
|
|
return h.lnd.Channels, nil
|
|
}
|
|
|
|
// ClosedChannels returns a list of our closed channels.
|
|
func (h *mockLightningClient) ClosedChannels(_ context.Context) ([]lndclient.ClosedChannel,
|
|
error) {
|
|
|
|
return h.lnd.ClosedChannels, nil
|
|
}
|
|
|
|
// ForwardingHistory returns the mock's set of forwarding events.
|
|
func (h *mockLightningClient) ForwardingHistory(_ context.Context,
|
|
_ lndclient.ForwardingHistoryRequest) (*lndclient.ForwardingHistoryResponse,
|
|
error) {
|
|
|
|
return &lndclient.ForwardingHistoryResponse{
|
|
LastIndexOffset: 0,
|
|
Events: h.lnd.ForwardingEvents,
|
|
}, nil
|
|
}
|
|
|
|
// ListInvoices returns our mock's invoices.
|
|
func (h *mockLightningClient) ListInvoices(_ context.Context,
|
|
_ lndclient.ListInvoicesRequest) (*lndclient.ListInvoicesResponse,
|
|
error) {
|
|
|
|
invoices := make([]lndclient.Invoice, 0, len(h.lnd.Invoices))
|
|
for _, invoice := range h.lnd.Invoices {
|
|
invoices = append(invoices, *invoice)
|
|
}
|
|
|
|
return &lndclient.ListInvoicesResponse{
|
|
Invoices: invoices,
|
|
}, nil
|
|
}
|
|
|
|
// ListPayments makes a paginated call to our list payments endpoint.
|
|
func (h *mockLightningClient) ListPayments(_ context.Context,
|
|
_ lndclient.ListPaymentsRequest) (*lndclient.ListPaymentsResponse,
|
|
error) {
|
|
|
|
return &lndclient.ListPaymentsResponse{
|
|
Payments: h.lnd.Payments,
|
|
}, nil
|
|
}
|
|
|
|
// ChannelBackup retrieves the backup for a particular channel. The
|
|
// backup is returned as an encrypted chanbackup.Single payload.
|
|
func (h *mockLightningClient) ChannelBackup(context.Context, wire.OutPoint) ([]byte, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// ChannelBackups retrieves backups for all existing pending open and
|
|
// open channels. The backups are returned as an encrypted
|
|
// chanbackup.Multi payload.
|
|
func (h *mockLightningClient) ChannelBackups(ctx context.Context) ([]byte, error) {
|
|
return nil, nil
|
|
}
|