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

add bitcoin support to nebula #84

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

thisHermit
Copy link

@thisHermit thisHermit commented Dec 26, 2024

This PR introduces Bitcoin network support to the Nebula crawler by implementing necessary interfaces, integrating the btcsuite/btcd/wire package, and adding a basic Bitcoin network crawler. Key changes include:

1. Interface Implementations

  • PeerInfo:
    • Added Bitcoin-specific struct for peer information, adhering to Nebula's interface requirements.
  • CrawlDriverConfig:
    • Created a configuration struct for Bitcoin network parameters and logging.
  • CrawlDriver:
    • Implemented the core crawling driver for Bitcoin, enabling peer connections, message handling, and shutdown procedures.

2. Bitcoin Network Integration

  • Introduced CLI support for Bitcoin (--network bitcoin).
  • Updated the main crawler logic to initialize and run the Bitcoin CrawlDriver.

3. Error Handling and Protocol Compliance

  • Resolved message-handling issues with unknown Bitcoin protocol messages.
  • Ensured compliance with Bitcoin protocol, including proper handshake procedures and protocol negotiation.

4. btcsuite/btcd/wire Package Integration

  • Added dependency on btcsuite/btcd/wire for Bitcoin protocol implementation.
  • Utilized provided message types, serialization methods, and network magic numbers.

5. Basic Bitcoin Network Crawler Implementation

  • Translated existing DNS and peer crawling logic from btc-crawl to Nebula format.
  • Implemented crawling logic for Bitcoin nodes, including handshake and peer discovery.
  • Added Bitcoin-specific logging for development and debugging.

Plan.md Outdated Show resolved Hide resolved
Comment on lines +25 to +31
type AddrInfo struct {
id string
Addr []ma.Multiaddr
}
type PeerInfo struct {
AddrInfo
}
Copy link
Owner

Choose a reason for hiding this comment

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

You can move the fields into the PeerInfo struct. I don't think the nesting is necessary. You can also export the id field like so:

Suggested change
type AddrInfo struct {
id string
Addr []ma.Multiaddr
}
type PeerInfo struct {
AddrInfo
}
type PeerInfo struct {
ID string
Addr []ma.Multiaddr
}

Comment on lines 61 to 74
type CrawlDriverConfig struct {
Version string
TrackNeighbors bool
DialTimeout time.Duration
BootstrapPeers []ma.Multiaddr
AddrDialType config.AddrType
AddrTrackType config.AddrType
KeepENR bool
MeterProvider metric.MeterProvider
TracerProvider trace.TracerProvider
LogErrors bool
UDPBufferSize int
UDPRespTimeout time.Duration
}
Copy link
Owner

Choose a reason for hiding this comment

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

You don't need the following fields.

Suggested change
type CrawlDriverConfig struct {
Version string
TrackNeighbors bool
DialTimeout time.Duration
BootstrapPeers []ma.Multiaddr
AddrDialType config.AddrType
AddrTrackType config.AddrType
KeepENR bool
MeterProvider metric.MeterProvider
TracerProvider trace.TracerProvider
LogErrors bool
UDPBufferSize int
UDPRespTimeout time.Duration
}
type CrawlDriverConfig struct {
Version string
TrackNeighbors bool
DialTimeout time.Duration
BootstrapPeers []ma.Multiaddr
MeterProvider metric.MeterProvider
TracerProvider trace.TracerProvider
LogErrors bool
}

maybe Version can also be removed.

bitcoin/driver_crawler.go Outdated Show resolved Hide resolved
bitcoin/driver_crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
bitcoin/crawler.go Outdated Show resolved Hide resolved
"dnsseed.bitcoin.dashjr.org",
"seed.bitcoinstats.com",
"seed.bitnodes.io",
"bitseed.xf2.org",
Copy link
Owner

Choose a reason for hiding this comment

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

Consider using multi address format:

Suggested change
"bitseed.xf2.org",
"/dns/bitseed.xf2.org",

@thisHermit thisHermit changed the title feat: add bitcoin support to nebula add bitcoin support to nebula Jan 23, 2025
@thisHermit thisHermit marked this pull request as ready for review January 23, 2025 15:06
@dennis-tra
Copy link
Owner

Could you also add the new network to the readme and perhaps mark it as alpha?

// there is no other reliable transport address like TCP or QUIC we use the UDP
// IP address + port and craft a TCP address out of it. The UDP address will
// still be removed and replaced with TCP.
func sanitizeAddrs(maddrs []ma.Multiaddr) ([]ma.Multiaddr, bool) {
Copy link
Owner

Choose a reason for hiding this comment

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

this function is obsolete and can be removed

Comment on lines +476 to +479
if conn == nil {
log.Infoln("SOMETHING IS WRONG!!!!")
}
return wire.WriteMessage(conn, msg, wire.ProtocolVersion, wire.MainNet)
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
if conn == nil {
log.Infoln("SOMETHING IS WRONG!!!!")
}
return wire.WriteMessage(conn, msg, wire.ProtocolVersion, wire.MainNet)
return wire.WriteMessage(conn, msg, wire.ProtocolVersion, wire.MainNet)

})
logEntry.Debugln("Connecting to peer", pi.ID.ShortString())

netAddr, _ := manet.ToNetAddr(pi.Addrs[0])
Copy link
Owner

Choose a reason for hiding this comment

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

handle error

Comment on lines +133 to +138
// addrInfo := peer.AddrInfo{
// ID: pi.ID(),
// Addrs: sanitizedAddrs,
// }

var conn net.Conn
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
// addrInfo := peer.AddrInfo{
// ID: pi.ID(),
// Addrs: sanitizedAddrs,
// }
var conn net.Conn
var conn net.Conn

}
result.Error = err
resultCh <- result
close(resultCh)
Copy link
Owner

Choose a reason for hiding this comment

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

rather do a defer close(resultCh) and also remove the close call at the end of the function

close(resultCh)
return
}
// conn, result.ConnectError = c.connect(ctx, addrInfo) // use filtered addr list
Copy link
Owner

Choose a reason for hiding this comment

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

same here, why the connect method below and this here? I would prefer to keep and use a dedicated connect method that abstracts away the error case handling and only returns an error if we really couldn't connect on any of the provided addresses.

result.Agent = nodeRes.UserAgent
result.ProtocolVersion = nodeRes.ProtocolVersion
if err != nil {
log.Debugf("[%s] Handshake failed: %v", addrs, err)
Copy link
Owner

Choose a reason for hiding this comment

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

rather use the WithError method on the logger. Also the log messages below.

Comment on lines +185 to +190
firstReceived := -1
tolerateMessages := 5
// The nodes send a lot of inv messages
tolerateInvMessages := 50
tolerateVerAckMessages := 10
toleratePingMessages := 3
Copy link
Owner

Choose a reason for hiding this comment

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

could you in a brief code comment explain the logic behind the message "toleration"

Comment on lines +333 to +337
if conn != nil {
if err := conn.Close(); err != nil {
log.WithError(err).WithField("remoteID", pi.ID().ShortString()).Warnln("Could not close connection on context cancel")
}
}
Copy link
Owner

Choose a reason for hiding this comment

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

rather put this in a defer statement at the point in the code where you have received the connection object.

Addr: []ma.Multiaddr{maddr},
},
}
}
Copy link
Owner

Choose a reason for hiding this comment

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

any chance to remove the code duplication with above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants