2019-03-06 20:13:50 +00:00
|
|
|
package test
|
|
|
|
|
|
|
|
import (
|
2019-03-12 15:10:37 +00:00
|
|
|
"crypto/rand"
|
2019-12-09 15:33:33 +00:00
|
|
|
"encoding/hex"
|
2019-03-06 20:13:50 +00:00
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/btcsuite/btcd/btcec"
|
2019-12-10 00:16:41 +00:00
|
|
|
"github.com/btcsuite/btcd/wire"
|
2019-03-06 20:13:50 +00:00
|
|
|
"github.com/btcsuite/btcutil"
|
2019-03-06 23:29:44 +00:00
|
|
|
"github.com/lightninglabs/loop/lndclient"
|
2020-05-20 11:42:20 +00:00
|
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
2019-03-06 20:13:50 +00:00
|
|
|
"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
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
2019-03-12 15:10:37 +00:00
|
|
|
Done: done,
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
2019-12-09 15:33:33 +00:00
|
|
|
pubKeyBytes, err := hex.DecodeString(h.lnd.NodePubkey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-03-06 20:13:50 +00:00
|
|
|
var pubKey [33]byte
|
2019-12-09 15:33:33 +00:00
|
|
|
copy(pubKey[:], pubKeyBytes)
|
2019-03-06 20:13:50 +00:00
|
|
|
return &lndclient.Info{
|
|
|
|
BlockHeight: 600,
|
|
|
|
IdentityPubkey: pubKey,
|
2019-12-09 15:33:33 +00:00
|
|
|
Uris: []string{h.lnd.NodePubkey + "@127.0.0.1:9735"},
|
2019-03-06 20:13:50 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-03-12 15:10:37 +00:00
|
|
|
func (h *mockLightningClient) EstimateFeeToP2WSH(ctx context.Context,
|
|
|
|
amt btcutil.Amount, confTarget int32) (btcutil.Amount,
|
|
|
|
error) {
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-03-12 15:10:37 +00:00
|
|
|
return 3000, nil
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2019-03-12 15:10:37 +00:00
|
|
|
switch {
|
|
|
|
case in.Hash != nil:
|
2019-03-06 20:13:50 +00:00
|
|
|
hash = *in.Hash
|
2019-03-12 15:10:37 +00:00
|
|
|
case in.Preimage != nil:
|
2019-03-06 20:13:50 +00:00
|
|
|
hash = (*in.Preimage).Hash()
|
2019-03-12 15:10:37 +00:00
|
|
|
default:
|
|
|
|
if _, err := rand.Read(hash[:]); err != nil {
|
|
|
|
return lntypes.Hash{}, "", err
|
|
|
|
}
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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),
|
2019-12-03 09:42:01 +00:00
|
|
|
zpay32.Amount(in.Value),
|
2019-03-06 20:13:50 +00:00
|
|
|
)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-20 11:42:20 +00:00
|
|
|
// 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,
|
|
|
|
}
|
|
|
|
|
2019-03-06 20:13:50 +00:00
|
|
|
return hash, payReqString, nil
|
|
|
|
}
|
2019-12-10 00:16:41 +00:00
|
|
|
|
2020-05-20 11:42:20 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2019-12-10 00:16:41 +00:00
|
|
|
// ListTransactions returns all known transactions of the backing lnd node.
|
|
|
|
func (h *mockLightningClient) ListTransactions(
|
|
|
|
ctx context.Context) ([]*wire.MsgTx, error) {
|
|
|
|
|
|
|
|
h.lnd.lock.Lock()
|
|
|
|
txs := h.lnd.Transactions
|
|
|
|
h.lnd.lock.Unlock()
|
|
|
|
return txs, nil
|
|
|
|
}
|
2020-01-31 20:41:18 +00:00
|
|
|
|
2020-05-18 14:23:02 +00:00
|
|
|
// ListChannels retrieves all channels of the backing lnd node.
|
|
|
|
func (h *mockLightningClient) ListChannels(ctx context.Context) (
|
|
|
|
[]lndclient.ChannelInfo, error) {
|
|
|
|
|
|
|
|
return h.lnd.Channels, nil
|
|
|
|
}
|
|
|
|
|
2020-01-31 20:41:18 +00:00
|
|
|
// 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
|
|
|
|
}
|