lnd/discovery/mock_test.go
Eugene Siegel 013452cff0
discovery: implement ChannelAnnouncement banning
This commit hooks up the banman to the gossiper:
- peers that are banned and don't have a channel with us will get
  disconnected until they are unbanned.
- peers that are banned and have a channel with us won't get
  disconnected, but we will ignore their channel announcements until
  they are no longer banned. Note that this only disables gossip of
  announcements to us and still allows us to open channels to them.
2024-08-27 14:11:06 -04:00

201 lines
4.1 KiB
Go

package discovery
import (
"errors"
"net"
"sync"
"sync/atomic"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/lnpeer"
"github.com/lightningnetwork/lnd/lnwire"
)
// mockPeer implements the lnpeer.Peer interface and is used to test the
// gossiper's interaction with peers.
type mockPeer struct {
pk *btcec.PublicKey
sentMsgs chan lnwire.Message
quit chan struct{}
disconnected atomic.Bool
}
var _ lnpeer.Peer = (*mockPeer)(nil)
func (p *mockPeer) SendMessage(_ bool, msgs ...lnwire.Message) error {
if p.sentMsgs == nil && p.quit == nil {
return nil
}
for _, msg := range msgs {
select {
case p.sentMsgs <- msg:
case <-p.quit:
return errors.New("peer disconnected")
}
}
return nil
}
func (p *mockPeer) SendMessageLazy(sync bool, msgs ...lnwire.Message) error {
return p.SendMessage(sync, msgs...)
}
func (p *mockPeer) AddNewChannel(_ *lnpeer.NewChannel,
_ <-chan struct{}) error {
return nil
}
func (p *mockPeer) WipeChannel(_ *wire.OutPoint) {}
func (p *mockPeer) IdentityKey() *btcec.PublicKey { return p.pk }
func (p *mockPeer) PubKey() [33]byte {
var pubkey [33]byte
copy(pubkey[:], p.pk.SerializeCompressed())
return pubkey
}
func (p *mockPeer) Address() net.Addr { return nil }
func (p *mockPeer) QuitSignal() <-chan struct{} {
return p.quit
}
func (p *mockPeer) LocalFeatures() *lnwire.FeatureVector {
return nil
}
func (p *mockPeer) RemoteFeatures() *lnwire.FeatureVector {
return nil
}
func (p *mockPeer) AddPendingChannel(_ lnwire.ChannelID,
_ <-chan struct{}) error {
return nil
}
func (p *mockPeer) RemovePendingChannel(_ lnwire.ChannelID) error {
return nil
}
func (p *mockPeer) Disconnect(err error) {
p.disconnected.Store(true)
}
// mockMessageStore is an in-memory implementation of the MessageStore interface
// used for the gossiper's unit tests.
type mockMessageStore struct {
sync.Mutex
messages map[[33]byte]map[lnwire.Message]struct{}
}
func newMockMessageStore() *mockMessageStore {
return &mockMessageStore{
messages: make(map[[33]byte]map[lnwire.Message]struct{}),
}
}
var _ GossipMessageStore = (*mockMessageStore)(nil)
func (s *mockMessageStore) AddMessage(msg lnwire.Message, pubKey [33]byte) error {
s.Lock()
defer s.Unlock()
if _, ok := s.messages[pubKey]; !ok {
s.messages[pubKey] = make(map[lnwire.Message]struct{})
}
s.messages[pubKey][msg] = struct{}{}
return nil
}
func (s *mockMessageStore) DeleteMessage(msg lnwire.Message, pubKey [33]byte) error {
s.Lock()
defer s.Unlock()
peerMsgs, ok := s.messages[pubKey]
if !ok {
return nil
}
delete(peerMsgs, msg)
return nil
}
func (s *mockMessageStore) Messages() (map[[33]byte][]lnwire.Message, error) {
s.Lock()
defer s.Unlock()
msgs := make(map[[33]byte][]lnwire.Message, len(s.messages))
for peer, peerMsgs := range s.messages {
for msg := range peerMsgs {
msgs[peer] = append(msgs[peer], msg)
}
}
return msgs, nil
}
func (s *mockMessageStore) Peers() (map[[33]byte]struct{}, error) {
s.Lock()
defer s.Unlock()
peers := make(map[[33]byte]struct{}, len(s.messages))
for peer := range s.messages {
peers[peer] = struct{}{}
}
return peers, nil
}
func (s *mockMessageStore) MessagesForPeer(pubKey [33]byte) ([]lnwire.Message, error) {
s.Lock()
defer s.Unlock()
peerMsgs, ok := s.messages[pubKey]
if !ok {
return nil, nil
}
msgs := make([]lnwire.Message, 0, len(peerMsgs))
for msg := range peerMsgs {
msgs = append(msgs, msg)
}
return msgs, nil
}
type mockScidCloser struct {
m map[lnwire.ShortChannelID]struct{}
channelPeer bool
sync.Mutex
}
func newMockScidCloser(channelPeer bool) *mockScidCloser {
return &mockScidCloser{
m: make(map[lnwire.ShortChannelID]struct{}),
channelPeer: channelPeer,
}
}
func (m *mockScidCloser) PutClosedScid(scid lnwire.ShortChannelID) error {
m.Lock()
m.m[scid] = struct{}{}
m.Unlock()
return nil
}
func (m *mockScidCloser) IsClosedScid(scid lnwire.ShortChannelID) (bool,
error) {
m.Lock()
defer m.Unlock()
_, ok := m.m[scid]
return ok, nil
}
func (m *mockScidCloser) IsChannelPeer(pubkey *btcec.PublicKey) (bool, error) {
return m.channelPeer, nil
}