diff options
| author | Bitflash <btf01@proton.me> | 2026-07-29 14:11:58 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-29 14:11:58 -0300 |
| commit | 41b2ba748531605a1afd84fdb967330c0efc529f (patch) | |
| tree | 4675efd69a09bee537bb7606bd895bd1a4995827 /src/net.h | |
| parent | 997e511e120272e8f2ddd29716b486e597410f02 (diff) | |
net: exchange signed .btf descriptors between peers (#32)
Discovery has depended entirely on the Nostr relays. Two connected nodes never
told each other who else existed, so a relay outage left a running network
unable to grow, and a node that found one stale peer had no way to learn there
was anything better. The old `addr` gossip went out with the IRC seed.
Peers now trade signed descriptors over a new "btfpeers" message: our own
first, then peers that actually answered us. The receiver checks each Schnorr
signature against the key the `.btf` address decodes to, so the sender is
trusted for nothing -- forging an entry needs somebody else's secret key. That
leaves flooding with self-generated keys, which the per-message caps and the
"peers that answered" ordering are there to blunt.
Unknown commands are ignored (main.cpp), so nodes without this just drop the
message; nothing here is a protocol break.
The cache from the peer-cache change now keeps each peer's descriptor verbatim
alongside the parsed fields, because that signature is what makes a peer
relayable. Entries without one -- resolved through Nostr, or written before
this -- stay dialable, just not passed on. A dial never clears a descriptor
already on file.
Diffstat (limited to 'src/net.h')
| -rw-r--r-- | src/net.h | 19 |
1 files changed, 19 insertions, 0 deletions
| @@ -29,6 +29,21 @@ CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting | |||
| 29 | void ThreadBtfAccept(void* parg); | 29 | void ThreadBtfAccept(void* parg); |
| 30 | void ThreadBtfConnect(void* parg); | 30 | void ThreadBtfConnect(void* parg); |
| 31 | extern string strBtfConnect; | 31 | extern string strBtfConnect; |
| 32 | |||
| 33 | // --- .btf peer exchange --------------------------------------------------- | ||
| 34 | // Peers gossip signed descriptors so discovery survives a relay outage. Both | ||
| 35 | // caps apply to a single "btfpeers" message; the generic header limit is 256 MB, | ||
| 36 | // which is no protection at all for something a stranger can send unprompted. | ||
| 37 | static const unsigned int MAX_PEX_DESCRIPTORS = 20; | ||
| 38 | static const unsigned int MAX_PEX_DESCRIPTOR_BYTES = 1024; | ||
| 39 | // Ignore a peer's exchange more often than this. One announcement per side per | ||
| 40 | // connection is the intended traffic; anything faster is someone else's idea. | ||
| 41 | static const int64 PEX_MIN_INTERVAL = 60; | ||
| 42 | |||
| 43 | // Descriptors to hand a peer: ours first, then peers that answered us. | ||
| 44 | void BtfPexCollect(std::vector<std::string>& vDescOut); | ||
| 45 | // Verify descriptors a peer sent and remember the good ones. Returns how many. | ||
| 46 | int BtfPexAccept(const std::vector<std::string>& vDesc); | ||
| 32 | void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); | 47 | void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); |
| 33 | bool AnySubscribed(unsigned int nChannel); | 48 | bool AnySubscribed(unsigned int nChannel); |
| 34 | void ThreadBitcoinMiner(void* parg); | 49 | void ThreadBitcoinMiner(void* parg); |
| @@ -467,6 +482,9 @@ public: | |||
| 467 | // publish and subscription | 482 | // publish and subscription |
| 468 | vector<char> vfSubscribe; | 483 | vector<char> vfSubscribe; |
| 469 | 484 | ||
| 485 | // Last "btfpeers" we accepted from this node, to rate-limit the exchange. | ||
| 486 | int64 nLastPexRecv; | ||
| 487 | |||
| 470 | 488 | ||
| 471 | CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) | 489 | CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) |
| 472 | { | 490 | { |
| @@ -483,6 +501,7 @@ public: | |||
| 483 | fDisconnect = false; | 501 | fDisconnect = false; |
| 484 | nRefCount = 0; | 502 | nRefCount = 0; |
| 485 | nReleaseTime = 0; | 503 | nReleaseTime = 0; |
| 504 | nLastPexRecv = 0; | ||
| 486 | vfSubscribe.assign(256, false); | 505 | vfSubscribe.assign(256, false); |
| 487 | 506 | ||
| 488 | // Push a version message | 507 | // Push a version message |