-
Notifications
You must be signed in to change notification settings - Fork 120
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
T2. Add isolated Tor connection API, but don't enable it by default #3303
Conversation
0f76943
to
a9104ff
Compare
8fccc5d
to
4593eed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall, I only added some minor things. It would be nice if the test vectors were refactored a bit to reduce repeated code though.
8c2630b
to
1fe25a9
Compare
1fe25a9
to
f238100
Compare
94122f0
to
ff2e152
Compare
Codecov Report
@@ Coverage Diff @@
## main #3303 +/- ##
==========================================
- Coverage 78.43% 78.42% -0.02%
==========================================
Files 267 267
Lines 31530 31526 -4
==========================================
- Hits 24732 24724 -8
- Misses 6798 6802 +4 |
@Mergifyio update |
✅ Branch has been successfully updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved! Yay, progress towards getting Tor support in Zebra :D
/// Returns a new tor client instance, and updates [`SHARED_TOR_CLIENT`]. | ||
/// | ||
/// If there is a bootstrap error, [`SHARED_TOR_CLIENT`] is not modified. | ||
async fn new_tor_client() -> Result<TorClient<TokioRuntimeHandle>, BoxError> { | ||
let runtime = tokio::runtime::Handle::current(); | ||
let runtime = TokioRuntimeHandle::new(runtime); | ||
let tor_client = TorClient::bootstrap(runtime, TorClientConfig::default()).await?; | ||
|
||
// # Correctness | ||
// | ||
// It is ok for multiple tasks to race, because all tor clients have identical configs. | ||
// And all connections are isolated, regardless of whether they use a new or cloned client. | ||
// (Any replaced clients will be dropped.) | ||
let mut shared_tor_client = SHARED_TOR_CLIENT | ||
.lock() | ||
.expect("panic in shared tor client mutex guard"); | ||
*shared_tor_client = Some(tor_client.isolated_client()); | ||
|
||
Ok(tor_client) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I gave similar feedback to the Tor team, and they have opened a ticket to improve the API:
https://forum.zcashcommunity.com/t/arti-a-pure-rust-tor-implementation-for-zcash-and-beyond/38776/58?u=teor
I expect we will rewrite this code when we upgrade to the next arti
version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But here's what's going on in detail:
connect_isolated_tor
either boostraps a new client, or creates an isolated clone of the shared client instance.
new_tor_client
is a once-off method for bootstrapping a new client.
The isolated_client
method ensures that the shared client's streams are on different circuits from the returned client's streams. (And if multiple initial connections race, and bootstrap multiple clients, all their streams are independent, because they make independent connections.)
cloned_tor_client
is the method for cloning a new isolated client. It calls isolated_client
for each clone.
Is there any upside (from a privacy-only standpoint, I don't care about other aspects) to use The latter proxies everything through tor, and its the way I've been using zebra so far. |
Currently, Zebra does not send any data through In the future, Zebra might send user-generated transactions through We want to avoid syncing the entire blockchain over Tor. If hundreds of Zebra clients did that, it would put a lot of load on the Tor network. Particularly after a Zebra database upgrade, when nodes sync the full chain again.
I'm glad to know that this configuration works! I think this configuration is fine in general. But there are some things you should be aware of. Zebra's initial sync of 20 GB of Zcash blockchain data might make you stand out on the Tor network. This could reduce your anonymity, even when using Tor. (Zebra does an initial sync every time the database format changes.) Since all the blockchain data is public, and Zebra doesn't generate transactions yet, there isn't much sensitive information that gets hidden using Tor. Some possibly sensitive data is the block you're currently syncing, the exact content of your node's mempool, and the fact that your home IP address is using Zcash. |
Motivation
When Zebra sends user-generated transactions over the internet, the transaction IDs can be linked to the sending and receiving IP addresses. This can link people with specific Zcash transfers. (But the amount of information disclosed is much less for fully shielded transactions.)
But if we send user-generated transactions over Tor, it's much harder to link them to the sender's IP address.
It's ok to merge this PR because:
arti
dependency is a specific public crate patch release, so it won't change unless we change itarti
releaseSolution
Tor API:
Dependencies:
Tests:
Close #1643
Review
This PR is ready for review, but it's based on PR #3302, so we should keep it in draft until that PR merges.
Let's assign reviewers when people are back from leave.
Reviewer Checklist
cargo test --features tor