-
Notifications
You must be signed in to change notification settings - Fork 20.9k
core, eth: enforce network split post DAO hard-fork #2795
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
Conversation
Updated: Wed Jul 20 02:22:26 UTC 2016 |
Would it be better if p2p network selectivity was a general capability available to support any main-chain fork? The code is written in a way that makes it appear very DAO specific. Also if a node administrator wanted to support DAO protocol rules, but relay transactions for both networks, would they be able to do that? What happens if a client lies? |
Why is so much code being added specifically for a bug within a contract? Do you not see how poor this solution is if it requires this many fundamental changes specific to this single event and not more general tools? It would be easier to swallow of these changes were general and not DAO specific. The geth is the primary client, you should not be making it so specific, you should be making it generic as possible. Making it easier to work with private networks so proper testing is easier to accomplish.
This is the basic question anyone should ask whenever building anything. If this is not always on your mind you are making insecure software. |
@julian1 Yes, it would be better to have generic selectivity. There are plans already to extend the discovery protocol (these are very old plans, no idea when they'll get implemented) + a nicer solutions would be to modify the No, a node operator shouldn't be able to relay transactions for both networks. Sooner or later those will not be compatible (i.e. non-executable transactions), which would just burden each others' networks. Is there a particular reason it's desirable? @julian1 @whatisgravity We always have in mind that clients might lie. In this particular case, a client may lie, will get connected, but at a consensus level will not be able to feed junk because of the header extra-data section validations. Think of this check similar to CORS: the idea is to prevent nodes en-mass to make cross-network connections, causing strange anomalies. You can of course do that with your particular node(s), but as long as the majority plays nice, a few bad apples can't cause too big issues.
That's exactly what we've been trying to do with this PR collection. I can't program a generic forker because there's no telling what a fork will include, so there's no point in programming it as it will most probably be wrong (also time is of essence here). However I did try to make this DAO specific fork as generic as possible (configurable via genesis.json, override flags, etc), specifically to make them properly testable in private networks. Further, I've also written a client tester/simulator specifically for this case, to simulate networks of (arbitrary) clients and test various aspects of them in a client-independent and even tester-independent way. The tester is called |
25e949a
to
44f2020
Compare
@karalabe Regarding p2p network partitioning. If a node receives a block with an invalid transaction (considered from the perspective of whatever protocol rules it follows) then it will not relay the block to its immediately connected p2p peers. Since block propagation gets interrupted at the first-step - won't the network partition itself quickly and automatically - simply by having peers disconnect from other peers that relay bad-blocks? Was this able to be tested in simulation? Also, would convergence on the partitioned state be aided by being able to tune disconnection policy to be more aggressive. (For example disconnect from a peer if it sends 1 bad-block in the last 3)? I wonder if that would alleviate the need to hard-code/duplicate flags indicating protocol choices in block headers? I worry that if Ethereum ends up being forked many times in future - then we will end up with a whole matrix of little header flags creating a lot of complicated logic as well as maintenance debt. |
Currently block propagation is done in two phases: a new block's header is verified (PoW included) and if everything checks out, the block is already propagated to log(n) nodes. It is then tried to be imported, and if import succeeds the block is announced to everyone else. The idea was that blocks seeming good should propagate as fast as possible through the network. This also means however that unless we remove the quick propagation mechanism, the network will fall apart if we start dropping nodes since from the quick-check's perspective states cannot be verified, so by the time it turns out to be rotten, everyone has it. Regarding header content, that is mostly needed for the transition period when there's no "pro-fork" and/or "no-fork" headers to checkpoint with. Given that these hard forks are mostly protocol upgrades and there's little reason to support the minority (nor is there a reason to support these transitions in private networks), it is possible to switch out the mechanism to checkpointing after the fork passed and everything stabilized. (If however for whatever reason we need to support both camps longer, that can be ugly fast). |
I'm still not sure how this solution really prevents either network from creating modified clients to relay valid transactions to the other network complicating the split. |
Isn't there already a Ps thanks for going to these great lengths to keep both networks operating, its truly appreciated. |
Superseeded and merged in #2814. |
support |
Prerequisite PRs, merge these first to get rid of duplicate commits:
This PR is meant to enforce the network split after passing the DAO hard-fork block number. It is done by requesting the DAO fork-block's header immediately after an
eth
handshake completes. If the DAO challenge isn't completed within15 seconds
, the connection is dropped.To complete the DAO challenge, the remote peer must reply with the requested header (every peer will do so, it's how the
eth
protocol works). A few things can happen: