-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
[peer] Refactor peer code into its own package #445
Conversation
Update: Moved all message handlers into respective listeners. Listeners can be added and removed using a key (string) and all listeners are invoked when a message is received. Looking into a couple of issues which cropped up while testing:
|
I'll be giving this a thorough review over the coming days, but a few points from a very quick review are:
|
// Don't accept more transactions if we're shutting down. | ||
if atomic.LoadInt32(&b.shutdown) != 0 { | ||
p.txProcessed <- struct{}{} | ||
p.TxProcessed <- struct{}{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we're going to want a better mechanism for this. It is mixing peer and block manager state and won't fit in well with other callers.
Also, before this is ready for merge it will need the standard fare of package documentation and a full suite of test coverage.
|
Thanks @davecgh will add those. |
6150e4f
to
b39b230
Compare
d722b47
to
ca816a7
Compare
Refactored to remove fields owned by blockmanager i.e As for pending tasks, added a first version of |
32b5760
to
2c230a2
Compare
Added example to showcase usage of package Working on testing and writing |
Added both inbound and outbound peer examples. Working on ironing out a couple of minor issues and adding tests. |
Added tests for package peer, with coverage at ~47% now. Working on clearing up and improving the coverage. |
9287b25
to
2186828
Compare
Debugging an crash in |
Pushed a fix for the inv message crash issue. |
for k := range p.requestedTxns { | ||
delete(b.requestedTxns, k) | ||
for k, txPeer := range b.requestedTxns { | ||
if txPeer == p { // peer matches |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we have unique IDs for peers already. We should probably use that instead of relying on pointer equality. I realize that as long as the code is super careful they should match, but it wouldn't be very difficult to have two different pointers to the same peer which would cause a check like this fail.
Please squash all commits and update the initial commit message to reflect reality. |
ffd6da1
to
c3cc837
Compare
As a point of reference, all previous comments up until this point have been taken care of. |
c3cc837
to
53347ea
Compare
Updated commit message and added a |
|
||
// Ensure the limited number of most recent entries in the list | ||
// exist. | ||
for j := numNonces - 1; j >= numNonces-test.limit; j-- { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this and the loop below iterate with increasing j's? For this one it should start at the limit and iterate up to numNonces, and the one below would iterate from 0 up to the limit. imo that would be more readable than iterating them backwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, updated to iterate in increasing order.
I think this should be reworded as it could be interpreted to mean that these callbacks can be modified through this struct at runtime after a peer is created (it won't race because it creates a copy, but it won't work as intended either). It also MUST explain how these callbacks are executed. Per a single peer, do these callbacks execute concurrently with multiple messages or does one callback block the execution of the next? |
return | ||
} | ||
|
||
// TODO: actually test the following methods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bump
For reference, here is an overview of the major testing points I've done:
Connection count from
Outbound and inbound peers shown properly in
Total bytes read and written from
|
Once @jrick's comments are addressed, this is ready for master. |
00ece4b
to
631aa31
Compare
Everything has been addressed for me. OK |
ok |
This commit introduces package peer which contains peer related features refactored from peer.go. The following is an overview of the features the package provides: - Provides a basic concurrent safe bitcoin peer for handling bitcoin communications via the peer-to-peer protocol - Full duplex reading and writing of bitcoin protocol messages - Automatic handling of the initial handshake process including protocol version negotiation - Automatic periodic keep-alive pinging and pong responses - Asynchronous message queueing of outbound messages with optional channel for notification when the message is actually sent - Inventory message batching and send trickling with known inventory detection and avoidance - Ability to wait for shutdown/disconnect - Flexible peer configuration - Caller is responsible for creating outgoing connections and listening for incoming connections so they have flexibility to establish connections as they see fit (proxies, etc.) - User agent name and version - Bitcoin network - Service support signalling (full nodes, bloom filters, etc.) - Maximum supported protocol version - Ability to register callbacks for handling bitcoin protocol messages - Proper handling of bloom filter related commands when the caller does not specify the related flag to signal support - Disconnects the peer when the protocol version is high enough - Does not invoke the related callbacks for older protocol versions - Snapshottable peer statistics such as the total number of bytes read and written, the remote address, user agent, and negotiated protocol version - Helper functions for pushing addresses, getblocks, getheaders, and reject messages - These could all be sent manually via the standard message output function, but the helpers provide additional nice functionality such as duplicate filtering and address randomization - Full documentation with example usage - Test coverage In addition to the addition of the new package, btcd has been refactored to make use of the new package by extending the basic peer it provides to work with the blockmanager and server to act as a full node. The following is a broad overview of the changes to integrate the package: - The server is responsible for all connection management including persistent peers and banning - Callbacks for all messages that are required to implement a full node are registered - Logic necessary to serve data and behave as a full node is now in the callback registered with the peer Finally, the following peer-related things have been improved as a part of this refactor: - Don't log or send reject message due to peer disconnects - Remove trace logs that aren't particularly helpful - Finish an old TODO to switch the queue WaitGroup over to a channel - Improve various comments and fix some code consistency cases - Improve a few logging bits - Implement a most-recently-used nonce tracking for detecting self connections and generate a unique nonce for each peer
631aa31
to
00bddf7
Compare
This pull request introduces package peer which contains peer related features
refactored from
peer.go
.The following is an overview of the features the package provides:
communications via the peer-to-peer protocol
version negotiation
channel for notification when the message is actually sent
detection and avoidance
for incoming connections so they have flexibility to establish
connections as they see fit (proxies, etc.)
not specify the related flag to signal support
and written, the remote address, user agent, and negotiated protocol
version
addresses
,getblocks
,getheaders
, andreject
messagesfunction, but the helpers provide additional nice functionality such
as duplicate filtering and address randomization
In addition to the addition of the new package,
btcd
has been refactoredto make use of the new package by extending the basic peer it provides to
work with the
blockmanager
andserver
to act as a full node. Thefollowing is a broad overview of the changes to integrate the package:
server
is responsible for all connection management includingpersistent peers and banning
are registered
callback registered with the peer
Finally, the following peer-related things have been improved as a part
of this refactor:
WaitGroup
over to a channelconnections and generate a unique nonce for each peer