-
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
Add the ability to mark amendments as obsolete #4291
Conversation
Seems reasonable. You might also consider placing any UNL validator found voting for an obsoleted amendment on the nUNL for each flag ledger that voting occurs. However if you do this then the code change needs to come with an amendment for the nUNL behaviour change. |
This would leak even more info about your UNL though? I'm not sure if "dead" amendments should be carried in code as "Obsolete" forever, on the other hand it only adds a few lines compared to the alternative of just deleting the obsolete amendments completely and seems relatively safe compared to the current situation. |
Can you describe more? Do you mean: If a validator removes a node from its UNL (places it on nUNL) and publishes its ValidatorList, then external world can take a diff between the versions of ValidatorList and discern the one validator on it past UNL? |
Any validator that gets put by your validator on a nUNL proposal is currently trusted by your validator. If I can get on a nUNL proposal just by proposing an obsolete amendment, it is a good way to make all other validators that have me on their UNL leak that information. Validations are not logged or stored and proposals are even more ephemeral, so this would be largely unnoticed or look like an accidental misconfiguration. |
I don't know why you think the UNL of validators should be a secret to begin with? I would actually rather they publish / volunteer that information. Whether or not I want to trust your validator strongly depends on who else your validator listens to. |
Because this is one of the main design goals of the algorithm for example to be able to add validators to your UNL that might be viewed controversially in your jurisdiction. A good UNL would for example have lots of validators on there that are very unlikely to collude, but by that very nature it means that there will be some raised eyebrows if you start adding Iranian, Chinese and Russian validators in addition to the current recommended, western centric one. There is also no way built in to verify or attest that a certain host is on my UNL, so even if someone volunteers that data, it can be trivially faked or false. This is not the right place to explain this though - I'm just pointing out that UNLs are supposed to be private (and if you want to volunteer some info about yours, that's your personal choice) and publishing a nUNL proposal is already leaking information. Adding more ways to add up on there just makes the situation worse. |
Given that validations are relayed and can be/are generated pseudonymously, and the keys can be changed on an existing validator and it appears as a new validator, I think this is putting a hat on a hat. If you want the location of your validator to be secret then it already is: simply don't tell anyone where it runs. Network safety requires very high (I would strongly argue 100%) UNL overlap. Hypothetical privacy concerns that are already dealt with by pseudonymity should not trump real practical fork safety. |
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 is a clever extension of the existing code. I like it for the most part. There is one part of the testing implementation that I think is dangerous, and that needs to be replaced. But, on the whole, nicely done.
Oh, and I looked at the code coverage of the new/revised code. That looks good too. Good tests. Thanks!
src/test/app/AmendmentTable_test.cpp
Outdated
// Even though this is written as a template, and could potentially be a | ||
// global helper, it's only intended to be used for | ||
// std::vector<AmendmentTable::FeatureInfo> in this class. | ||
template <class T> | ||
std::vector<T> | ||
operator+(std::vector<T> left, std::vector<T> right) | ||
{ | ||
left.reserve(left.size() + right.size()); | ||
for (auto& item : right) | ||
{ | ||
left.emplace_back(std::move(item)); | ||
} | ||
return left; | ||
} |
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'll be honest. I don't like this template one bit. Yes, it's clever. But it adds capabilities to a std::vector
that, according to the standard, a vector
should not have.
And, despite the comment, it it currently important that the definition be a template. This file uses the template both for a std::vector<std::string>
and a std::vector<AmendmentTable::FeatureInfo>
. Please remove this template. The two places that it is used are more safely handled by using typical (more verbose) 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.
Fixed / rewritten.
While amendment governance is the main topic, I'd like to share a new idea, an additional vote '
If an operator votes Before the addition of This new vote addition would benefit the network and VL publishers as we're able to identify which validator hasn't participated in amendment governance and in what sequence of amendments. Rather than relying on a Is this necessary?And if you're wondering if all of this is necessary as validators are actively participating in amendment governance (as of the NFT amendment, only 2 hasn't voted We should not wait until things go south again (validators turn passive). Let's take a recent event as an example: #4282 Current suggested approachDiscussed this matter with the others and it seems like including this as a new field on validation messages would be a do-able approach. Validation messages are discarded after consensus has been reached, ledger size will not increase. |
Two counter-points:
|
Thanks! Could you submit a review approval?
This is an interesting idea, but it's beyond the intended scope of this PR. |
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.
👍 The most recent changes look good. Thanks.
Just to be clear, if an "Obsolete" amendment were to (somehow) become confirmed by consensus, the server still has the code to process transactions according to that amendment so it would not be amendment blocked, and it would continue to function the same as if it had been voting "no" on the amendment normally? I am not sure this is an improvement over the old way of simply removing obsolete amendments from the code. Suppose an amendment has some very bad code associated with it (like, it causes corrupted ledgers or crashes) and becomes enabled. Is it better to jump off the cliff with the rest of consensus, or is it better to say, "Hey, the situation is not OK, I'm stopping here"? Personally I'd rather legitimate servers become amendment blocked and maybe even stop the whole network rather than enable a known-broken amendment. That's the "correctness over forward progress" principle, right? I guess the pragmatic counter-argument is that some bugs aren't so bad that they're worth stopping the whole network even if some undesirable stuff happens? I'd also like to preserve a path to actually, fully removing the obsolete code from the server, given enough time. I suppose it would make sense to extend XLS-11. One approach would be to give obsolete amendments the same longevity as the legacy code for enabled amendments, and retire the code two years after it's marked as obsolete. Or, it could be less, because the legacy code for obsolete amendments isn't needed for interpreting historical data (on Mainnet at least). |
Yes, that is correct.
Have we every actually removed an obsolete amendment? I know we have one ( Fortunately, the "very bad code" scenario hasn't happened, AFAIK, and I don't think this change really attempts to solve that problem. If that were to come up, we'd probably have to deal with it differently. I think the existing governance model can avoid this problem pretty well, too.
The |
e1e7791
to
0b71963
Compare
0b71963
to
b2cb0c0
Compare
* upstream/develop: `XRPFees`: Fee setting and handling improvements (XRPLF#4247)
* upstream/develop: Revise CONTRIBUTING (XRPLF#4382)
* upstream/develop: Update dependency: grpc (XRPLF#4407) Introduce min/max observers for Number Optimize uint128_t division by 10 within Number.cpp Replace Number division algorithm Include rounding mode in XRPAmount to STAmount conversion. Remove undefined behavior * Taking the negative of a signed negative is UB, but taking the negative of an unsigned is not. Silence warnings Introduce rounding modes for Number: Use Number for IOUAmount and STAmount arithmetic Add tests Add implicit conversion from STAmount to Number Add clip Add conversions between Number, XRPAmount and int64_t AMM Add Number class and associated algorithms
* upstream/develop: Update documented pathfinding configuration defaults: (XRPLF#4409)
@RichardAH feel free to review this, at your convenience. |
* upstream/develop: Rename to fixNonFungibleTokensV1_2 and some cosmetic changes (XRPLF#4419) Only account specified as destination can settle through brokerage: (XRPLF#4399) Prevent brokered sale of NFToken to owner: (XRPLF#4403) Fix 3 issues around NFToken offer acceptance (XRPLF#4380) Allow NFT to be burned when number of offers is greater than 500 (XRPLF#4346) Add fixUnburnableNFToken feature (XRPLF#4391) Change default vote on fixUniversalNumber from yes to no (XRPLF#4414)
* upstream/develop: Resolve a couple of Github Action CI annoyances: (XRPLF#4413)
* upstream/develop: README: Add a few source code starting points (XRPLF#4421)
* upstream/develop: Fix Conan version constraint in workflows (XRPLF#4430) Refactor getTrustedForLedger() (XRPLF#4424) README: Update "Build from source" section (XRPLF#4426)
* upstream/develop: Undo API changes introduced in XRPFees: (XRPLF#4429) Remove recipe for RocksDB and add recipe for Snappy (XRPLF#4431)
* upstream/develop: Set version to 1.10.0-rc4 Rename 'NFT' to 'NFToken' in DisallowIncoming flags (XRPLF#4442) Update Docker.md (XRPLF#4432) Update package building scripts and images to use Conan (XRPLF#4435) Disable duplicate detector: (XRPLF#4438)
* upstream/develop: Set version to 1.10.0
* upstream/develop: docs: security bug bounty acknowledgements (XRPLF#4460)
* upstream/develop: Rectify the import paths of boost/iterator: (XRPLF#4293) Allow port numbers be be specified with a colon: (XRPLF#4328) Use <=> operator for base_uint, Issue, and Book: (XRPLF#4411) Reporting Mode: Do not attempt to acquire missing data from peer network (XRPLF#4458)
|
||
return left; | ||
} | ||
|
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.
Nicely done!
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!
* upstream/develop: refactor: optimize NodeStore object conversion: (4353) fix(ValidatorSite): handle rare null pointer dereference in timeout: (4420) fix(gateway_balances): handle overflow exception: (4355) Set version to 1.10.1-b1
* upstream/develop: docs: update protocol README (4457) `fixNFTokenRemint`: prevent NFT re-mint: (4406) fix: support RPC markers for any ledger object: (4361)
High Level Overview of Change
regardless of operator configuration.
vote.
Context of Change
This comment: #4282 (comment) pointed out an ongoing issue - there are amendments that simply shouldn't be voted on because they're broken, there's no actual code implementing them, or other reasons. Unfortunately, they need to remain supported on the main net servers on the off chance that they do get enabled. Remember: If they get enabled, any versions that don't support them will be amendment blocked.
Up to now, the communication to let operators know not to vote for these amendments has been done via back channels, blog posts, etc. Why not use code to both communicate and enforce this message?
A determined operator is still not absolutely prevent from voting against an amendment. They are free to change the source and compile locally, and still stick to the rules of the protocol.
Type of Change
Before / After
Before: there are two options for an amendment's
DefaultVote
behaviour: yes and no.After: there are three options for an amendments
VoteBehavior
: DefaultYes, DefaultNo, and Obsolete.To go along with this, for the
feature
admin API, there's a new possible value for thevetoed
field. For obsolete amendments, thevetoed
field has the value"Obsolete"
.Test Plan
There are currently four amendments marked
Obsolete
that haven't passed yet:CryptoConditionsSuite
NonFungibleTokensV1
fixNFTokenDirV1
fixNFTokenNegOffer
Test cases:
Future Tasks
Amendment governance is an ongoing discussion. I am not going to rehash all the details here.