Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(SPV-742): add peer manager #247

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8c1d575
feat(SPV-742): improve peer logs
arkadiuszos4chain Apr 26, 2024
c222d04
feat(SPV-742): make server responsible for peers
arkadiuszos4chain Apr 26, 2024
d8f6b67
feat(SPV-742): make multiple outbound connection
arkadiuszos4chain Apr 26, 2024
3118c13
feat(SPV-742): add address book and store active peer addresses there
arkadiuszos4chain Apr 26, 2024
c2a5e82
feat(SPV-742): ask peers for known addresses on connection
arkadiuszos4chain Apr 26, 2024
6d495d1
feat(SPV-742): ban peer/addresse on error (naive 24h ban)
arkadiuszos4chain Apr 26, 2024
45919ea
feat(SPV-742): observe active outbound connections and keep them at d…
arkadiuszos4chain Apr 26, 2024
2fee765
feat(SPV-742): handle incoming connections
arkadiuszos4chain Apr 29, 2024
8f11329
feat(SPV-742): accept peers from local network
arkadiuszos4chain Apr 29, 2024
a2e3723
feat(SPV-742): fix address book
arkadiuszos4chain Apr 30, 2024
18c04d8
feat(SPV-742): add unit tests
arkadiuszos4chain Apr 30, 2024
adb4dec
feat(SPV-742): chnage DefaultPort type to uint16
arkadiuszos4chain Apr 30, 2024
9b214c4
feat(SPV-742): fix linter errors
arkadiuszos4chain Apr 30, 2024
5f5d06f
feat(SPV-742): fix linter errors
arkadiuszos4chain Apr 30, 2024
c2ec406
feat(SPV-742): fix linter errors
arkadiuszos4chain Apr 30, 2024
41c272a
feat(SPV-742): fix linter errors
arkadiuszos4chain May 1, 2024
7bab33f
feat(SPV-742): fix linter errors
arkadiuszos4chain May 1, 2024
4be1d5e
feat(SPV-742): adjust to review; add comments; minor server refactori…
arkadiuszos4chain May 2, 2024
d53cddc
feat(SPV-742): remove comments
arkadiuszos4chain May 2, 2024
a2b499c
feat(SPV-742): remove comments
arkadiuszos4chain May 2, 2024
66cc4e1
feat(SPV-742): remove comments
arkadiuszos4chain May 2, 2024
dc5d944
feat(SPV-742): fix error handling on server start
arkadiuszos4chain May 2, 2024
279a15c
feat(SPV-742): fix deadlock when disconnect peer
arkadiuszos4chain May 2, 2024
a560d91
feat(SPV-742): revert withCancelHandle() for clarity
arkadiuszos4chain May 2, 2024
0439f2f
feat(SPV-742): fix linter
arkadiuszos4chain May 2, 2024
be18961
feat(SPV-742): adjust to some comments
arkadiuszos4chain May 8, 2024
ff09468
feat(SPV-742): adjust to some comments
arkadiuszos4chain May 8, 2024
4a7dea9
feat(SPV-742): adjust comments- replace log helper funcitons with new…
arkadiuszos4chain May 8, 2024
558038c
feat(SPV-742): adjust comments- remove unnecessary peer address string
arkadiuszos4chain May 8, 2024
bb1004c
feat(SPV-742): adjust comments- improve peer collection implementation
arkadiuszos4chain May 10, 2024
25f2fbb
feat(SPV-742): adjust comments- move network to wire package; reimple…
arkadiuszos4chain May 10, 2024
c28cbec
feat(SPV-742): fix linter
arkadiuszos4chain May 10, 2024
8089afc
feat(SPV-742): adjust comments- filter seed address
arkadiuszos4chain May 10, 2024
0b0acf0
feat(SPV-742): adjust comments- use only ONE peer to sync with chain,…
arkadiuszos4chain May 10, 2024
d0f50bb
feat(SPV-742): fix linter
arkadiuszos4chain May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ type P2PConfig struct {
UserAgentName string `mapstructure:"user_agent_name" description:"The name that should be used during announcement of the client on the p2p network"`
UserAgentVersion string `mapstructure:"user_agent_version" description:"By default will be equal to application version, but can be overridden for development purposes"`
Experimental bool `mapstructure:"experimental" description:"Turns on a new (highly experimental) way of getting headers with the usage of /internal/transports/p2p instead of /transports/p2p"`

MaxOutboundConnections uint `mapstructure:"max_outbound_connections" description:"Maximum active outbound connections"`
}

// LoggingConfig represents a logging config.
Expand Down
1 change: 1 addition & 0 deletions config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func getP2PDefaults() *P2PConfig {
UserAgentName: ApplicationName,
UserAgentVersion: Version(),
Experimental: false,
MaxOutboundConnections: 8,
}
}

Expand Down
27 changes: 0 additions & 27 deletions internal/transports/p2p/addr.go

This file was deleted.

82 changes: 0 additions & 82 deletions internal/transports/p2p/addr_test.go

This file was deleted.

120 changes: 120 additions & 0 deletions internal/transports/p2p/network/address_book.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package network

import (
"fmt"
"math/rand"
"sync"
"time"

"github.com/bitcoin-sv/block-headers-service/internal/transports/p2p/peer"
"github.com/bitcoin-sv/block-headers-service/internal/wire"
)

type AddressBook struct {
banDuration time.Duration
addrs []*knownAddress
keyIndex map[string]int

arkadiuszos4chain marked this conversation as resolved.
Show resolved Hide resolved
mu sync.Mutex
}

func NewAdressbook(banDuration time.Duration) *AddressBook {
return &AddressBook{
addrs: make([]*knownAddress, 0, 400),
keyIndex: make(map[string]int, 400),
banDuration: banDuration,
}
}

func (a *AddressBook) UpsertPeerAddr(p *peer.Peer) {
a.mu.Lock()
defer a.mu.Unlock()

pa := p.GetPeerAddr()
key, ka := a.internalFind(pa)

if ka != nil {
ka.peer = p
} else {
a.internalAddAddr(key, &knownAddress{addr: pa, peer: p})
}
}

func (a *AddressBook) AddAddrs(address []*wire.NetAddress) {
a.mu.Lock()
defer a.mu.Unlock()

for _, addr := range address {
if !IsRoutable(addr) {
continue
}

key, ka := a.internalFind(addr)
if ka == nil {
a.internalAddAddr(key, &knownAddress{addr: addr})
} else if addr.Timestamp.After(ka.addr.Timestamp) {
ka.addr.Timestamp = addr.Timestamp
}
}
}

func (a *AddressBook) BanAddr(addr *wire.NetAddress) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func (a *AddressBook) BanAddr(addr *wire.NetAddress) {
func (a *AddressBook) Ban(addr *wire.NetAddress) {

a.mu.Lock()
defer a.mu.Unlock()

_, ka := a.internalFind(addr)
if ka != nil {
now := time.Now()
ka.banTimestamp = &now
}
}

func (a *AddressBook) GetRndUnusedAddr(tries uint) *wire.NetAddress {
kuba-4chain marked this conversation as resolved.
Show resolved Hide resolved
a.mu.Lock()
defer a.mu.Unlock()

alen := len(a.addrs)
for i := uint(0); i < tries; i++ {
ka := a.addrs[rand.Intn(alen)]

Check failure on line 78 in internal/transports/p2p/network/address_book.go

View workflow job for this annotation

GitHub Actions / on-push / Lint

G404: Use of weak random number generator (math/rand instead of crypto/rand) (gosec)
if ka.peer == nil {
if ka.isBanned(a.banDuration) {
continue
}
return ka.addr
}
}

return nil
}

func (a *AddressBook) internalFind(addr *wire.NetAddress) (string, *knownAddress) {
arkadiuszos4chain marked this conversation as resolved.
Show resolved Hide resolved
key := addrKey(addr)
addrIndex, ok := a.keyIndex[key]

if ok {
return key, a.addrs[addrIndex]
}
return key, nil
}

func (a *AddressBook) internalAddAddr(key string, addr *knownAddress) {
newItemIndex := len(a.addrs)

a.addrs = append(a.addrs, addr)
a.keyIndex[key] = newItemIndex
}

func addrKey(addr *wire.NetAddress) string {
return fmt.Sprintf("%s:%d", addr.IP, addr.Port)
}

type knownAddress struct {
addr *wire.NetAddress
peer *peer.Peer

banTimestamp *time.Time
}

func (a *knownAddress) isBanned(duration time.Duration) bool {
return a.banTimestamp != nil && time.Since(*a.banTimestamp) < duration
kuba-4chain marked this conversation as resolved.
Show resolved Hide resolved
}
arkadiuszos4chain marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading