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

Stratum v2 connman #50

Open
wants to merge 24 commits into
base: sv2-transport
Choose a base branch
from
Open

Stratum v2 connman #50

wants to merge 24 commits into from

Conversation

Sjors
Copy link
Owner

@Sjors Sjors commented Jul 19, 2024

Based on:

Followed by #49. Parent PR #68

This PR introduces Sv2Connman, a subclass of SockMan (bitcoin#30988). It uses the Sv2Transport introduced in bitcoin#30315 to enable incoming connections from other Stratum v2 roles.

It's main target user is the Template Provider role introduced in #49.

There may be other Stratum v2 roles we want to support in the future.

Earlier version(s): bitcoin#30332


Note to self, to keep this rebased until bitcoin#30205 and bitcoin#30988 land (2 merge commits and 3 normal commits):

git rebase --rebase-merges HEAD~5 --onto sv2-transport

This won't include changes in the original branches. To achieve that:

git fetch vasild
git reset --hard sv2-transport
git merge vasild/sockman
git merge vasild/DynSock
git cherry-pick sjors/2024/06/sv2_connection~2^..sjors/2024/06/sv2_connection

Note that this code will most likely not be upstreamed to Bitcoin Core, but instead used to create a standalone c++ application that connects to a running node via an IPC interface. See bitcoin#31098.

@Sjors
Copy link
Owner Author

Sjors commented Jul 19, 2024

@pinheadmz wrote in the original PR:

I am working on a libevent-replacing HTTP server using netbase primitives and yeah, I have some functions that look a lot like the sv2connamn in this branch.

I think it would be cool if possible to abstract the mechanisms in ThreadSocketHandler to work on "abstract clients" and I'd be happy to review and collaborate on that.

I plan to take a look at this.

@Sjors
Copy link
Owner Author

Sjors commented Aug 29, 2024

CMake rebase.

@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from 6b5ee20 to 4f957ee Compare August 29, 2024 11:37
@Sjors Sjors force-pushed the 2024/06/sv2_transport branch from 922fd8a to 50b6eb8 Compare August 29, 2024 11:47
@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from 4f957ee to b69544c Compare August 29, 2024 11:49
@Sjors Sjors force-pushed the 2024/06/sv2_transport branch from 50b6eb8 to 6a02367 Compare September 5, 2024 12:48
@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from b69544c to 1ca68d2 Compare September 5, 2024 12:57
@Sjors Sjors force-pushed the 2024/06/sv2_transport branch from 6a02367 to ce4269c Compare September 10, 2024 14:50
@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from 1ca68d2 to b578e0a Compare September 10, 2024 14:54
@Sjors Sjors force-pushed the 2024/06/sv2_transport branch 3 times, most recently from 8220337 to 5fca2c5 Compare September 19, 2024 14:40
@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from b578e0a to 489c9fb Compare September 19, 2024 15:02
@Sjors Sjors force-pushed the 2024/06/sv2_transport branch from 5fca2c5 to dfb9a6d Compare September 20, 2024 09:13
@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from 489c9fb to a55fa83 Compare September 20, 2024 09:17
@Sjors
Copy link
Owner Author

Sjors commented Sep 20, 2024

Rebased to move everything into a bitcoin_sv2 library (use -DWITH_SV2=ON to compile).

@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from ab9a6a0 to 296ba97 Compare November 22, 2024 10:22
@Sjors
Copy link
Owner Author

Sjors commented Nov 22, 2024

Rebased to incorporate the latest and greatest from bitcoin#30205.

* `CConnman::CalculateKeyedNetGroup()` needs `CNetAddr`, not `CAddress`,
  thus change its argument.

* Both callers of `CConnman::CreateNodeFromAcceptedSocket()` create a
  dummy `CAddress` from `CService`, so use `CService` instead.

* `GetBindAddress()` only needs to return `CAddress`.

* `CNode::addrBind` does not need to be `CAddress`.
Introduce a new low-level socket managing class `SockMan`
and move the `CConnman::BindListenPort()` method to it.

Also, separate the listening socket from the permissions -
they were coupled in `struct ListenSocket`, but the socket
is protocol agnostic, whereas the permissions are specific
to the application of the Bitcoin P2P protocol.
It was copied verbatim from `CConnman::BindListenPort()` in the previous
commit. Modernize its variables and style and log the error messages
from the caller.
Move the `CConnman::AcceptConnection()` method to `SockMan` and split
parts of it:
* the flip-to-CJDNS part: to just after the `AcceptConnection()` call
* the permissions part: at the start of `CreateNodeFromAcceptedSocket()`
CConnman-specific or in other words, Bitcoin P2P specific. Now
the `ThreadI2PAcceptIncoming()` method is protocol agnostic and
can be moved to `SockMan`.
Change `CConnman::m_nodes` from `std::vector<CNode*>` to
`std::unordered_map<NodeId, CNode*>` because interaction
between `CConnman` and `SockMan` is going to be based on
`NodeId` and finding a node by its id would better be fast.

As a nice side effect the existent search-by-id operations in
`CConnman::AttemptToEvictConnection()`,
`CConnman::DisconnectNode()` and
`CConnman::ForNode()` now become `O(1)` (were `O(number of nodes)`),
as well as the erase in `CConnman::DisconnectNodes()`.
Move the parts of `CConnman::GenerateWaitSockets()` that are specific to
the Bitcoin-P2P protocol to dedicated methods:
`ShouldTryToSend()` and `ShouldTryToRecv()`.

This brings us one step closer to moving `GenerateWaitSockets()` to the
protocol agnostic `SockMan` (which would call `ShouldTry...()` from
`CConnman`).
…cketHandler()

Move some parts of `CConnman::SocketHandlerConnected()` and
`CConnman::ThreadSocketHandler()` that are specific to the Bitcoin-P2P
protocol to dedicated methods:
`EventIOLoopCompletedForNode()` and `EventIOLoopCompletedForAllPeers()`.

This brings us one step closer to moving `SocketHandlerConnected()` and
`ThreadSocketHandler()` to the protocol agnostic `SockMan` (which would
call `EventIOLoopCompleted...()` from `CConnman`).
Introduce 4 new methods for the interaction between `CConnman` and
`SockMan`:

* `EventReadyToSend()`:
  called when there is readiness to send and do the actual sending of data.

* `EventGotData()`, `EventGotEOF()`, `EventGotPermanentReadError()`:
  called when the corresponing recv events occur.

These methods contain logic that is specific to the Bitcoin-P2P protocol
and move it away from `CConnman::SocketHandlerConnected()` which will
become a protocol agnostic method of `SockMan`.

Also, move the counting of sent bytes to `CConnman::SocketSendData()` -
both callers of that method called `RecordBytesSent()` just after the
call, so move it from the callers to inside
`CConnman::SocketSendData()`.
Move the protocol agnostic parts of `CConnman::ConnectNode()` into
`SockMan::ConnectAndMakeNodeId()` and leave the Bitcoin-P2P specific
stuff in `CConnman::ConnectNode()`.

Move the protocol agnostic `CConnman::m_unused_i2p_sessions`, its mutex
and `MAX_UNUSED_I2P_SESSIONS_SIZE` to `SockMan`.

Move `GetBindAddress()` from `net.cpp` to `sockman.cpp`.
Move `MaybeFlipIPv6toCJDNS()`, which is Bitcoin P2P specific from the
callers of `CConnman::EventNewConnectionAccepted()` to inside that
method.

Move the IsSelectable check, the `TCP_NODELAY` option set and the
generation of new node id out of `CConnman::EventNewConnectionAccepted()`
because those are protocol agnostic. Move those to a new method
`SockMan::NewSockAccepted()` which is called instead of
`CConnman::EventNewConnectionAccepted()`.
Move `CNode::m_sock` and `CNode::m_i2p_sam_session` to `SockMan::m_connected`.
Also move all the code that handles sockets to `SockMan`.

`CNode::CloseSocketDisconnect()` becomes
`CConnman::MarkAsDisconnectAndCloseConnection()`.

`CConnman::SocketSendData()` is renamed to
`CConnman::SendMessagesAsBytes()` and its sockets-touching bits are moved to
`SockMan::SendBytes()`.

`CConnman::GenerateWaitSockets()` goes to
`SockMan::GenerateWaitSockets()`.

`CConnman::ThreadSocketHandler()` and
`CConnman::SocketHandler()` are combined into
`SockMan::ThreadSocketHandler()`.

`CConnman::SocketHandlerConnected()` goes to
`SockMan::SocketHandlerConnected()`.

`CConnman::SocketHandlerListening()` goes to
`SockMan::SocketHandlerListening()`.
`SockMan` members

`AcceptConnection()`
`NewSockAccepted()`
`GetNewNodeId()`
`m_i2p_sam_session`
`m_listen private`

are now used only by `SockMan`, thus make them private.
@Sjors Sjors force-pushed the 2024/06/sv2_connection branch from 4ba3ba8 to a3a7a46 Compare December 19, 2024 06:12
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.

3 participants