mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
013452cff0
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.
201 lines
4.1 KiB
Go
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
|
|
}
|