Skip to content
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

whisper: PoW requirement #15701

Merged
merged 12 commits into from
Dec 21, 2017
Merged

whisper: PoW requirement #15701

merged 12 commits into from
Dec 21, 2017

Conversation

gluk256
Copy link
Contributor

@gluk256 gluk256 commented Dec 18, 2017

New Whisper-level message introduced (PoW requirement), corresponding logic added, plus some tests.

sendMsg(t, true, 0)
checkPropagation(t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should create two unit tests, both with a specific name. You want tests to be as specific as possible, to pinpoint the root cause quicker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally yes, but this case is special. this is already the worst whisper test (in terms of duration), because initialization takes too long. if i splitted the test, it would take double to run it. and it is already quite bad.

w.settings.Store(minPowIdx, val)
} else {
go func() {
// // allow some time before all the peers have processed the notification
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment / uncomment error :)


w.notifyPeersAboutPowRequirementChange(val)

if testMode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why making such a big difference between the tests and the regular code? If the real function waits, the tests should too.

Copy link
Contributor Author

@gluk256 gluk256 Dec 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

real function waits for a reason, which is related to syncronization in real-life environment. in test environment it does not make much sense. but if this test will run longer than all other tests together, than it will be really painful to run the tests every time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand it might take longer to run the test, at the same time running the whole list of tests is really long because of swarm so I would not lose sleep over this. What you can also do, is configure the waiting time to be different in the case of a test environment, so the code remains the same but the wait time is shorter for tests. That would ensure that the code that is being tested is the same as that which runs in production.

I have been looking for a way to distinguish a normal build from a test build in the doc, haven't found anything so far. Anything else that the powers that be have decided you don't need?

If you manage to do that, then my recommendation in the previous comment doesn't need to happen.

return nil
}

func (w *Whisper) notifyPeersAboutPowRequirementChange(pow float64) {
w.peerMu.Lock()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing network stuff in a critical section, that's a long waiting time while holdig a mutex. Could you do something lighter, e.g. starting a goroutine to do this? Or copy the list ? How contentious do we expect that list to be, and how much of a problem is it going to be if a peer is removed/added?

return errors.New("invalid powRequirementCode message")
}
f := math.Float64frombits(i)
if math.IsInf(f, 0) || math.IsNaN(f) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And negative/zero values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zero allowed, but not negative

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I misread what IsInf was doing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, no I didn't. You also need to make sure that the PoW is positive

return false, nil // drop envelope without error
return false, nil // drop envelope without error for now

// after the Status message will include the PoW requirement, it should return an error here:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once the status message includes the PoW requirement, an error should be returned here

@@ -176,14 +181,41 @@ func (w *Whisper) SetMaxMessageSize(size uint32) error {
}

// SetMinimumPoW sets the minimal PoW required by this node
func (w *Whisper) SetMinimumPoW(val float64) error {
func (w *Whisper) SetMinimumPoW(val float64, testMode bool) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would make more sense to Mock SetMinimumPoW during your tests instead of explicitly changing the function interface to specify if this is a test or not. Many things can slip through the cracks this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean, i should create another function, e.g. SetMinimumPowTest?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, have a Whisper as an interface that implements SetMinimumPoW. Then, in tests, implement the Whisper interface as a WhisperMock structure and implement a different SetMinimumPoW for this. However, as I'm saying below, I think this is overkill when you can simply use the same function in both cases.

Copy link
Member

@gballet gballet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still like the critical section to be checked, but I'm preparing to work on a scalability test in January and I guess it can be covered then.

@gluk256
Copy link
Contributor Author

gluk256 commented Dec 21, 2017

"Premature optimization is the root of all evil"
this function will be called once per hour, or even once per day.
at this point its performance is more than sufficiant.

@fjl
Copy link
Contributor

fjl commented Dec 21, 2017

Please rebase

@fjl
Copy link
Contributor

fjl commented Dec 21, 2017

nevermind, done.

@fjl fjl merged commit 38b1e8e into ethereum:master Dec 21, 2017
@karalabe karalabe added this to the 1.8.0 milestone Dec 21, 2017
mariameda pushed a commit to NiluPlatform/go-nilu that referenced this pull request Aug 23, 2018
New Whisper-level message introduced (PoW requirement),
corresponding logic added, plus some tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants