-
Notifications
You must be signed in to change notification settings - Fork 961
added check for fee recipient per validator and added unit tests #8454
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
base: unstable
Are you sure you want to change the base?
Changes from 3 commits
4c0dbc5
a5443ad
5fe8cb8
98af956
08d48f5
dd7515f
295fda0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -12,7 +12,7 @@ use std::collections::HashSet; | |||||
| use std::fs::{self, File, create_dir_all}; | ||||||
| use std::io; | ||||||
| use std::path::{Path, PathBuf}; | ||||||
| use tracing::error; | ||||||
| use tracing::{error, info}; | ||||||
| use types::{Address, graffiti::GraffitiString}; | ||||||
| use validator_dir::VOTING_KEYSTORE_FILE; | ||||||
| use zeroize::Zeroizing; | ||||||
|
|
@@ -212,6 +212,16 @@ impl ValidatorDefinition { | |||||
| }, | ||||||
| }) | ||||||
| } | ||||||
|
|
||||||
| pub fn check_fee_recipient(&self, global_fee_recipient: Option<Address>) -> Option<&PublicKey> { | ||||||
| // Skip disabled validators. Also skip if validator has its own fee set, or the global flag is set | ||||||
| if !self.enabled || self.suggested_fee_recipient.is_some() || global_fee_recipient.is_some() | ||||||
| { | ||||||
| return None; | ||||||
| } | ||||||
|
|
||||||
| Some(&self.voting_public_key) | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// A list of `ValidatorDefinition` that serves as a serde-able configuration file which defines a | ||||||
|
|
@@ -410,6 +420,52 @@ impl ValidatorDefinitions { | |||||
| .iter() | ||||||
| .filter_map(|def| def.signing_definition.voting_keystore_password_path()) | ||||||
| } | ||||||
|
|
||||||
| /// Called after loading to run safety checks on all validators | ||||||
| pub fn check_all_fee_recipients( | ||||||
| &self, | ||||||
| global_fee_recipient: Option<Address>, | ||||||
| ) -> Result<(), String> { | ||||||
| let missing: Vec<&PublicKey> = self | ||||||
| .0 | ||||||
| .iter() | ||||||
| .filter_map(|def| def.check_fee_recipient(global_fee_recipient)) | ||||||
| .collect(); | ||||||
|
|
||||||
| if !missing.is_empty() { | ||||||
| let pubkeys = missing | ||||||
| .iter() | ||||||
| .map(|pk| pk.to_string()) | ||||||
| .collect::<Vec<_>>() | ||||||
| .join(", "); | ||||||
|
|
||||||
| return Err(format!( | ||||||
| "The following validators are missing a `suggested_fee_recipient`: {}. \ | ||||||
| Fix this by adding a `suggested_fee_recipient` in your \ | ||||||
| `validator_definitions.yml` or by supplying a fallback fee \ | ||||||
| recipient via the `--suggested-fee-recipient` flag.", | ||||||
| pubkeys | ||||||
| )); | ||||||
| } | ||||||
|
|
||||||
| // Friendly reminder for users using the fallback flag | ||||||
| if global_fee_recipient.is_some() { | ||||||
| let count = self | ||||||
| .0 | ||||||
| .iter() | ||||||
| .filter(|d| d.enabled && d.suggested_fee_recipient.is_none()) | ||||||
| .count(); | ||||||
| if count > 0 { | ||||||
| info!( | ||||||
| "The fallback --suggested-fee-recipient is being used for {} validator(s). \ | ||||||
| Consider setting the fee recipient for each validator individually via `validator_definitions.yml`.", | ||||||
|
||||||
| Consider setting the fee recipient for each validator individually via `validator_definitions.yml`.", | |
| You may alternatively set the fee recipient for each validator individually via `validator_definitions.yml`.", |
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.
For this, I previously used a warn, and @eserilev suggested I change it to an info log. I don't mind changing it to a debug or something.
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.
Let's wait to hear from Eitan and see what he says.
I think even removing this log looks good to me (or move to debug), because the suggested_fee_recipient is something sensitive to users and having a new INFO log there could be a surprise and users may start to questions or panic if they should define in the yml file
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 debug or removing the log seems fine to me.
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.
Noted
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.
chong-he marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
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.
For succinctness, we can combine this with the test fee_recipient_check_fails_when_missing() to avoid repeatedly defining the same fields. We can revise the test name a bit, then add the checks in the same tests
Edit: I believe we can even go "all out" for succinctness, to define a general ValidatorDefinitions, then for each test, update the necessary fields for each test purpose, and add an assert right below, i.e., instead of having multiple tests, we can have just 1 or 2 test functions, move the test name (and revise a bit) and put it as a comment right above and before the assert. This will be cleaner as well
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 spotting this. I feel those two tests should be combined. 🤝
About having just 1 or 2 test functions, I actually tried compressing the tests into 3 functions, and while it makes things more compact, the functions appeared not so comprehensible due to how long they became. So I think I prefer to separate test concerns as much as possible.
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.
Let's combine those 2 tests at least
To me, having a longer function is ok as long as the tests are clearly defined / commented above it. It is nicer to have fewer lines that can cover the tests (e.g., avoid defining the fields repeatedly) looks cleaner.
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.
For succinctness, we can combine this with the test
fee_recipient_check_fails_when_missing()to avoid repeatedly defining the same fields. We can revise the test name a bit, then add the checks in the same tests
Yes. The two tests you highlighted have been combined in the update I pushed yesterday. 🫡
Uh oh!
There was an error while loading. Please reload this page.