Skip to content

Commit 76b8ffd

Browse files
0a23820 merge bitcoin#27937: i2p documentation updates (Kittywhiskers Van Gogh) 1dc50d0 merge bitcoin#26838: I2P documentation updates (Kittywhiskers Van Gogh) 5058519 merge bitcoin#25993: Add I2P guidance related to bandwidth and i2pd software version (Kittywhiskers Van Gogh) 859f59b merge bitcoin#26837: I2P network optimizations (Kittywhiskers Van Gogh) 9f80734 merge bitcoin#26065: use the same destination type for transient and persistent addresses (Kittywhiskers Van Gogh) 9bf3829 merge bitcoin#25355: add support for transient addresses for outbound connections (Kittywhiskers Van Gogh) 4977073 merge bitcoin#22497: remove ResetI2PPorts() (Kittywhiskers Van Gogh) 63d5853 merge bitcoin#22648: improve i2p/tor docs and i2p reachable unit tests (Kittywhiskers Van Gogh) f04ce8b partial bitcoin#22229: consolidate to f-strings (part 1) (Kittywhiskers Van Gogh) 68ea6cc merge bitcoin#22589: update I2P hardcoded seeds and docs for 22.0 (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * Dependent on dashpay#6034 ## Breaking Changes * With I2P connections, a new, transient address is used for each outbound connection if `-i2pacceptincoming=0`. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: re-utACK [0a23820](dashpay@0a23820); only changed commit title / text Tree-SHA512: ef426263d7e81a5eec8555db21dcd24f5dbb65f5faa7013c7e0601a4c60ae675813aadf68ebc19936aa15bdbd8f6db88b4bd55dfaf4ac412abbda86fb1ac9c83
2 parents 74a10a8 + 0a23820 commit 76b8ffd

File tree

16 files changed

+372
-341
lines changed

16 files changed

+372
-341
lines changed

doc/i2p.md

Lines changed: 114 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,33 @@ started with I2P terminology.
99

1010
## Run Dash Core with an I2P router (proxy)
1111

12-
A running I2P router (proxy) with [SAM](https://geti2p.net/en/docs/api/samv3)
13-
enabled is required (there is an [official one](https://geti2p.net) and
14-
[a few alternatives](https://en.wikipedia.org/wiki/I2P#Routers)). Notice the IP
15-
address and port the SAM proxy is listening to; usually, it is
16-
`127.0.0.1:7656`. Once it is up and running with SAM enabled, use the following
17-
Dash Core options:
12+
A running I2P router (proxy) is required with the [SAM](https://geti2p.net/en/docs/api/samv3)
13+
application bridge enabled. The following routers are recommended for use with Dash Core:
14+
15+
- [i2prouter (I2P Router)](https://geti2p.net), the official implementation in
16+
Java. The SAM bridge is not enabled by default; it must be started manually,
17+
or configured to start automatically, in the Clients page in the
18+
router console (`http://127.0.0.1:7657/configclients`) or in the `clients.config` file.
19+
- [i2pd (I2P Daemon)](https://github.com/PurpleI2P/i2pd)
20+
([documentation](https://i2pd.readthedocs.io/en/latest)), a lighter
21+
alternative in C++. It enables the SAM bridge by default.
22+
23+
Note the IP address and port the SAM proxy is listening to; usually, it is
24+
`127.0.0.1:7656`.
25+
26+
Once an I2P router with SAM enabled is up and running, use the following Dash
27+
Core configuration options:
1828

1929
```
2030
-i2psam=<ip:port>
2131
I2P SAM proxy to reach I2P peers and accept I2P connections (default:
2232
none)
2333
2434
-i2pacceptincoming
25-
If set and -i2psam is also set then incoming I2P connections are
26-
accepted via the SAM proxy. If this is not set but -i2psam is set
27-
then only outgoing connections will be made to the I2P network.
28-
Ignored if -i2psam is not set. Listening for incoming I2P
29-
connections is done through the SAM proxy, not by binding to a
30-
local address and port (default: 1)
35+
Whether to accept inbound I2P connections (default: 1). Ignored if
36+
-i2psam is not set. Listening for inbound I2P connections is
37+
done through the SAM proxy, not by binding to a local address and
38+
port.
3139
```
3240

3341
In a typical situation, this suffices:
@@ -36,26 +44,68 @@ In a typical situation, this suffices:
3644
dashd -i2psam=127.0.0.1:7656
3745
```
3846

39-
The first time Dash Core connects to the I2P router, its I2P address (and
40-
corresponding private key) will be automatically generated and saved in a file
41-
named `i2p_private_key` in the Dash Core data directory.
42-
4347
## Additional configuration options related to I2P
4448

45-
You may set the `debug=i2p` config logging option to have additional
46-
information in the debug log about your I2P configuration and connections. Run
47-
`dash-cli help logging` for more information.
49+
```
50+
-debug=i2p
51+
```
52+
53+
Set the `debug=i2p` config logging option to see additional information in the
54+
debug log about your I2P configuration and connections. Run `dash-cli help
55+
logging` for more information.
56+
57+
```
58+
-onlynet=i2p
59+
```
60+
61+
Make outgoing connections only to I2P addresses. Incoming connections are not
62+
affected by this option. It can be specified multiple times to allow multiple
63+
network types, e.g. onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p.
64+
65+
Warning: if you use -onlynet with values other than onion, and the -onion or
66+
-proxy option is set, then outgoing onion connections will still be made; use
67+
-noonion or -onion=0 to disable outbound onion connections in this case.
4868

49-
It is possible to restrict outgoing connections in the usual way with
50-
`onlynet=i2p`. I2P support was added to Dash Core in version 20.0 (fall 2023)
51-
and there may be fewer I2P peers than Tor or IP ones. Therefore, using
52-
`onlynet=i2p` alone (without other `onlynet=`) may make a node more susceptible
53-
to [Sybil attacks](https://en.dash.it/wiki/Weaknesses#Sybil_attack). Use
69+
I2P support was added to Dash Core in version 20.0 and there may be fewer I2P
70+
peers than Tor or IP ones. Therefore, using I2P alone without other networks may
71+
make a node more susceptible to [Sybil
72+
attacks](https://en.bitcoin.it/wiki/Weaknesses#Sybil_attack). You can use
5473
`dash-cli -addrinfo` to see the number of I2P addresses known to your node.
5574

56-
## I2P related information in Dash Core
75+
Another consideration with `onlynet=i2p` is that the initial blocks download
76+
phase when syncing up a new node can be very slow. This phase can be sped up by
77+
using other networks, for instance `onlynet=onion`, at the same time.
78+
79+
In general, a node can be run with both onion and I2P hidden services (or
80+
any/all of IPv4/IPv6/onion/I2P), which can provide a potential fallback if one
81+
of the networks has issues.
82+
83+
## Persistent vs transient I2P addresses
84+
85+
The first time Dash Core connects to the I2P router, it automatically
86+
generates a persistent I2P address and its corresponding private key by default
87+
or if `-i2pacceptincoming=1` is set. The private key is saved in a file named
88+
`i2p_private_key` in the Dash Core data directory. The persistent I2P
89+
address is used for making outbound connections and accepting inbound
90+
connections.
91+
92+
In the I2P network, the receiver of an inbound connection sees the address of
93+
the initiator. This is unlike the Tor network, where the recipient does not
94+
know who is connecting to it.
5795

58-
There are several ways to see your I2P address in Dash Core:
96+
If your node is configured by setting `-i2pacceptincoming=0` to not accept
97+
inbound I2P connections, then it will use a random transient I2P address for
98+
itself on each outbound connection to make it harder to discriminate,
99+
fingerprint or analyze it based on its I2P address.
100+
101+
I2P addresses are designed to be long-lived. Waiting for tunnels to be built
102+
for every peer connection adds delay to connection setup time. Therefore, I2P
103+
listening should only be turned off if really needed.
104+
105+
## Fetching I2P-related information from Dash Core
106+
107+
There are several ways to see your I2P address in Dash Core if accepting
108+
incoming I2P connections (`-i2pacceptincoming`):
59109
- in the debug log (grep for `AddLocal`, the I2P address ends in `.b32.i2p`)
60110
- in the output of the `getnetworkinfo` RPC in the "localaddresses" section
61111
- in the output of `dash-cli -netinfo` peer connections dashboard
@@ -73,8 +123,7 @@ to connect to the I2P network. Any I2P router that supports it can be used.
73123

74124
## Ports in I2P and Dash Core
75125

76-
Dash Core uses the [SAM v3.1](https://geti2p.net/en/docs/api/samv3)
77-
protocol. One particularity of SAM v3.1 is that it does not support ports,
126+
One particularity of SAM v3.1 is that it does not support ports,
78127
unlike newer versions of SAM (v3.2 and up) that do support them and default the
79128
port numbers to 0. From the point of view of peers that use newer versions of
80129
SAM or other protocols that support ports, a SAM v3.1 peer is connecting to them
@@ -85,3 +134,40 @@ listening port to 0 when listening for incoming I2P connections and advertises
85134
its own I2P address with port 0. Furthermore, it will not attempt to connect to
86135
I2P addresses with a non-zero port number because with SAM v3.1 the destination
87136
port (`TO_PORT`) is always set to 0 and is not in the control of Dash Core.
137+
138+
## Bandwidth
139+
140+
By default, your node shares bandwidth and transit tunnels with the I2P network
141+
in order to increase your anonymity with cover traffic, help the I2P router used
142+
by your node integrate optimally with the network, and give back to the network.
143+
It's important that the nodes of a popular application like Dash contribute
144+
as much to the I2P network as they consume.
145+
146+
It is possible, though strongly discouraged, to change your I2P router
147+
configuration to limit the amount of I2P traffic relayed by your node.
148+
149+
With `i2pd`, this can be done by adjusting the `bandwidth`, `share` and
150+
`transittunnels` options in your `i2pd.conf` file. For example, to limit total
151+
I2P traffic to 256KB/s and share 50% of this limit for a maximum of 20 transit
152+
tunnels:
153+
154+
```
155+
bandwidth = 256
156+
share = 50
157+
158+
[limits]
159+
transittunnels = 20
160+
```
161+
162+
Similar bandwidth configuration options for the Java I2P router can be found in
163+
`http://127.0.0.1:7657/config` under the "Bandwidth" tab.
164+
165+
Before doing this, please see the "Participating Traffic Considerations" section
166+
in [Embedding I2P in your Application](https://geti2p.net/en/docs/applications/embedding).
167+
168+
In most cases, the default router settings should work fine.
169+
170+
## Bundling I2P in a Dash application
171+
172+
Please see the "General Guidance for Developers" section in https://geti2p.net/en/docs/api/samv3
173+
if you are developing a downstream application that may be bundling I2P with Dash.

doc/release-notes-25355.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
P2P and network changes
2+
-----------------------
3+
4+
- With I2P connections, a new, transient address is used for each outbound
5+
connection if `-i2pacceptincoming=0`.

doc/tor.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ outgoing connections, but more is possible.
5151
-onlynet=onion Make outgoing connections only to .onion addresses. Incoming
5252
connections are not affected by this option. This option can be
5353
specified multiple times to allow multiple network types, e.g.
54-
ipv4, ipv6 or onion. If you use this option with values other
55-
than onion you *cannot* disable onion connections; outgoing onion
56-
connections will be enabled when you use -proxy or -onion. Use
57-
-noonion or -onion=0 if you want to be sure there are no outbound
58-
onion connections over the default proxy or your defined -proxy.
54+
onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p.
55+
Warning: if you use -onlynet with values other than onion, and
56+
the -onion or -proxy option is set, then outgoing onion
57+
connections will still be made; use -noonion or -onion=0 to
58+
disable outbound onion connections in this case.
5959

6060
An example how to start the client if the Tor proxy is running on local host on
6161
port 9050 and only allows .onion nodes to connect:

src/addrman.cpp

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <addrman.h>
77

88
#include <hash.h>
9-
#include <i2p.h>
109
#include <logging.h>
1110
#include <netaddress.h>
1211
#include <serialize.h>
@@ -778,100 +777,3 @@ std::vector<bool> CAddrMan::DecodeAsmap(fs::path path)
778777
}
779778
return bits;
780779
}
781-
782-
void CAddrMan::ResetI2PPorts()
783-
{
784-
for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; ++bucket) {
785-
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
786-
const auto id = vvNew[bucket][i];
787-
if (id == -1) {
788-
continue;
789-
}
790-
auto it = mapInfo.find(id);
791-
if (it == mapInfo.end()) {
792-
return;
793-
}
794-
auto& addr_info = it->second;
795-
if (!addr_info.IsI2P() || addr_info.GetPort() == I2P_SAM31_PORT) {
796-
continue;
797-
}
798-
799-
auto addr_info_newport = addr_info;
800-
// The below changes addr_info_newport.GetKey(), which is used in finding a
801-
// bucket and a position within that bucket. So a re-bucketing may be necessary.
802-
addr_info_newport.port = I2P_SAM31_PORT;
803-
804-
// Reposition entries of vvNew within the same bucket because we don't know the source
805-
// address which led to the decision to store the entry in vvNew[bucket] so we can't
806-
// re-evaluate that decision, but even if we could, CAddrInfo::GetNewBucket() does not
807-
// use CAddrInfo::GetKey() so it would end up in the same bucket as before the port
808-
// change.
809-
const auto i_target = addr_info_newport.GetBucketPosition(nKey, true, bucket);
810-
811-
if (i_target == i) { // No need to re-position.
812-
addr_info = addr_info_newport;
813-
continue;
814-
}
815-
816-
// Reposition from i to i_target, removing the entry from i_target (if any).
817-
ClearNew(bucket, i_target);
818-
vvNew[bucket][i_target] = id;
819-
vvNew[bucket][i] = -1;
820-
addr_info = addr_info_newport;
821-
}
822-
}
823-
824-
for (int bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; ++bucket) {
825-
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
826-
const auto id = vvTried[bucket][i];
827-
if (id == -1) {
828-
continue;
829-
}
830-
auto it = mapInfo.find(id);
831-
if (it == mapInfo.end()) {
832-
return;
833-
}
834-
auto& addr_info = it->second;
835-
if (!addr_info.IsI2P() || addr_info.GetPort() == I2P_SAM31_PORT) {
836-
continue;
837-
}
838-
839-
auto addr_info_newport = addr_info;
840-
// The below changes addr_info_newport.GetKey(), which is used in finding a
841-
// bucket and a position within that bucket. So a re-bucketing may be necessary.
842-
addr_info_newport.port = I2P_SAM31_PORT;
843-
844-
const auto bucket_target = addr_info_newport.GetTriedBucket(nKey, m_asmap);
845-
const auto i_target = addr_info_newport.GetBucketPosition(nKey, false, bucket_target);
846-
847-
if (bucket_target == bucket && i_target == i) { // No need to re-position.
848-
addr_info = addr_info_newport;
849-
continue;
850-
}
851-
852-
// Reposition from (bucket, i) to (bucket_target, i_target). If the latter is
853-
// occupied, then move the entry from there to vvNew.
854-
855-
const auto old_target_id = vvTried[bucket_target][i_target];
856-
if (old_target_id != -1) {
857-
CAddrInfo& old_target_info = mapInfo[old_target_id];
858-
859-
old_target_info.fInTried = false;
860-
vvTried[bucket_target][i_target] = -1;
861-
--nTried;
862-
863-
const auto new_bucket = old_target_info.GetNewBucket(nKey, m_asmap);
864-
const auto new_bucket_i = old_target_info.GetBucketPosition(nKey, true, new_bucket);
865-
ClearNew(new_bucket, new_bucket_i);
866-
867-
old_target_info.nRefCount = 1;
868-
vvNew[new_bucket][new_bucket_i] = old_target_id;
869-
++nNew;
870-
}
871-
872-
vvTried[bucket_target][i_target] = id;
873-
vvTried[bucket][i] = -1;
874-
addr_info = addr_info_newport;
875-
}
876-
}
877-
}

src/addrman.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,6 @@ class CAddrMan
464464

465465
RemoveInvalid();
466466

467-
ResetI2PPorts();
468-
469467
Check();
470468
}
471469

@@ -800,14 +798,6 @@ class CAddrMan
800798
//! Remove invalid addresses.
801799
void RemoveInvalid() EXCLUSIVE_LOCKS_REQUIRED(cs);
802800

803-
/**
804-
* Reset the ports of I2P peers to 0.
805-
* This is needed as a temporary measure because now we enforce port 0 and
806-
* only connect to I2P hosts if the port is 0, but in the early days some
807-
* I2P addresses with port 8333 were rumoured and persisted into addrmans.
808-
*/
809-
void ResetI2PPorts() EXCLUSIVE_LOCKS_REQUIRED(cs);
810-
811801
friend class CAddrManTest;
812802
friend class CAddrManDeterministic;
813803
};

0 commit comments

Comments
 (0)