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

Fix MasternodeRateCheck #1490

Merged
merged 3 commits into from
Aug 23, 2017
Merged

Conversation

the-schnibble
Copy link

@the-schnibble the-schnibble commented Jun 7, 2017

Rationale:

  1. MasternodeRateCheck is working only for watchdog's/trigger's owner when he is creating the object initially. In all other cases, the method always returns true for all the objects with correct timestamp.
  2. The method updates MN's CRateCheckBuffer even if check has failed. Bearing in mind (1) it is not a big problem, but we still can drop this object in some cases (object is invalid, we have this object already or watchdog object doesn't fit required time bounds)

Explanation of the commits:

fixed an issue with MasternodeRateCheck always returns true

This is simple fix for the issue.

Consequences:

Initial call to MasternodeRateCheck is no longer updating the buffer when the rate check fails.
Taking into account another problem discovered in processing of MNGOVERNANCEOBJECT we don't need to update buffer because it won't help to counter spam. But it could cause another problems with governance objects propagation.

We shouldn't update buffer unless we accept the object. Otherwise if we reject some object, update the buffer for it's masternode, but other nodes won't update this (because we didn't relay the object), and then this MN can create another valid object which will be accepted by most of nodes, but rejected by us.

UPDATE_TRUE in MasternodeRateCheck is always returns true, just because we always use this flag when object has accepted and this value doesn't matter. In next commit this part of code changed to "return void".

additioanal fixes and refactoring

This commit is basically refactoring of the code. It's purposed to make buffer updating outside of MasternodeRateCheck.


Some test results for the PR: https://github.com/the-schnibble/dash-tests/blob/master/results/mn_rate_check.txt

The test itself: https://github.com/the-schnibble/dash-tests/blob/master/mn_rate_check.py

Here node1 is a slightly modified masternode which can create triggers with an arbitrary rate to check that the constraint works for others. The test also checks (counts records in the log) that all objects are relayed, accepted and rejected by nodes as expected (I'm using a private testnet with a reduced interval of superblocks, so the test was waiting for 8.46 minutes to check the "rate limit").

@UdjinM6 UdjinM6 changed the base branch from master to v0.12.2.x June 7, 2017 16:17
@UdjinM6 UdjinM6 added this to the 12.2 milestone Jun 7, 2017
@UdjinM6
Copy link

UdjinM6 commented Jun 7, 2017

Needs rebase to fix macos travis ci build

@UdjinM6 UdjinM6 requested a review from tgflynn June 7, 2017 16:33
@UdjinM6 UdjinM6 added the bug label Jun 7, 2017
@the-schnibble the-schnibble force-pushed the check_rates_only branch 3 times, most recently from 73f3624 to a2a9ec6 Compare June 7, 2017 21:48
@@ -863,6 +862,8 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, up
default:
break;
}

it->second.fStatusOK = true;
Copy link

Choose a reason for hiding this comment

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

This line shouldn't be needed because this is set by the last_object_rec constructor (this code only runs for a newly added object).

Copy link
Author

Choose a reason for hiding this comment

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

yes, it is unnecessary

case UPDATE_FAIL_ONLY:
if(!fRateOK) {
pBuffer->AddTimestamp(nTimestamp);
if(!fRateOK)
Copy link

@tgflynn tgflynn Jun 9, 2017

Choose a reason for hiding this comment

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

It looks like the problems you discovered still aren't fixed here.

The break is still missing for the UPDATE_FAIL_ONLY case and all code paths still return true.

Also I don't think UPDATE_TRUE should return true if the rate check fails.

EDIT: OK, I see that there is a path that returns false (I think you should make the break explicit though, not rely on the fall-through behavior which is hard to follow.) I still don't think the UPDATE_TRUE case should be returning true unconditionally.

Copy link
Author

Choose a reason for hiding this comment

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

Actually, we pass UPDATE_TRUE only when the object has been accepted. Would it better to have a separate method for updating the buffer? I have refactored the code and possibly fixed some other issues with CRateCheckBuffer. Here it is: aaeed1c

@the-schnibble the-schnibble changed the title Fixed an issue with MasternodeRateCheck always returns true Fixed an issue with MasternodeRateCheck always returns true [WIP] Jun 9, 2017
@the-schnibble the-schnibble changed the title Fixed an issue with MasternodeRateCheck always returns true [WIP] Fixed an issue with MasternodeRateCheck always returns true Jun 9, 2017
@UdjinM6
Copy link

UdjinM6 commented Jul 4, 2017

needs rebase

@the-schnibble the-schnibble force-pushed the check_rates_only branch 2 times, most recently from 219d7f5 to 1729598 Compare July 4, 2017 15:44
@UdjinM6
Copy link

UdjinM6 commented Jul 4, 2017

Looks like this one is going to conflict with #1489, let's get back to this after #1489 is merged.

@UdjinM6
Copy link

UdjinM6 commented Jul 5, 2017

Needs another rebase (as expected)

@the-schnibble the-schnibble changed the title Fixed an issue with MasternodeRateCheck always returns true [WIP] Fixed an issue with MasternodeRateCheck always returns true Jul 6, 2017
@the-schnibble the-schnibble force-pushed the check_rates_only branch 2 times, most recently from cb02642 to 27781f5 Compare July 13, 2017 14:12
@the-schnibble the-schnibble changed the title [WIP] Fixed an issue with MasternodeRateCheck always returns true [WIP] Fix MasternodeRateCheck Jul 13, 2017
@the-schnibble the-schnibble changed the title [WIP] Fix MasternodeRateCheck Fix MasternodeRateCheck Jul 13, 2017
switch(nObjectType) {
case GOVERNANCE_OBJECT_TRIGGER:
// Allow 1 trigger per mn per cycle, with a small fudge factor
pBuffer = &it->second.triggerBuffer;
buffer = it->second.triggerBuffer;
Copy link

Choose a reason for hiding this comment

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

Why this was changed? What's the point of updating local variable only?

Copy link
Author

Choose a reason for hiding this comment

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

A local variable is used here to check whether the rate limit exceeded if the object is accepted. I moved the buffer updating outside of MasternodeRateCheck to a separate method MasternodeRateUpdate.

Copy link

Choose a reason for hiding this comment

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

Ah, I see. Thanks!

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

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

utACK

@UdjinM6 UdjinM6 merged commit 4ed838c into dashpay:v0.12.2.x Aug 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants