Files
electronwall/main_test.go
2022-07-10 20:37:54 +02:00

373 lines
10 KiB
Go

package main
import (
"context"
"errors"
"testing"
"time"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/stretchr/testify/require"
)
type lndclientMock struct {
htlcEvents chan *routerrpc.HtlcEvent
htlcInterceptorRequests chan *routerrpc.ForwardHtlcInterceptRequest
htlcInterceptorResponses chan *routerrpc.ForwardHtlcInterceptResponse
channelEvents chan *lnrpc.ChannelEventUpdate
channelAcceptorRequests chan *lnrpc.ChannelAcceptRequest
channelAcceptorResponses chan *lnrpc.ChannelAcceptResponse
}
func newLndclientMock() *lndclientMock {
return &lndclientMock{
htlcEvents: make(chan *routerrpc.HtlcEvent),
htlcInterceptorRequests: make(chan *routerrpc.ForwardHtlcInterceptRequest),
htlcInterceptorResponses: make(chan *routerrpc.ForwardHtlcInterceptResponse),
channelAcceptorRequests: make(chan *lnrpc.ChannelAcceptRequest),
channelAcceptorResponses: make(chan *lnrpc.ChannelAcceptResponse),
}
}
// --------------- Channel events mocks ---------------
type channelAcceptorMock struct {
lnrpc.Lightning_ChannelAcceptorClient
channelAcceptorRequests chan *lnrpc.ChannelAcceptRequest
channelAcceptorResponses chan *lnrpc.ChannelAcceptResponse
}
func (lnd *lndclientMock) channelAcceptor(ctx context.Context) (
lnrpc.Lightning_ChannelAcceptorClient, error) {
return &channelAcceptorMock{
channelAcceptorRequests: lnd.channelAcceptorRequests,
channelAcceptorResponses: lnd.channelAcceptorResponses,
}, nil
}
func (c *channelAcceptorMock) RecvMsg(m interface{}) error {
req := <-c.channelAcceptorRequests
*m.(*lnrpc.ChannelAcceptRequest) = *req
return nil
}
func (c *channelAcceptorMock) Send(m *lnrpc.ChannelAcceptResponse) error {
c.channelAcceptorResponses <- m
return nil
}
type channelEventsMock struct {
lnrpc.Lightning_SubscribeChannelEventsClient
channelEvents chan *lnrpc.ChannelEventUpdate
}
func (h *channelEventsMock) Recv() (*lnrpc.ChannelEventUpdate, error) {
event := <-h.channelEvents
return event, nil
}
func (l *lndclientMock) subscribeChannelEvents(ctx context.Context,
in *lnrpc.ChannelEventSubscription) (
lnrpc.Lightning_SubscribeChannelEventsClient, error) {
return &channelEventsMock{
channelEvents: l.channelEvents,
}, nil
}
// --------------- Node info mocks ---------------
// getNodeInfo returns the information of a node given a pubKey
func (lnd *lndclientMock) getNodeInfo(ctx context.Context, pubkey string) (
nodeInfo *lnrpc.NodeInfo, err error) {
info := &lnrpc.NodeInfo{
Node: &lnrpc.LightningNode{
Alias: "alias-" + trimPubKey([]byte(pubkey)),
},
NumChannels: 2,
TotalCapacity: 1234,
}
return info, nil
}
// getNodeAlias returns the alias of a node pubkey
func (lnd *lndclientMock) getNodeAlias(ctx context.Context, pubkey string) (
string, error) {
info, err := lnd.getNodeInfo(ctx, pubkey)
if err != nil {
return "", err
}
if info.Node == nil {
return "", errors.New("node info not available")
}
return info.Node.Alias, nil
}
func (lnd *lndclientMock) getMyInfo(ctx context.Context) (
*lnrpc.GetInfoResponse, error) {
info := &lnrpc.GetInfoResponse{
IdentityPubkey: "my-pubkey-is-very-long-for-trimming-pubkey",
Alias: "my-alias",
}
return info, nil
}
func (lnd *lndclientMock) getPubKeyFromChannel(ctx context.Context, chan_id uint64) (
*lnrpc.ChannelEdge, error) {
return &lnrpc.ChannelEdge{
Node1Pub: "my-pubkey-is-very-long-for-trimming-pubkey",
Node2Pub: "other-pubkey-is-very-long-for-trimming-pubkey",
}, nil
}
// --------------- HTLC events mock ---------------
type htlcEventsMock struct {
routerrpc.Router_SubscribeHtlcEventsClient
htlcEvents chan *routerrpc.HtlcEvent
}
func (h *htlcEventsMock) Recv() (*routerrpc.HtlcEvent, error) {
event := <-h.htlcEvents
return event, nil
}
type htlcInterceptorMock struct {
routerrpc.Router_HtlcInterceptorClient
htlcInterceptorRequests chan *routerrpc.ForwardHtlcInterceptRequest
htlcInterceptorResponses chan *routerrpc.ForwardHtlcInterceptResponse
}
func (h *htlcInterceptorMock) Send(resp *routerrpc.ForwardHtlcInterceptResponse) error {
h.htlcInterceptorResponses <- resp
return nil
}
func (h *htlcInterceptorMock) Recv() (*routerrpc.ForwardHtlcInterceptRequest, error) {
event := <-h.htlcInterceptorRequests
return event, nil
}
func (l *lndclientMock) subscribeHtlcEvents(ctx context.Context,
in *routerrpc.SubscribeHtlcEventsRequest) (
routerrpc.Router_SubscribeHtlcEventsClient, error) {
return &htlcEventsMock{
htlcEvents: l.htlcEvents,
}, nil
}
func (l *lndclientMock) htlcInterceptor(ctx context.Context) (
routerrpc.Router_HtlcInterceptorClient, error) {
return &htlcInterceptorMock{
htlcInterceptorRequests: l.htlcInterceptorRequests,
htlcInterceptorResponses: l.htlcInterceptorResponses,
}, nil
}
func TestApp(t *testing.T) {
client := newLndclientMock()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
app := NewApp(ctx, client)
app.DispatchChannelAcceptor(ctx)
app.DispatchHTLCAcceptor(ctx)
time.Sleep(1 * time.Second)
cancel()
}
func TestHTLCDenylist(t *testing.T) {
client := newLndclientMock()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
app := NewApp(ctx, client)
Configuration.ForwardMode = "denylist"
Configuration.ForwardDenylist = []string{"700762x1327x1->690757x1005x1"}
app.DispatchHTLCAcceptor(ctx)
time.Sleep(1 * time.Second)
// should be denied
key := &routerrpc.CircuitKey{
ChanId: 770495967390531585,
HtlcId: 1337,
}
client.htlcInterceptorRequests <- &routerrpc.ForwardHtlcInterceptRequest{
IncomingCircuitKey: key,
OutgoingRequestedChanId: 759495353533530113,
}
resp := <-client.htlcInterceptorResponses
require.Equal(t, routerrpc.ResolveHoldForwardAction_FAIL, resp.Action)
client.htlcEvents <- &routerrpc.HtlcEvent{
EventType: routerrpc.HtlcEvent_FORWARD,
IncomingChannelId: key.ChanId,
IncomingHtlcId: key.HtlcId,
Event: &routerrpc.HtlcEvent_SettleEvent{},
}
// should be allowed
key = &routerrpc.CircuitKey{
ChanId: 123456789876543210,
HtlcId: 1337,
}
client.htlcInterceptorRequests <- &routerrpc.ForwardHtlcInterceptRequest{
IncomingCircuitKey: key,
OutgoingRequestedChanId: 9876543210123456543,
}
resp = <-client.htlcInterceptorResponses
require.Equal(t, routerrpc.ResolveHoldForwardAction_RESUME, resp.Action)
client.htlcEvents <- &routerrpc.HtlcEvent{
EventType: routerrpc.HtlcEvent_FORWARD,
IncomingChannelId: key.ChanId,
IncomingHtlcId: key.HtlcId,
Event: &routerrpc.HtlcEvent_SettleEvent{},
}
}
func TestHTLCAllowlist(t *testing.T) {
client := newLndclientMock()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
app := NewApp(ctx, client)
Configuration.ForwardMode = "allowlist"
Configuration.ForwardAllowlist = []string{"700762x1327x1->690757x1005x1"}
app.DispatchHTLCAcceptor(ctx)
time.Sleep(1 * time.Second)
// should be allowed
key := &routerrpc.CircuitKey{
ChanId: 770495967390531585,
HtlcId: 1337,
}
client.htlcInterceptorRequests <- &routerrpc.ForwardHtlcInterceptRequest{
IncomingCircuitKey: key,
OutgoingRequestedChanId: 759495353533530113,
}
resp := <-client.htlcInterceptorResponses
require.Equal(t, routerrpc.ResolveHoldForwardAction_RESUME, resp.Action)
client.htlcEvents <- &routerrpc.HtlcEvent{
EventType: routerrpc.HtlcEvent_FORWARD,
IncomingChannelId: key.ChanId,
IncomingHtlcId: key.HtlcId,
Event: &routerrpc.HtlcEvent_SettleEvent{},
}
// should be denied
key = &routerrpc.CircuitKey{
ChanId: 123456789876543210,
HtlcId: 1337,
}
client.htlcInterceptorRequests <- &routerrpc.ForwardHtlcInterceptRequest{
IncomingCircuitKey: key,
OutgoingRequestedChanId: 9876543210123456543,
}
resp = <-client.htlcInterceptorResponses
require.Equal(t, routerrpc.ResolveHoldForwardAction_FAIL, resp.Action)
client.htlcEvents <- &routerrpc.HtlcEvent{
EventType: routerrpc.HtlcEvent_FORWARD,
IncomingChannelId: key.ChanId,
IncomingHtlcId: key.HtlcId,
Event: &routerrpc.HtlcEvent_SettleEvent{},
}
}
func TestChannelAllowlist(t *testing.T) {
client := newLndclientMock()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
app := NewApp(ctx, client)
Configuration.ChannelMode = "allowlist"
Configuration.ChannelAllowlist = []string{"6d792d7075626b65792d69732d766572792d6c6f6e672d666f722d7472696d6d696e672d7075626b6579"}
app.DispatchChannelAcceptor(ctx)
time.Sleep(1 * time.Second)
// should be allowed
client.channelAcceptorRequests <- &lnrpc.ChannelAcceptRequest{
NodePubkey: []byte("my-pubkey-is-very-long-for-trimming-pubkey"),
FundingAmt: 1337,
PendingChanId: []byte("759495353533530113"),
}
resp := <-client.channelAcceptorResponses
require.Equal(t, resp.Accept, true)
// should be denied
client.channelAcceptorRequests <- &lnrpc.ChannelAcceptRequest{
NodePubkey: []byte("WRONG PUBKEY"),
FundingAmt: 1337,
PendingChanId: []byte("759495353533530113"),
}
resp = <-client.channelAcceptorResponses
require.Equal(t, resp.Accept, false)
}
func TestChannelDenylist(t *testing.T) {
client := newLndclientMock()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
app := NewApp(ctx, client)
Configuration.ChannelMode = "denylist"
Configuration.ChannelDenylist = []string{"6d792d7075626b65792d69732d766572792d6c6f6e672d666f722d7472696d6d696e672d7075626b6579"}
app.DispatchChannelAcceptor(ctx)
time.Sleep(1 * time.Second)
// should be denied
client.channelAcceptorRequests <- &lnrpc.ChannelAcceptRequest{
NodePubkey: []byte("my-pubkey-is-very-long-for-trimming-pubkey"),
FundingAmt: 1337,
PendingChanId: []byte("759495353533530113"),
}
resp := <-client.channelAcceptorResponses
require.Equal(t, resp.Accept, false)
// should be allowed
client.channelAcceptorRequests <- &lnrpc.ChannelAcceptRequest{
NodePubkey: []byte("WRONG PUBKEY"),
FundingAmt: 1337,
PendingChanId: []byte("759495353533530113"),
}
resp = <-client.channelAcceptorResponses
require.Equal(t, resp.Accept, true)
}