-
Notifications
You must be signed in to change notification settings - Fork 54
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
refactor(px): refactor peer exchange + tests #1527
Conversation
Jenkins BuildsClick to see older builds (3)
|
c2ca40e
to
3708e06
Compare
3708e06
to
1233fa9
Compare
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.
Waku peer-exchange wire formats must be added to the vacp2p/waku repository.
Please add them before proceeding with modifying the implementation. Flaws in the wire format and the RPC types should be fixed before moving forward.
# handle peer exchange request | ||
if rpc.request != PeerExchangeRequest(): | ||
# If we got a request (request field is not empty) | ||
if rpc.request != default(PeerExchangeRequest): |
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.
While I know this is in other places in the code, we should avoid doing it. This is a defect in this protocol's RPC codec and RPC types:
- If the field is mandatory, return a "required field missing error"
- If the field is optional, the codec should return an
Option
; here, you should check if it is present (or not) and act in consequence.
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.
Yep, I agree. But since the rpc doesn't allow us to add an error message, this would involve changing the px proto, changing the spec, and perhaps bumping the px version? All of this beyond the PR.
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.
This is not correct.
I am not asking to change the protocol. I am concerned about the implementation and the way this equality comparison uses the default(...)
to detect if the field was missing:
if rpc.request != default(PeerExchangeRequest):
You can return the this "required field missing" error from the rpc_codec
the same way other protocols do, and this check can be removed from the protocol handler because if the field is not present, the message will be considered invalid.
This doesn't require any protocol modification. It is an implementation detail, and it should be in the scope of the PR, given that this PR aims to improve the implementation. This technical debt cannot be left out of the scope.
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.
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.
As a general note, PRs can and should have a limited scope. This PR had a clear focus listed in the description and addressed those items.
Not approving a PR generally means that there is a critical bug/regression/technical debt introduced (not existing prior to PR) or a critical question which needs answering. Technical debt which existed before the PR can be pointed out, but to speed up PR process should not stop approval.
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.
Waku peer-exchange wire formats must be added to the vacp2p/waku repository.
Please add them before proceeding with modifying the implementation. Flaws in the wire format and the RPC types should be fixed before moving forward.
Sure, wouldnt consider it a blocker for this, but this should cover it:
waku-org/waku-proto#12
vacp2p/rfc#570
# handle peer exchange request | ||
if rpc.request != PeerExchangeRequest(): | ||
# If we got a request (request field is not empty) | ||
if rpc.request != default(PeerExchangeRequest): |
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.
Yep, I agree. But since the rpc doesn't allow us to add an error message, this would involve changing the px proto, changing the spec, and perhaps bumping the px version? All of this beyond the PR.
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.
Agree with the general approach of:
- decoupling peer exchange response from connecting to peers
- what to do with peers in peer exchange response not being a concern of the protocol but the "application", but think we can have
WakuNode
be setup as a basic peer exchange client application: e.g. calling request once on init, similar to DNS lookup being done once when configured.
apps/wakunode2/wakunode2.nim
Outdated
let pxPeersRes = await node.wakuPeerExchange.request(desiredOutDegree) | ||
if pxPeersRes.isOk: | ||
var record: enr.Record | ||
var validPeers = 0 | ||
for pi in pxPeersRes.get().peerInfos: | ||
if enr.fromBytes(record, pi.enr): | ||
node.peerManager.addPeer(record.toRemotePeerInfo().get, WakuRelayCodec) | ||
validPeers += 1 | ||
info "Retrieved peer info via peer exchange protocol", validPeers = validPeers | ||
else: | ||
warn "Failed to retrieve peer info via peer exchange protocol" |
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.
This is a bit weird for me. While I agree with removing this from the protocol
module, why not into waku_node
when set up as a peer exchange client? It may make sense during node init
to call some function that sets up peer exchange as a client and for now does only a single request. Basically we init and start all other discovery mechanisms when initiating the WakuNode
, so this belongs there IMO.
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.
yes indeed, not sure what i was thinking. Addressed in 9083938
Added also a new test which also showcases how this is expected to be used.
nwaku/tests/v2/test_wakunode.nim
Lines 293 to 317 in 9083938
asyncTest "Function fetchPeerExchangePeers succesfully exchanges px peers": | |
let | |
node1 = WakuNode.new(generateKey(), ValidIpAddress.init("0.0.0.0"), Port(0)) | |
node2 = WakuNode.new(generateKey(), ValidIpAddress.init("0.0.0.0"), Port(0)) | |
# Start and mount peer exchange | |
await allFutures([node1.start(), node2.start()]) | |
await allFutures([node1.mountPeerExchange(), node2.mountPeerExchange()]) | |
# Mock that we discovered a node (to avoid running discv5) | |
var enr = enr.Record() | |
require enr.fromUri("enr:-Iu4QGNuTvNRulF3A4Kb9YHiIXLr0z_CpvWkWjWKU-o95zUPR_In02AWek4nsSk7G_-YDcaT4bDRPzt5JIWvFqkXSNcBgmlkgnY0gmlwhE0WsGeJc2VjcDI1NmsxoQKp9VzU2FAh7fwOwSpg1M_Ekz4zzl0Fpbg6po2ZwgVwQYN0Y3CC6mCFd2FrdTIB") | |
node2.wakuPeerExchange.enrCache.add(enr) | |
# Set node2 as service peer (default one) for px protocol | |
node1.peerManager.addServicePeer(node2.peerInfo.toRemotePeerInfo(), WakuPeerExchangeCodec) | |
# Request 1 peer from peer exchange protocol | |
await node1.fetchPeerExchangePeers(1) | |
# Check that the peer ended up in the peerstore | |
let rpInfo = enr.toRemotePeerInfo.get() | |
check: | |
node1.peerManager.peerStore.peers.anyIt(it.peerId == rpInfo.peerId) | |
node1.peerManager.peerStore.peers.anyIt(it.addrs == rpInfo.addrs) |
19bab05
to
9083938
Compare
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.
LGTM! Thanks. I'm still uneasy about the wakunode2 performing the API call, but I think this is clearly beyond the scope of this PR. :)
@LNSD I addresses your comments (rfc update and proto updates) which are already merged, and replied. Is there anything left? Would like to merge this today unless you need more time. |
9083938
to
d33294d
Compare
Please, check my comments on the |
@LNSD thanks, addresses the changes. |
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 see some details that do not follow the agreed style guide, but you can merge it if you want ✅
Last item to close #1463
Some refactoring in the px protocol + more tests + moving the "what to do with the peers we got via px" logic to the application. Some discussions started in #1463 and this prepares the ground for #1521.
Summary of changes:
Result
and catch exceptions (mainlyreadLp
andwriteLp
since can raise an Exception if the stream is prematurely closed)respond
proc, reusing the existing connection instead of attempting to create a new one.PeerExchangeResponse
to a px node without that node ever requesting anything from you.request
proc variants both succesfull and not.Test:
End to end test
Node that discovers peers and runs peer exchange:
Node that sets the above one as px node
Peers are succesfuly retrieved in the second node and added to the peerstore.