zcash: move blacklist management to address book
This commit is contained in:
parent
a01f5196b7
commit
28d329c835
|
@ -12,7 +12,6 @@ import (
|
||||||
|
|
||||||
type Address struct {
|
type Address struct {
|
||||||
netaddr *wire.NetAddress
|
netaddr *wire.NetAddress
|
||||||
blacklisted bool
|
|
||||||
lastUpdate time.Time
|
lastUpdate time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +43,6 @@ func (a *Address) fromPeerKey(s PeerKey) (*Address, error) {
|
||||||
)
|
)
|
||||||
|
|
||||||
a.netaddr = na
|
a.netaddr = na
|
||||||
a.blacklisted = false
|
|
||||||
a.lastUpdate = na.Timestamp
|
a.lastUpdate = na.Timestamp
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
@ -57,7 +55,6 @@ func (a *Address) asNetAddress() *wire.NetAddress {
|
||||||
|
|
||||||
func (a *Address) fromNetAddress(na *wire.NetAddress) (*Address, error) {
|
func (a *Address) fromNetAddress(na *wire.NetAddress) (*Address, error) {
|
||||||
a.netaddr = na
|
a.netaddr = na
|
||||||
a.blacklisted = false
|
|
||||||
a.lastUpdate = na.Timestamp
|
a.lastUpdate = na.Timestamp
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
@ -67,14 +64,17 @@ func (a *Address) MarshalText() (text []byte, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressBook struct {
|
type AddressBook struct {
|
||||||
addrs map[PeerKey]*Address
|
peers map[PeerKey]*Address
|
||||||
|
blacklist map[PeerKey]*Address
|
||||||
|
|
||||||
addrState sync.RWMutex
|
addrState sync.RWMutex
|
||||||
addrRecvCond *sync.Cond
|
addrRecvCond *sync.Cond
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAddressBook() *AddressBook {
|
func NewAddressBook() *AddressBook {
|
||||||
addrBook := &AddressBook{
|
addrBook := &AddressBook{
|
||||||
addrs: make(map[PeerKey]*Address),
|
peers: make(map[PeerKey]*Address),
|
||||||
|
blacklist: make(map[PeerKey]*Address),
|
||||||
}
|
}
|
||||||
addrBook.addrRecvCond = sync.NewCond(&addrBook.addrState)
|
addrBook.addrRecvCond = sync.NewCond(&addrBook.addrState)
|
||||||
return addrBook
|
return addrBook
|
||||||
|
@ -88,7 +88,7 @@ func (bk *AddressBook) Add(s PeerKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bk.addrState.Lock()
|
bk.addrState.Lock()
|
||||||
bk.addrs[s] = newAddr
|
bk.peers[s] = newAddr
|
||||||
bk.addrState.Unlock()
|
bk.addrState.Unlock()
|
||||||
|
|
||||||
// Wake anyone who was waiting on us to receive an address.
|
// Wake anyone who was waiting on us to receive an address.
|
||||||
|
@ -99,8 +99,8 @@ func (bk *AddressBook) Remove(s PeerKey) {
|
||||||
bk.addrState.Lock()
|
bk.addrState.Lock()
|
||||||
defer bk.addrState.Unlock()
|
defer bk.addrState.Unlock()
|
||||||
|
|
||||||
if _, ok := bk.addrs[s]; ok {
|
if _, ok := bk.peers[s]; ok {
|
||||||
delete(bk.addrs, s)
|
delete(bk.peers, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,9 +108,9 @@ func (bk *AddressBook) Blacklist(s PeerKey) {
|
||||||
bk.addrState.Lock()
|
bk.addrState.Lock()
|
||||||
defer bk.addrState.Unlock()
|
defer bk.addrState.Unlock()
|
||||||
|
|
||||||
if target, ok := bk.addrs[s]; ok {
|
if target, ok := bk.peers[s]; ok {
|
||||||
target.blacklisted = true
|
bk.blacklist[s] = target
|
||||||
target.lastUpdate = time.Now()
|
delete(bk.peers, s)
|
||||||
} else {
|
} else {
|
||||||
// Create a new Address just to be blacklisted
|
// Create a new Address just to be blacklisted
|
||||||
addr, err := (&Address{}).fromPeerKey(s)
|
addr, err := (&Address{}).fromPeerKey(s)
|
||||||
|
@ -118,8 +118,7 @@ func (bk *AddressBook) Blacklist(s PeerKey) {
|
||||||
// XXX effectively NOP bogus peer strings
|
// XXX effectively NOP bogus peer strings
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addr.blacklisted = true
|
bk.blacklist[s] = addr
|
||||||
bk.addrs[s] = addr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +127,7 @@ func (bk *AddressBook) Touch(s PeerKey) {
|
||||||
bk.addrState.Lock()
|
bk.addrState.Lock()
|
||||||
defer bk.addrState.Unlock()
|
defer bk.addrState.Unlock()
|
||||||
|
|
||||||
if target, ok := bk.addrs[s]; ok {
|
if target, ok := bk.peers[s]; ok {
|
||||||
target.lastUpdate = time.Now()
|
target.lastUpdate = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +137,7 @@ func (bk *AddressBook) IsKnown(s PeerKey) bool {
|
||||||
bk.addrState.RLock()
|
bk.addrState.RLock()
|
||||||
defer bk.addrState.RUnlock()
|
defer bk.addrState.RUnlock()
|
||||||
|
|
||||||
_, known := bk.addrs[s]
|
_, known := bk.peers[s]
|
||||||
return known
|
return known
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,11 +145,8 @@ func (bk *AddressBook) IsBlacklisted(s PeerKey) bool {
|
||||||
bk.addrState.RLock()
|
bk.addrState.RLock()
|
||||||
defer bk.addrState.RUnlock()
|
defer bk.addrState.RUnlock()
|
||||||
|
|
||||||
if target, ok := bk.addrs[s]; ok {
|
_, blacklisted := bk.blacklist[s]
|
||||||
return target.blacklisted
|
return blacklisted
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForAddresses waits for n addresses to be received and their initial
|
// WaitForAddresses waits for n addresses to be received and their initial
|
||||||
|
@ -159,7 +155,7 @@ func (bk *AddressBook) IsBlacklisted(s PeerKey) bool {
|
||||||
func (bk *AddressBook) waitForAddresses(n int, done chan struct{}) {
|
func (bk *AddressBook) waitForAddresses(n int, done chan struct{}) {
|
||||||
bk.addrState.Lock()
|
bk.addrState.Lock()
|
||||||
for {
|
for {
|
||||||
addrCount := len(bk.addrs)
|
addrCount := len(bk.peers)
|
||||||
if addrCount < n {
|
if addrCount < n {
|
||||||
bk.addrRecvCond.Wait()
|
bk.addrRecvCond.Wait()
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,10 +173,10 @@ func (bk *AddressBook) shuffleAddressList(n int) []net.IP {
|
||||||
bk.addrState.RLock()
|
bk.addrState.RLock()
|
||||||
defer bk.addrState.RUnlock()
|
defer bk.addrState.RUnlock()
|
||||||
|
|
||||||
resp := make([]net.IP, 0, len(bk.addrs))
|
resp := make([]net.IP, 0, len(bk.peers))
|
||||||
|
|
||||||
for _, v := range bk.addrs {
|
for k, v := range bk.peers {
|
||||||
if v.blacklisted {
|
if _, blacklisted := bk.blacklist[k]; blacklisted {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,3 +372,8 @@ func (s *Seeder) Ready() bool {
|
||||||
func (s *Seeder) Addresses(n int) []net.IP {
|
func (s *Seeder) Addresses(n int) []net.IP {
|
||||||
return s.addrBook.shuffleAddressList(n)
|
return s.addrBook.shuffleAddressList(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testBlacklist adds a peer to the blacklist directly, for testing.
|
||||||
|
func (s *Seeder) testBlacklist(pk PeerKey) {
|
||||||
|
s.addrBook.Blacklist(pk)
|
||||||
|
}
|
||||||
|
|
|
@ -206,3 +206,29 @@ func TestRequestAddresses(t *testing.T) {
|
||||||
t.Errorf("Should have timed out, instead got: %v", err)
|
t.Errorf("Should have timed out, instead got: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBlacklist(t *testing.T) {
|
||||||
|
regSeeder, err := newTestSeeder(network.Regtest)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = regSeeder.ConnectOnDefaultPort("127.0.0.1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
regSeeder.RequestAddresses()
|
||||||
|
err = regSeeder.WaitForAddresses(1, 1*time.Second)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error getting one mocked address: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
regSeeder.testBlacklist(PeerKey("127.0.0.1:12345"))
|
||||||
|
err = regSeeder.Connect("127.0.0.1", "12345")
|
||||||
|
if err != ErrBlacklistedPeer {
|
||||||
|
t.Errorf("Blacklist did not prevent connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue