Skip to content

Backport Bitcoin PR#8085: p2p: Begin encapsulation#1537

Merged
UdjinM6 merged 33 commits intodashpay:v0.12.2.xfrom
OlegGirko:bc-pr-8085
Jul 21, 2017
Merged

Backport Bitcoin PR#8085: p2p: Begin encapsulation#1537
UdjinM6 merged 33 commits intodashpay:v0.12.2.xfrom
OlegGirko:bc-pr-8085

Conversation

@OlegGirko
Copy link
Copy Markdown

This is backport of Bitcoin PR bitcoin#8085.

Brace yourself, this is the biggest PR (33 commits) I'm sending in in networking refactoring series and most important one.

All 33 commits are relatively small, so I'd advise to review them one by one, rather than just overall file changes.

When merging this PR, please don't squash commits, just use normal merge. Otherwise it will be difficult to understand these changes when searching in history later.

The original PR description follows.

This work creates CConnman. The idea is to begin moving data structures and functionality out of globals in net.h and into an instanced class, in order to avoid side-effects in networking code. Eventually, an (internal) api begins to emerge, and as long as the conditions of that api are met, the inner-workings may be a black box.

For now (for ease), a single global CConnman is created. Down the road, the instance could be passed around instead. Also, CConnman should be moved out of net.h/net.cpp, but that can be done in a separate move-only-ish step.

A few todos remain here:

  • there are if(g_connman)'s everywhere. A few places should assume that a connman is running (or it should be passed around). For example, ProcessMessages.
  • GetRelayTx/RelayTransaction are awkward. Where should mapRelay live? Should it be dealt with directly rather than hidden inside of relay functions? (rebased on top of Defer inserting into maprelay until just before relaying. bitcoin/bitcoin#8082)
  • How to deal with CConnman parameters? Continue adding them to Start(), or have it parse the program options itself? (Created CConnman::Options)
  • RPC needs a new error for dealing with the "p2p not enabled" case.

Todos for a follow-up PR:

  • Actually create connman.h/cpp and move the class there.
  • Pass CConnman into QT similar to the wallet
  • Drop StartNode/StopNode and just use CConnman::Stop/Start directly (Need to make sure that MapPort can be moved directly into Init without side-effects)
  • Pass CChainParams into CConnman and pass it around
  • Create CConnmanOptions to reduce the verbosity of CConnman::Start()
  • Deal with fDiscover/fListen/etc in CConnman

theuni added 30 commits July 17, 2017 19:43
This will eventually solve a circular dependency
This behavior seems to have been quite racy and broken.

Move nLocalHostNonce into CNode, and check received nonces against all
non-fully-connected nodes. If there's a match, assume we've connected
to ourself.
These are in-turn passed to CNode at connection time. This allows us to offer
different services to different peers (or test the effects of doing so).
CConnman then passes the current best height into CNode at creation time.

This way CConnman/CNode have no dependency on main for height, and the signals
only move in one direction.

This also helps to prevent identity leakage a tiny bit. Before this change, an
attacker could theoretically make 2 connections on different interfaces. They
would connect fully on one, and only establish the initial connection on the
other. Once they receive a new block, they would relay it to your first
connection, and immediately commence the version handshake on the second. Since
the new block height is reflected immediately, they could attempt to learn
whether the two connections were correlated.

This is, of course, incredibly unlikely to work due to the small timings
involved and receipt from other senders. But it doesn't hurt to lock-in
nBestHeight at the time of connection, rather than letting the remote choose
the time.
Copy link
Copy Markdown

@tgflynn tgflynn left a comment

Choose a reason for hiding this comment

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

utACK for commit ad82cbf

@tgflynn
Copy link
Copy Markdown

tgflynn commented Jul 18, 2017

Note above approval was only intended for 1 commit, not whole PR.

Copy link
Copy Markdown

@tgflynn tgflynn left a comment

Choose a reason for hiding this comment

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

utACK for commmit 5f58829

Copy link
Copy Markdown

@tgflynn tgflynn left a comment

Choose a reason for hiding this comment

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

utACK for commit 461c587

Comment thread src/qt/peertablemodel.cpp
stats.nodeStateStats.nCommonHeight = -1;
stats.fNodeStateStatsAvailable = false;
pnode->copyStats(stats.nodeStats);
stats.nodeStats = nodestats;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This looks strange. Why recopy the same data multiple times ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

For better modularity and readability, I presume. Instead of iterating through all vNodes holding a lock, a method has been introduced to get copy of stats. This can potentially allow to completely encapsulate how stats are stored and access them only through method.

Although this code is less efficient,

  • amount of data copied is small,
  • code is not on critical path.

@UdjinM6 UdjinM6 added this to the 12.2 milestone Jul 18, 2017
Copy link
Copy Markdown

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

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

looks good 👍

tested (local wallet, not mn), ACK

Comment thread src/net.cpp Outdated
void CConnman::ForEachNode(std::function<void(CNode* pnode)> func)
{
LOCK(cs_vNodes);
for (auto&& node : vNodes)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why the double '&' here ?

@tgflynn
Copy link
Copy Markdown

tgflynn commented Jul 21, 2017

utACK (all commits)

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.

5 participants