-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Replace watchdogs with ping #1491
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
|
Thanks! However we do not merge to master. Changed base branch to v0.12.2.x for you now, pls specify it correctly next time. Needs rebase. |
UdjinM6
left a comment
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.
See inline comments
+
- You need to distinguish between different formats of
mnpinCMasternodeMan::ProcessMessageand deserialize accordingly otherwise you'll get lots of exceptions like " Exception 'CDataStream::read(): end of data: unspecified iostream_category error' caught, normally caused by a message being shorter than its stated length". - Bumping
CMasternodeMan::SERIALIZATION_VERSION_STRINGmight also be a good idea.
src/activemasternode.cpp
Outdated
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 is some mess in the message here
src/activemasternode.h
Outdated
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.
Needs empty line above public
src/instantx.h
Outdated
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 you should bump MIN_... consts, what is the rationale? (same for similar changes below)
src/masternode.h
Outdated
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.
If it's just a flag - why not bool? Also it's quite inconsistent to have variables with the same exact name but with different types (talking about this and activemasternode.* here).
src/masternode.h
Outdated
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.
Since versions are 1,2,3 etc do we really need 4 bytes here?
src/masternodeman.cpp
Outdated
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 doubt this solves anything - SetMasternodeLastPing is only used by CActiveMasternode (the local one itself) and we should take sentinelPing into account for every other masternode as well. Should fix corresponding conditions or otherwise all other masternodes are going to be in WATCHDOG_EXPIRED state.
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.
Yes, this should be called from CMasternodeMan::ProcessMessage or in some function called from there.
src/rpcgovernance.cpp
Outdated
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 doubt this belongs here, getgovernanceinfo's purpose is to print out global governance constants, not the state of the current masternode.
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.
Why not ?
"getgovernanceinfo's purpose is to print out global governance constants, not the state of the current masternode." - I don't know that it's purpose should be that narrowly construed. It contains lastsuperblock and nextsuperblock which are not global constants.
Also hassentinelping isn't really about the state of the masternode but rather is a version dependent property.
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 wasn't quite accurate about constants, let's read that as governance globals instead. In any case, I think that node specific field like that doesn't belong here. It's also excessive since you can simply get protocolversion via getinfo.
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.
Yes, really excessive, I will remove it.
|
A couple of comments:
I think it should probably be added to the output of the simple "masternode list" command, not just "masternode list full" because the later is very computationally inefficient. Since it doesn't really make sense to show the sentinel version without the protocol version, that should probably be added to "masternode list" as well. |
Every output other then "masternode list full" is for a single thing to query, so I would not change this and would keep the default output as is. If we want sentinel version to be displayed in the list it could go to "full" + a new one like "sentinel" or smht like that. |
|
Maybe we could add a command: "masternode list info" which would display all the mn information that can be queried efficiently (including sentinelVersion). |
You mean like some "static" info? The inefficiency in |
|
Another option would be to fix "masternode list full" by keeping the last paid info up to date instead of recomputing it on request. But that would be a much bigger job and definitely a separate PR. |
It's already the case for MNs. It's not the case for all other nodes because the first computation takes time and most normal nodes/qt clients will never use it. Second request should be fast even on non-MNs already. |
542d76a to
ca478c5
Compare
tgflynn
left a comment
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.
Found a couple of small issues and bigger problem with the rpc command.
src/activemasternode.cpp
Outdated
|
|
||
| bool CActiveMasternode::UpdateSentinelPing(int version) | ||
| { | ||
| if(!mnodeman.Has(vin)) { |
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 there's any real need for this block of code since you're just setting some variables. There's nothing to protect here.
src/rpcmasternode.cpp
Outdated
| ); | ||
| } | ||
|
|
||
| if(activeMasternode.nState == ACTIVE_MASTERNODE_INITIAL || |
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 see a need for this conditional, you can just call UpdateSentinelPing directly.
src/rpcmasternode.cpp
Outdated
| return false; | ||
|
|
||
|
|
||
| activeMasternode.UpdateSentinelPing(params[1].get_int()); |
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 this will work unless you add:
{ "sentinelping", 0}
to the vRPCConvertParams[] array in rpcclient.cpp.
UdjinM6
left a comment
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.
see inline comments
As a general note, it feels like this is not going to be as easy as I initially thought because these changes are not backward compatible on p2p level actually. We should probably release a mandatory pre-12.2 update for 12.1 at some point to let old nodes recognize new message format/signatures (that is probably inevitable anyway). This should make migration smoother (or otherwise network will split because old nodes will ban new ones for incorrect messages/signatures).
src/masternode.cpp
Outdated
| { | ||
| LOCK(cs); | ||
| nTimeLastWatchdogVote = GetTime(); | ||
| if(t == 0) |
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.
This can be written in one line:
nTimeLastWatchdogVote = (t == 0) ? GetTime() : t;
Also I would prefer for an argument to be named in a more descriptive manner e.g. nVoteTime or smth like that
src/activemasternode.h
Outdated
| bool SendMasternodePing(); | ||
|
|
||
| // sentinel ping data | ||
| int64_t sentinelPing; |
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.
consider using current naming convention i.e. nSmth for numbers (including Time could also be a good idea to make it a bit more descriptive)
src/masternode.h
Outdated
| int64_t sigTime; //mnb message times | ||
| std::vector<unsigned char> vchSig; | ||
| bool sentinelIsActual; // true if last sentinel ping was actual | ||
| uint16_t sentinelVersion; |
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.
use current naming convention here too
src/masternode.h
Outdated
| if(ser_action.ForRead() && (s.size() == 0)) | ||
| return; | ||
| READWRITE(sentinelIsActual); | ||
| READWRITE(sentinelVersion); |
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 should probably also include sentinelIsActual and sentinelVersion into mnp signature (see Sign/CheckSignature functions), otherwise nodes in-between will be able to change/fake it. this can be a problem because some nodes won't update wd time and will consider sentinel on original node to be non-active and this could result in network split. Note that functions I mentioned above should be able to create/check both versions of signatures depending on (original, for verification) MN protocol 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.
Ignore this for now
UdjinM6
left a comment
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 are few places where new VersionInfo should be used to preserve consistency imo. Also I'm not quite sure if it has to be defined in utils because it's used specifically for sentinel, but it's probably ok.
| return true; | ||
| } | ||
|
|
||
| bool CActiveMasternode::UpdateSentinelPing(int 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.
should probably use VersionInfo here
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've thought that VersionInfo is convertor, not storage for version information. But if you think it is better to use it to store the version itself, I change this variables type. This is also require some changes in VersionInfo class itself (i.e. default initialization, serialization, etc.), in this case it is better to move it from utils.h header, I think. May be it is better to rename this class to VersionInfoConverter, for example?
|
|
||
| // sentinel ping data | ||
| int64_t nSentinelPingTime; | ||
| uint32_t nSentinelVersion; |
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.
should probably use VersionInfo here
| std::string GetStatus() const; | ||
| std::string GetTypeString() const; | ||
|
|
||
| bool UpdateSentinelPing(int 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.
should probably use VersionInfo here
| int64_t sigTime; //mnb message times | ||
| std::vector<unsigned char> vchSig; | ||
| bool fSentinelIsCurrent; // true if last sentinel ping was actual | ||
| uint32_t nSentinelVersion; // MSB is always 0, other 3 bits corresponds to x.x.x version scheme |
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.
should probably use VersionInfo here
src/util.cpp
Outdated
| { | ||
| if(tokens[idx].length() == 0) | ||
| throw std::runtime_error("Invalid version format"); | ||
| if(!std::none_of(tokens[idx].begin(), tokens[idx].end(), |
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 like this will allow non-digit characters in the version string. Is this intentional ?
|
Looks good 👍 |
|
utACK |
|
needs rebase |
- fix the error message text in CActivbeMasternodeUpdateSentinelPing; - add empty string before public: in CActiveMasternode class declaration; - rename field sentinelPing in CMasternodePing to sentinelIsActual and change $ - decrease sentinelVersion field size to uint16_t;
- call UpdateWatchdogVoteTime in CMasternodeMan::ProcessMessage - deserialize masternodeping from the previous version archive without exception - add ability to set time in UpdateWatchdogVoteTime - set nTimeLastWatchdogVote to masternode ping sigTime if sentinel is actual - bump CMasternodeMan::SERIALIZATION_VERSION_STRING
Version format is "x.x.x"
UdjinM6
left a comment
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 👍
utACK
4af241b320 Merge bitcoin-core/secp256k1#1535: build: Replace hardcoded "auto" value with default one f473c959f0 Merge bitcoin-core/secp256k1#1543: cmake: Do not modify build types when integrating by downstream project d403eea484 Merge bitcoin-core/secp256k1#1546: cmake: Rename `SECP256K1_LATE_CFLAGS` and switch to Bitcoin Core's approach d7ae25ce6f Merge bitcoin-core/secp256k1#1550: fix: typos in secp256k1.c 0e2fadb20c fix: typos in secp256k1.c 69b2192ad4 Merge bitcoin-core/secp256k1#1545: cmake: Do not set `CTEST_TEST_TARGET_ALIAS` 5dd637f3cf Merge bitcoin-core/secp256k1#1548: README: mention ellswift module 7454a53736 README: mention ellswift module 4706be2cd0 cmake: Reimplement `SECP256K1_APPEND_CFLAGS` using Bitcoin Core approach c2764dbb99 cmake: Rename `SECP256K1_LATE_CFLAGS` to `SECP256K1_APPEND_CFLAGS` f87a3589f4 cmake: Do not set `CTEST_TEST_TARGET_ALIAS` 158f9e5eae cmake: Do not modify build types when integrating by downstream project 35c0fdc86b Merge bitcoin-core/secp256k1#1529: cmake: Fix cache issue when integrating by downstream project 4392f0f717 Merge bitcoin-core/secp256k1#1533: tests: refactor: tidy up util functions (dashpay#1491) bedffd53d8 Merge bitcoin-core/secp256k1#1488: ci: Add native macOS arm64 job 4b8d5eeacf Merge bitcoin-core/secp256k1#1532: cmake: Disable eager MSan in ctime_tests f55703ba49 autotools: Delete unneeded compiler test 396e885886 autotools: Align MSan checking code with CMake's implementation abde59f52d cmake: Report more compiler details in summary 7abf979a43 cmake: Disable `ctime_tests` if build with `-fsanitize=memory` 4d9645bee0 cmake: Remove "AUTO" value of `SECP256K1_ECMULT_GEN_KB` option a06805ee74 cmake: Remove "AUTO" value of `SECP256K1_ECMULT_WINDOW_SIZE` option 1791f6fce4 Merge bitcoin-core/secp256k1#1517: autotools: Disable eager MSan in ctime_tests 26b94ee92a autotools: Remove "auto" value of `--with-ecmult-gen-kb` option 122dbaeb37 autotools: Remove "auto" value of `--with-ecmult-window` option e73f6f8fd9 tests: refactor: drop `secp256k1_` prefix from testrand.h functions 0ee7453a99 tests: refactor: add `testutil_` prefix to testutil.h functions 0c6bc76dcd tests: refactor: move `random_` helpers from tests.c to testutil.h 0fef8479be tests: refactor: rename `random_field_element_magnitude` -> `random_fe_magnitude` 59db007f0f tests: refactor: rename `random_group_element_...` -> `random_ge_...` ebfb82ee2f ci: Add job with -fsanitize-memory-param-retval e1bef0961c configure: Move "experimental" warning to bottom 55e5d975db autotools: Disable eager MSan in ctime_tests ec4c002faa cmake: Simplify `PROJECT_IS_TOP_LEVEL` emulation cae9a7ad14 cmake: Do not set emulated PROJECT_IS_TOP_LEVEL as cache variable 218f0cc93b ci: Add native macOS arm64 job git-subtree-dir: src/secp256k1 git-subtree-split: 4af241b32099067464e015fa66daac5096206dea
Rationale: Watchdogs have proved quite problematic. We should be able to replace them by integrating sentinel information into Masternode ping objects. Need new rpc call for sentinel to update its timestamp and version then add these to masternode ping's.
This requires changes to both dashcore and sentinel (sentinel project has PR#17 with the same name). The changes are made in a backward compatible way so that dashcore and sentinel do not necessarily have to be upgraded at the same time.
Changes for dashcore:
add rpc call allowing sentinel to ping node and set sentinel version (sentinelping);
add field to governanceinfo indicating whether sentinel ping is enabled or not;
add sentinel ping flag field to CMasternodePing, this flag is set to 1 when last sentinel ping was less then MASTERNODE_WATCHDOG_MAX_SECONDS, and is set to 0 in other case;
add sentinel version field to CMasternodePing;
set CMasternode::nTimeLastWatchdogVote to current time during sentinel ping;
bump protocol version;