Commit Graph

24 Commits

Author SHA1 Message Date
tomFlowee 6ade318b2e Introduce interleaving during download
The download from a peer is now limited to just 4000 blocks, at which
point the download proceeds from another peer.
Naturally it can go back to the first afterwards too.

The idea is that we download a month worth of blocks at a time and then
fetch the same blocks from a backup peer in order to be certain we
actually see the real state.
The problem we've seen is that after the first downloads we end up
starting the second and if the initial sync or a similar large download
happens, many people won't leave it running until the backup actually
completes since the UI looks like its finished.

This is also a good starting point for rating peers at download speed by
having predictable chunks and that means we could time and aim to use
the faster peers.
This is becoming relevant as we can see a huge difference where peers
give you 10x performance compared to some of the slower ones.
2024-02-23 22:08:28 +01:00
tomFlowee 4fe9d69e7b Use more specific define-guards 2024-01-24 21:03:58 +01:00
tomFlowee c6302bd7c0 Limit the amount of times we send mempool 2023-04-06 13:32:30 +02:00
tomFlowee 1d309cd7ae P2PNet: re-do SVP's bloom filter and mempool.
Every peer that we connect to should get the bloom filter set and it
should also get the 'mempool' call sent once which will make that peer
respond with all matches of the bloom filters which are in the mempool.

The tricky part is that we should have the latest bloom filter set on
each of those peers before the mempool is sent, since they work
together.
Also if we are behind, the mempool should not be sent. (It can cause
problems in the wallet if we receive unconfirmed transactions before
mined transactions)

So, when a peer starts downloading merkle blocks, the bloom filter of all
the other peers becomes invalid the moment a match is found by an actual
wallet.
This is Ok on one peer because the merkleblock automatically updates the
filter on match on the server side, but obviously not on the other peers
we have for that wallet.

The approach we follow is that as soon as a sync-run is done on a single
peer (we do a main and also a backup sync), we tell the wallet to re-
build its bloom filter for _all_ peers and if the sync that peer did
leads us to be at the chain-tip, we also send each peer the mempool
command.
2023-04-01 22:54:35 +02:00
tomFlowee aa6f0676a3 Docs improvements. Mostly API docs 2023-03-27 15:19:05 +02:00
tomFlowee 70e4f2292e Refactor the SPV merkleblock/mempool sending
Tuesdays idea of adding some code into the SyncSPVAction didn't feel
right.
A second look made clear that bloom filter updates make much more sense
to go hand in hand with sending a mempool message. Especially since they
depend on each other on the server side.

To-rehash:
the wallet may decide at any time that a new bloom filter is needed. It
then uses the superclass (code in p2plib) PrivacySegment, to build that
filter. As part of that we get a lock object which, when going out of
scope, makes the peers that are subscribed to the privacySegment send
out the filter.

This separation of concerns means that the subclass wallet in the app
doens't know about peers or messages, only its superclass PrivacySegment
does.

What we did in this change is make the PrivacySegment class decide to
combine a bloom update with a mempool call. Typicall only once per
connection.

This means I can remove hacks in the SyncSPVAction which forced the
sending of the mempool message separately.
2023-02-24 19:41:42 +01:00
tomFlowee 58afd8ab6a Make compile with older libc 2022-09-13 20:30:38 +02:00
tomFlowee 62a6f5c7d9 Cleanups in spv sync for multiple peers
This makes the logic much more pridictable.
2022-07-13 14:00:47 +02:00
tomFlowee c71ebb9bee Avoid reporting incorrect updates 2021-11-26 18:10:31 +01:00
tomFlowee 4411ecb2e5 Fix API docs. 2021-07-30 14:03:03 +02:00
tomFlowee adfe4081cb Update copyright notice and email address 2021-02-02 13:08:07 +01:00
TomZ 301a4ca3ee Fix properly following the chain-tip
This is done in several steps:

1. Separate my height from the remote peer heights.
Instead of assuming we have one height, recognize that a peer may
not be at the tip at the same time we are. We monitor headers/invs
to update the 'peerHeight' variable.

2. Ask for merkle blocks from a peer to the maximum height of that
peer (but not later than what we validated to be true).
This avoids us asking past the remotes tip which they didn't like.

3. Redo the SyncSPVAction to use all this and make it much more
reliable in finding peers to download from and getting all the
changes as fast as possible.
2020-11-13 21:03:56 +01:00
TomZ 0556bc56d1 Fix bugs in SPV sync behavior. 2020-11-09 18:38:38 +01:00
TomZ 652fc1e161 Introduce structure to broadcast transactions.
To send out transactions in the p2p net is quite a lot of work,
you need to find multiple peers to send the transaction to. First
you send an INV, then you respond to a getData to actually send
the transaction and last you wait for 'reject' messages that may
indicate that there is something wrong with the transaction.

This introduces the BroadcastTxData class that wraps a transaction
and gets callbacks for sending and for rejects, abstracting away
all the complexity for the user.
2020-06-08 21:35:10 +02:00
TomZ 45d9ac3bd2 Make Peer listen to Bloom filter changes 2020-05-18 14:32:34 +02:00
TomZ 01e8bcfb09 Announce all transactions per block at once.
Instead of forwarding one transaction at a time as the peer sends them
to us, bundle them in a group of transactions known to be merkle-checked
and all belonging together in one block.

Since the peer has no obligation (and with CTOR even less) to send the
transactions in natural order, we should get them per block so we know
all transactions forwarded have parents.
2020-05-16 11:01:27 +02:00
TomZ 148f9c0e93 Improve tracking of 'good' peers.
This avoids a peer once sending acceptable headers and never
being bothered again. Instead we now check regularly and keep
track of when the peer was known to follow the same chain as us.
2020-05-11 18:49:16 +02:00
TomZ d49b1ae5e2 Make NetworkManager connections leaner
The NetworkManager usage was mostly for low connection counts and this
made defaults selection easy.
With more usages it is important to allow the NWM-connection to be more
configurable about memory usage and leaner in general.

This changes the headers-buffers (used to create envelopes) to not be per
connection anymore but per thread using the tread_local keyword.

This changes the ring-buffers to become configurable using
NetworkConnections::setMessageQueueSizes().

Also removing some include statements where they were not really needed
in the P2PNet lib.
2020-05-09 20:23:05 +02:00
TomZ 7ad2592d40 P2PNet: API cleanups and review + docs. 2020-05-06 10:42:58 +02:00
TomZ fb6f91bf79 Simplify p2pnet ownership
Make the Peer object be owned by a shared pointer.
2020-05-05 22:53:25 +02:00
TomZ 3f16f6224a Fix the threading model in the P2PNet
This allows deletion of peers also from other threads than their own
assigned ones.
2020-05-03 21:02:45 +02:00
TomZ 2298df4935 Make peer shutdown safer.
This avoids a race condition on remove/delete of peer where
the connection manager decides to delete a peer while in its own thread
the peer is processing a package.
This moves deletion of the peer to its own strand.
2020-04-27 15:47:15 +02:00
TomZ 6e10b8d435 P2PNet: Fixes and some new methods 2020-04-26 16:20:45 +02:00
TomZ 25ffc84f80 Introduce new lib p2p
We reuse the NetworkManager lower level code in order to connect
to the Bitcoin P2P network.
This implements the basics for anyone wanting to be a player on
this network.
2020-04-20 21:49:03 +02:00