-
Notifications
You must be signed in to change notification settings - Fork 20.4k
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
cmd, eth: add support for --whitelist <blocknum>=<hash>
#18028
Conversation
FYI I've been testing this on ropsten with:
Those were the two blocks that came up during the fork issues as having bad alternatives. |
Thanks! I'll take a deeper look and do some testing later, and I'm unsure about light clients, but one thing: I think it might actually be preferable to not have toml integration on this, since it not good if people use this temporary protection and then leave it in there permanently -- that will just increase the overall network noise. |
Good point, I was actually testing the toml integration and it didn't seem to work ( Also, I just took a stab at light client support here: It seems to work, but I'll leave it outside this PR until we have more clarity if it's needed. One thing it did highlight though is that I defined |
0f2da54
to
d052166
Compare
Ok, I just force pushed a couple updates:
I'll update my light client branch to rebase off that, but won't open a PR for it just yet. |
d052166
to
4633346
Compare
And the light client branch has been force-pushed w/ the same changes: ryanschneider@85d7059 |
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.
LGTM, but I'll do some testing on it aswell
@holiman do you still need to test on your end? |
Sorry, I totally forgot about this one. Looks good to me! |
Could you rebase it to get a new travis run? |
AFAIK you can't specify the same argument multiple times, the former ones will be overwritten by later ones. We should use a comma separated vector for this. Can we just name the flag |
@karalabe I used I'll change the flag to just |
a069613
to
654e545
Compare
Any idea why the lint step on Tarvis is saying that |
@ryanschneider You're using Go 1.10, 1.11 changes some formatting rules. Please update your local installation |
cmd/utils/flags.go
Outdated
@@ -182,6 +182,10 @@ var ( | |||
Name: "lightkdf", | |||
Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", | |||
} | |||
BlockHashWhitelistsFlag = cli.StringSliceFlag{ |
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 don't think we need such a long name for the variable either. WhitelistFlag
should be enough (note, singular too).
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.
Ok, I've force pushed updates as b406a1c57 that changes to a StringFlag
.
cmd/utils/flags.go
Outdated
@@ -182,6 +182,10 @@ var ( | |||
Name: "lightkdf", | |||
Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", | |||
} | |||
BlockHashWhitelistsFlag = cli.StringSliceFlag{ | |||
Name: "whitelist", | |||
Usage: "Reject peers which send non-matching block hashes (<block number>=<hash>)", |
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 think the description would be clearer as:
Comma separated block number-to-hash mappings to enforce (<number>=<hash>)
I don't think we need to mention peers and networking in this code. That's an implementation detail if you use the flag correctly.
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.
Updated in b406a1c57 as well.
common/blockhash_whitelist.go
Outdated
@@ -0,0 +1,37 @@ | |||
package common |
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.
We're trying in general to get rid of the common
package. Lets not add further logic into it. Imho parsing the flags should just be part of the cmd/utils
package as a private method. I also don't really see a reason to specify a custom typ for the whitelist. map[uint64]common.Hash
is a pretty simple and understandable type.
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.
Done in b406a1c57, map[uint64]common.Hash
is used everywhere, no new files in common
now.
I followed the convention seen in that file and added a new setWhitelist(ctx, cfg)
func that does the parsing.
eth/config.go
Outdated
@@ -87,6 +87,9 @@ type Config struct { | |||
SyncMode downloader.SyncMode | |||
NoPruning bool | |||
|
|||
// Block hash whitelist | |||
BlockHashWhitelist *common.BlockHashWhitelist `toml:"-"` |
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.
BlockHashWhitelist
-> Whitelist
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's no reason to use a pointer here. A map can be nil.
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.
Done.
eth/handler.go
Outdated
@@ -88,6 +89,8 @@ type ProtocolManager struct { | |||
txsSub event.Subscription | |||
minedBlockSub *event.TypeMuxSubscription | |||
|
|||
whitelist *common.BlockHashWhitelist |
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's no reason to use a pointer here. A map can be nil.
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.
Done.
eth/handler.go
Outdated
@@ -307,6 +311,18 @@ func (pm *ProtocolManager) handle(p *peer) error { | |||
} | |||
}() | |||
} | |||
|
|||
// If we have any explicit whitelist block hashes, request them | |||
if whitelist := pm.whitelist; whitelist != nil { |
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.
No reason to create this whole assign-the-validate check if you don't use a pointer. A map can be nil, and you can iterate a nil map (will be a noop).
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.
Done.
eth/handler.go
Outdated
@@ -452,6 +468,18 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { | |||
// Filter out any explicitly requested headers, deliver the rest to the downloader | |||
filter := len(headers) == 1 | |||
if filter { | |||
// Check for any responses not matching our whitelist | |||
if whitelist := pm.whitelist; whitelist != nil { |
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.
No reason to create this whole assign-the-validate check if you don't use a pointer. A map can be nil, and you can iterate a nil map (will be a noop).
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.
Done.
eth/handler.go
Outdated
if expected, ok := (*whitelist)[headers[0].Number.Uint64()]; ok { | ||
actual := headers[0].Hash() | ||
if !bytes.Equal(expected.Bytes(), actual.Bytes()) { | ||
p.Log().Debug("dropping peer with non-matching whitelist block", "number", headers[0].Number.Uint64(), "expected", expected, "actual", actual) |
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.
Please capitalize log messages: Dropping
Instead of actual
use hash
and move it as the second context parameter after number.
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.
Done.
eth/handler.go
Outdated
return errors.New("whitelist block mismatch") | ||
} | ||
|
||
p.Log().Debug("whitelist match", "number", headers[0].Number.Uint64(), "expected", expected) |
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.
Please drop the empty line, no use for it. Please make the log message meaningful.
"Whitelist block verified", Please use hash
, not "expected". It's a convention throughout the code.
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.
Done.
eth/handler_test.go
Outdated
{1, nil, nil, 1}, // A single random block should be retrievable | ||
{10, nil, nil, 10}, // Multiple random blocks should be retrievable | ||
{limit, nil, nil, limit}, // The maximum possible blocks should be retrievable | ||
{limit + 1, nil, nil, limit}, // No more than the possible block count should be returned |
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.
You'll need Go 1.11 to not break this gofmt things.
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.
Weird, I've been using Go 1.11 for awhile, but somehow my IDE was still using 1.10 for go fmt
. I re-setup the go fmt support and confirmed it's using Go 1.11 style now, so these changes weren't made in the new commit.
654e545
to
b406a1c
Compare
Ok, I think all of @karalabe concerns have been addressed, sorry if that spammed you with individual updates, I just realized that since I'm not a reviewer they went out one-by-one instead of in a batch. I left the comments unresolved so you can decide if the changes resolve them, though in general I think GH's UX for handling resolution on outdated code leaves a little to be desired, if you have any feedback on how you want me to communicate changes in future PRs I'm all ears. |
--blockhashwhitelists
flag to explicitly whitelist chains containing certain blocks--whitelist <blocknum>=<hash>,...
flag
b406a1c
to
4984ad9
Compare
4984ad9
to
1f84480
Compare
* Rejects peers that respond with a different hash for any of the passed in block numbers. * Meant for emergency situations when the network forks unexpectedly.
1f84480
to
31b3334
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.
LGTM
--whitelist <blocknum>=<hash>,...
flag--whitelist <blocknum>=<hash>,...
flag
--whitelist <blocknum>=<hash>,...
flag--whitelist <blocknum>=<hash>
As discussed with @holiman in #17935.
I'm not sure what the issue I was running into was last time where I thought I needed to do this for the bootnodes, I didn't run into that issue this time when testing.
I think the only remaining question I have is does this need to be implemented for light clients as well?