Skip to content

Conversation

Sjors
Copy link
Owner

@Sjors Sjors commented Jun 27, 2024

Introduce libbitcoin_net for all networking stuff.

See libraries.md for the current architecture.

This PR probably involves too many changes for something that doesn't solve an acute problem. But it's hopefully an interesting sketch and could inform discussions on further library design (and where to put stuff).

My own goal is to end up with libbitcoin_sv2 which only depends on libbitcoin_net, libbitcoin_crypto and libbitcoin_util. I might however settle for just a dependency on libbitcoin_common (as opposed to the current situation where the Template Provider is part of libbitcoin_node and has various dependencies on it).

Having networking code in its own library may have additional benefits:

  • use our networking code in another project, especially Transport
  • being able to ship some binaries with no networking code (like bitcoin-wallet and bitcoin-util)
  • swapping out the network library for something written in another language
  • easier fuzzing of the network code (??)

The main changes are:

  • move Transport to libbitcoin_net. Moving it out of libbitcoin_node is what got me down this rabbit hole; it's fairly easy to move it to libbitcoin_common, but I wanted to see if I could go beyond that.
    • move various things this depends on to libbitcoin_net: CNetMessage, NodeID, MAX_PROTOCOL_MESSAGE_LENGTH, BIP324, etc.
    • pass Params().MessageStart() into Transport so it doesn't need libbitcoin_common for chainparams.h.
  • move key.h from libbitcoin_common to libbitcoin_util (for GenerateRandomKey())
  • move non-consensus hash functions to libbitcoin_util (mainly BIP32Hash)
  • move ExtPubKey and EllSwift to libbitcoin_util (pubkey.h is part of libbitcoin_consensus which I'm trying to avoid a dependency on)

Some observations:

  • we use some cryptographic primitives for both consensus and networking (hash functions, public keys), some only for networking (EllSwift) and some for neither (private keys, BIP32). Shoving them all into libbitcoin_crypto is not ideal (and I didn't do so) because it would bloat the kernel (the one thing we plan to have a stable API for and want to keep lean and mean).
  • we might need another library for XOnlyPubKey (and maybe a few other things) which are needed for consensus, but also for ECDH (transport v2, sv2 noise) and signing (e.g. an sv2 certificate). This means they can't be in libbitcoin_util, because libbitcoin_consensus can't have dependency on that. See circular dependency below.

TODO:

  • satisfy contrib/devtools/check-deps.sh
  • fix circular dependency for XOnlyPubKey: part of both consensus and kernel, but (after my refactor) needed by util for CKey::SignSchnorr.
    • could move it to libbitcoin_crypto, but that seems the wrong place
    • could move SignSchnorr to libbitcoin_common
  • fix circular dependency with EllSwiftPubKey: it's used by key.cpp which is in util. I could move all of key.cpp to common, but then Net would depend on common.
  • wait for (or rebase on) cmake and fix windows native build
  • clean up CPubKey::Derive -> CExtPubKey::Derive move
  • try to get rid of libbitcoin_net-->libbitcoin_consensus
  • try to get rid of libbitcoin_net-->libbitcoin_kernel
  • add more low level network stuff
  • add PCP after its merged

Sjors and others added 13 commits June 27, 2024 17:34
This commit introduces libbitcoin_net. A single header connection_types.h and its implementation are moved there to ensure all scaffolding is in place.
The typedef int64_t NodeId is used in several places which generally have no need for anything else in net.h.

Specifically the introduction of net/util.h prevents a circular dependency in the next commit.
Moving MAX_PROTOCOL_MESSAGE_LENGTH out of net.h is needed to prevent a circular dependency in the upcoming commit that moves Transport to Net.
This commit also adds seperate header and implementation files
for TransportV1 and TransportV2.
This removes the Transport dependency on chainparams.h (libbitcoin_common).
libbitcoin_wallet has no dependency on libbitcoin_net.

Drop the unused include so the next commit can move
protocol.h to libbitcoin_net without adding such a
dependency.
GenerateRandomKey() is used by V2Transport to generate the ephemeral keys used in the handshake.
The ci "test-each-commit" job fetches the PR branch being tested with a depth of (# of commits in PR + 2), and then tries to run tests on commits after the most recent merge commit.

When a PR is opened against a bitcoin core branch, a merge commit is always guaranteed to exist within the fetch depth, because bitcoin core branches always point at merge commits.

However, in fork repositories, pull requests can be opened based on other branches that don't contain recent merge commits, and this will currently cause git rev-list to fail with fatal: bad revision '^^@'.

Work around this problem by not requiring a recent merge commit, and just testing on all fetched commits if a merge commit can't be found.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
@Sjors Sjors force-pushed the 2024/07/libbitcoin-net branch from b64fc46 to 6088dd7 Compare June 27, 2024 15:35
@Sjors
Copy link
Owner Author

Sjors commented Jun 27, 2024

Regarding he Win64 build failures, it's probably easier to wait for cmake than to figure out how to add a new library to the various build_msvc artefacts.

This avoids a dependency from util on consensus for BIP32Hash.
@Sjors Sjors force-pushed the 2024/07/libbitcoin-net branch from f348006 to 0d4b40e Compare June 28, 2024 11:26
@Sjors Sjors changed the title [WIP] libbitcoin_net [wip,sketch] libbitcoin_net Jun 28, 2024
Moving ExtPubKey out of consensus avoids a dependency from consensus on util for BIP32Hash.

Move the CPubKey::Derive implementation into ExtPubKey::Derive to avoid a dependency of CPubKey on BIP32Hash.
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.

1 participant