-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Support UNLs with future effective dates: (UNL v2) #3619
Conversation
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.
Partial review, some quick comments. Will follow-up.
src/ripple/app/misc/NetworkOPs.cpp
Outdated
NetworkOPsImp::setExpiredValidatorList() | ||
{ | ||
expiredValidatorList_ = true; | ||
setMode(OperatingMode::TRACKING); |
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 TRACKING
is the right mode here. If we're tracking
we think we agree with the network but if we have no validator list, then we can't possibly be convinced of that fact.
I think CONNECTED
is probably better.
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, that makes sense. I was paralleling amendment blocked, but this is a good place for a difference.
void | ||
hash_append(Hasher& h, std::map<std::size_t, ValidatorBlobInfo> const& blobs) | ||
{ | ||
for (auto const& [_, item] : blobs) |
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.
Maybe use std::ignore
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.
std::ignore
doesn't work with structured bindings. (I'd love if we got a standard "ignore" variable like _
in other languages).
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.
Oh right, it's only for std::tie
🤦♂️
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.
Yeah, I definitely wish there was a more elegant way to do this...
src/ripple/app/main/Application.cpp
Outdated
@@ -2143,6 +2143,12 @@ ApplicationImp::serverOkay(std::string& reason) | |||
return false; | |||
} | |||
|
|||
if (getOPs().isExpiredValidatorList()) |
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.
Gramatically, isValidatorListExpired
is better. But before you change anything, either name raises questions: if I have multiple lists, one of which is expired will this trigger? The name of the function suggests no. The reason
we set suggests yes.
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.
Hm.
hasExpiredValidatorList
isAnyValidatorListExpired
needUpdatedUNL
isConsensusBlocked
Any preferences or suggestions?
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.
Until we decide on a better name, I'm going to use isUNLBlocked
.
#include <ripple/protocol/PublicKey.h> | ||
#include <boost/iterator/counting_iterator.hpp> | ||
#include <boost/range/adaptors.hpp> | ||
#include <mutex> | ||
#include <numeric> | ||
#include <shared_mutex> | ||
|
||
namespace protocol { | ||
// predeclaration | ||
class TMValidatorList; |
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.
My spidey sense is tingling...
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 only did this so I could reference these classes in some function declarations below without needing to #include
the entire protocol/messages.h
. If there's a better way, I'm all ears.
src/ripple/app/misc/ValidatorList.h
Outdated
std::size_t sequence; | ||
TimeKeeper::time_point expiration; | ||
TimeKeeper::time_point effective; |
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.
effective
is not very helpful. I think we should rename to something like:
TimeKeeper::time_point validFrom;
TimeKeeper::time_point validUntil;
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.
validFrom
and validUntil
are used internally for the logic within rippled
(in the C++ code). Validator list creators/maintainers use effective
and expiration
.
Rebased on to 1.7.0-b3 |
The node crashes for me when I provide validators under the |
f167315
to
058981c
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.
👍 pending resolutions of a couple of things below and @seelabs's comments.
src/ripple/app/misc/ValidatorList.h
Outdated
static constexpr std::uint32_t supportedListVersions[]{1, 2}; | ||
// In the initial release, to prevent potential abuse and attacks, any VL | ||
// collection with more than 5 entries will be considered malformed. | ||
static constexpr std::size_t MAX_SUPPORTED_BLOBS = 5; |
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 know that we need to support that many lists at once, to be honest. I think 2 would be fine, but it's at your discretion.
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 figure 2 is probably going to be what we're most likely to see, but I wanted to leave a little wiggle room in case someone comes up with some interesting use cases we haven't considered.
src/ripple/app/misc/NetworkOPs.cpp
Outdated
@@ -1561,6 +1579,13 @@ NetworkOPsImp::setAmendmentBlocked() | |||
setMode(OperatingMode::TRACKING); |
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.
While we're here, this should probably change too: TRACKING
means "convinced we agree with the network" per the documentation. If we are amendment blocked we might transiently agree with the network, but the fact that we are actually UNABLE to process transactions the network is able to generate suggests that this should be CONNECTED
instead.
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.
Good point. Done.
src/ripple/app/misc/NetworkOPs.cpp
Outdated
if ((om > OperatingMode::TRACKING) && amendmentBlocked_) | ||
if ((om > OperatingMode::CONNECTED) && isUNLBlocked()) | ||
om = OperatingMode::CONNECTED; | ||
else if ((om > OperatingMode::TRACKING) && isAmendmentBlocked()) | ||
om = OperatingMode::TRACKING; |
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.
Same here... CONNECTED
seems more appropriate.
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
* Discovered some bugs and inconsistencies doing multi-node testing.
* Fixes broken Release build unit tests
* Put and keep node in CONNECTED state instead of TRACKING if a VL expires. * Rename effective and expiration to validFrom and validTo respectively. * Renamed the "ExpiredValidatorList" set of functions to "UNLBlocked", though the name may change again later.
* Remove unnecessary `local` variable processing a local validator list. * Simplify VL protocol message size checking. * Simplify and consolidate VL version number handling. * Log requests for invalid VL version number.
* Fix a couple of asserts.
* Rename `isFunctionallyBlocked` to `isBlocked` * Moved a bunch of functions out of their class definition for readability * Removed some unhelpful comments * Added some helpful comments * Changed the unique_lock in ValidatorList to a lock_guard since it's never unlocked * Cleaned up some naming and formatting * Split `buildFileData` into two overloads for readability
I forgot to mention this yesterday, but that last push included both rebasing onto 1.7.0-b8 and the latest round of feedback from @seelabs. |
* Amendment blocked servers will never get past the "connected" state. * This necessitated reordering a few checks to return the appropriate error codes.
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.
Thanks for resolving those comments. LGTM 👍
* We could have gotten the VL from another source, so a peer sending it to us might have a lower "known sequence" value, or none (0).
Merged on Jan 8, 2021 via 4b9d3ca |
While effective date is documented there is no notes on XRPL.org that you need to specify version as 2. |
Strictly speaking, I think a version 1 blob with an effective date would work fine. It would not be best practice because the current VL blob wouldn't be included with it. |
High Level Overview of Change
pre-publish the next UNL while the current one is still valid.
compatible.
being amendment blocked, except reversible.
Context of Change
Internal Spec
Type of Change
Test Plan
Set up an internal site similar to https://vl.ripple.com. Publish a version 2 UNL file on that site, as described in the spec. (Replace
blob
andsignature
with ablobs_v2
array containing one or more blob/signature pairs.) Include one or more VLs in the array containing future effective dates (using Ripple-epoch time value). Verify that nodes switch to the new VL at the appropriate time.Future Tasks
Some relatively minor deviations and additions were made from the spec in the development process. I'll update the spec ASAP.
This change is