-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Warn validators about stake deactivation #5955
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.
Should i match vote_state.node_pubkey and validator public key here ?
Yep, that looks right to me!
@mvines could you leave a feedback, please? |
@mvines I added a counter and put logic inside set_handler. Does it look good? |
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.
Looking great so far, I have some comments but 📈
Can you remove the changes to programs/bpf/Cargo.lock
in this PR too please, they don't seem related
core/src/validator.rs
Outdated
.map(|accounts| { | ||
accounts | ||
.iter() | ||
.filter_map(|(pubkey, (stake, account))| { |
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.
nit: I think we can make this block smaller, like this:
.filter_map(|(pubkey, (stake, account))| {
if let Ok(vote_state) = VoteState::deserialize(&account.data) && vote_state.node_pubkey == validator_pubkey {
return Some((*pubkey, *stake));
}
None
})
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.
Does this approach not work 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.
What do you mean 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'm just suggesting the filter_map()
implementation be restructured to avoid the double else { None }
at the end, with the sample code I wrote
core/src/validator.rs
Outdated
.collect() | ||
}) | ||
.unwrap(); | ||
if current_stakes.len() > 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.
Hmm, I think we could just move the warn!()
into the .filter_map()
and then remove this entire block.
Codecov Report
@@ Coverage Diff @@
## master #5955 +/- ##
========================================
- Coverage 79.2% 74.3% -4.9%
========================================
Files 219 238 +19
Lines 41905 42312 +407
========================================
- Hits 33200 31464 -1736
- Misses 8705 10848 +2143 |
@mvines ready for review |
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 had a couple more comments, this is progressing nicely though!
@mvines, thanks for your guidance |
I just copied programs/bpf/Cargo.lock from solana master branch. I hope it works. |
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.
Also remove the changes to programs/bpf/Cargo.lock
please.
core/src/validator.rs
Outdated
.map(|accounts| { | ||
accounts | ||
.iter() | ||
.filter_map(|(pubkey, (stake, account))| { |
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.
Does this approach not work well?
core/src/validator.rs
Outdated
@@ -168,7 +173,36 @@ impl Validator { | |||
config.storage_slots_per_turn, | |||
bank.slots_per_segment(), | |||
); | |||
|
|||
let bf = bank_forks.clone(); |
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.
Can you wrap this entire new block in:
if config. enable_ctrl_c_handler {
..
}
since we only want to execute it when the handler is enabled.
Once that's done within the new if
block we can do this, which will avoid the need to use a short less readable bf
variable name :
- let bf = bank_forks.clone();
+ let bank_forks = bank_forks.clone();
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
validator/src/main.rs
Outdated
|
||
validator_config.rpc_config.drone_addr = matches.value_of("rpc_drone_addr").map(|address| { | ||
solana_netutil::parse_host_port(address).expect("failed to parse drone address") | ||
|
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.
can you please avoid making this change
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 you take a look at line 442, I added this line "solana_netutil::parse_host_port(address).expect("failed to parse drone address")"
Please feel free to promote this PR from "Draft" to a normal PR. I think this is almost ready to land! |
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.
Also remove the changes to
programs/bpf/Cargo.lock
please.
I have reviewed programs/bpf/Cargo.lock.
There is only one line added to programs/bpf/Cargo.lock to enable CTRL+C catch functionality.
"ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)"
core/src/validator.rs
Outdated
warn!("Validator exits.."); | ||
// run vvalidator exit | ||
} | ||
*counter_ref += 1; | ||
*c += 1; |
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.
it should work , there is test here. don't u think we have to test set_handler()?
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.
Sorry I'm not quite sure what you mean 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 think this comment has been made last week. It is no longer relevant
Ah, got it. Yep that's fine thanks :) |
I ran cargo test in solana/core and got a following error |
@mvines, you wrote :
What do you mean by that? |
core/Cargo.toml
Outdated
@@ -76,7 +76,8 @@ tokio-codec = "0.1" | |||
tokio-fs = "0.1" | |||
tokio-io = "0.1" | |||
untrusted = "0.7.0" | |||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.20.0" } | |||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.19.0-pre0" } |
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.
oops, this change shouldn't have snuck in
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 change is still unneeded, version should remain at 0.20.0 please
core/src/validator.rs
Outdated
.map(|accounts| { | ||
accounts | ||
.iter() | ||
.filter_map(|(pubkey, (stake, account))| { |
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'm just suggesting the filter_map()
implementation be restructured to avoid the double else { None }
at the end, with the sample code I wrote
core/src/validator.rs
Outdated
let bank_forks = bank_forks.clone(); | ||
let counter = Arc::new(AtomicUsize::new(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.
These two lines can move after if config. enable_ctrl_c_handler {
to keep their scope as limited as possible
@@ -1,3 +1,3 @@ | |||
fn main() { | |||
solana_validator::main() | |||
} |
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 where did the change to validator/src/ go that sets enable_ctrl_c_handler = true
i hope no more errors left. @mvines, could you review it, please? |
Looks super close, thanks for your patience. I see two issues:
|
@mvines, I applied changes to validator/src/lib.rs and ran cargo fmt. |
validator/src/lib.rs
Outdated
.send() | ||
.and_then(|response| response.error_for_status()) | ||
.map_err(|err| format!("Unable to get: {:?}", err))?; | ||
let client = ureq::agent(); |
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.
It looks like you're working off an older version of the code instead of the HEAD of the master branch. We switched from ureq to reqwest maybe a week ago now, so all these changes shouldn't be present.
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.
it seems i just have to copy validator/src/lib.rs of master branch to my branch right?
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'd get the latest lib.rs from the master branch, then only add in your change (which if I recall is just a single line)
core/src/validator.rs
Outdated
std::process::exit(1); | ||
} | ||
let bank = bank_forks.read().unwrap().working_bank(); | ||
let _: Vec<_> = bank |
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 point was that if the node currently has no stake it's ok to exit on the first ^C though. I don't see that code anymore here. It looks like we now collect all the stake but never check it for 0, and always exit on the second ^C
@mvines, i have updated lib.rs ( copied lib.rs from master branch and added one new line) and added few lines that a validator exits on first ^C if he has no stake. Please let me know what I have to do to proceed further. |
core/Cargo.toml
Outdated
@@ -76,7 +76,8 @@ tokio-codec = "0.1" | |||
tokio-fs = "0.1" | |||
tokio-io = "0.1" | |||
untrusted = "0.7.0" | |||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.20.0" } | |||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.19.0-pre0" } |
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 change is still unneeded, version should remain at 0.20.0 please
core/src/validator.rs
Outdated
warn!("Validator with no stake exiting on first ^C"); | ||
if *pubkey == keypair.pubkey() && *stake > 0 { | ||
if let Ok(vote_state) = VoteState::deserialize(&account.data) { | ||
warn!("Validator with stake is exiting on first ^C"); | ||
std::process::exit(1); |
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.
@mvines , do u think i should return Some(*pubkey, *stake) somewhere 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'd just return Some(*stake)
here. Then turn epoch_vote_accounts(..).map(|accounts| ...)
into epoch_vote_accounts(..).filter_map(|accounts| ...)
. This way once we arrive at line 206 we have either
- value
None
if the node is not stake, in which can we canstd::process::exit(1)
Some(stake)
representing the current stake of the node, in which can we canwarn!
the user
in /core ran cargo test , it raised the following error |
Hey looks like there's some compile errors with the latest commits |
core/src/validator.rs
Outdated
.filter_map(|account| match account { | ||
pubkey, (stake, accoount) => { | ||
.filter_map(|account| match (account) { | ||
Some(pubkey, (stake, account)) => { |
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.
@mvines, I guess filter_map unwraps an option automatically, so it is not necessarily to add Some here right?
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.
Sorry for the review delay here @cyberbono3! I just realized that we can use .find() instead of .filter_map()
. This way let stakes: Vec<Option<u64>> ...
turns into just let stake: Option<u64> ...
, we can remove the for stake in stakes.iter()
loop entirely and just match stake { ... }
directly.
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.
@mvines thanks for your feedback. I used find instead of filter_map and then matched stake directly. I tried to run cargo test from solana/core to make sure my code has no compile errors, got this error. It seems, that we use outdated librocksdb-sys v5.18.3, the current version is librocksdb-sys = "6.1.3"
@mvines, trying to complete this PR i was running cargo test in core/ to find out if my code is correct. I encountered multiple compile errors . i have tried to fix them by updeting the version of some libraries in Cargo.toml. After I fixed these compile errors, other errors have been popped up (e.g. updated library has no such method etc). i would appreciate your guidance to resolve this issue. |
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, getting there.
I also see CI is complaining about cargo fmt
issues, a quick run of cargo fmt
should fix those up though!
core/src/validator.rs
Outdated
.filter_map(|account| match account { | ||
pubkey, (stake, accoount) => { | ||
.filter_map(|account| match (account) { | ||
Some(pubkey, (stake, account)) => { |
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.
Sorry for the review delay here @cyberbono3! I just realized that we can use .find() instead of .filter_map()
. This way let stakes: Vec<Option<u64>> ...
turns into just let stake: Option<u64> ...
, we can remove the for stake in stakes.iter()
loop entirely and just match stake { ... }
directly.
@@ -457,8 +457,9 @@ pub fn main() { | |||
|
|||
validator_config.voting_disabled = matches.is_present("no_voting"); | |||
|
|||
validator_config.rpc_config.enable_validator_exit = matches.is_present("enable_rpc_exit"); | |||
|
|||
validator_config.rpc_config.enable_fullnode_exit = matches.is_present("enable_rpc_exit"); |
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 line looks like a minor rebase error, it shouldn't be modified.
@@ -457,7 +457,7 @@ pub fn main() { | |||
|
|||
validator_config.voting_disabled = matches.is_present("no_voting"); | |||
|
|||
validator_config.rpc_config.enable_fullnode_exit = matches.is_present("enable_rpc_exit"); | |||
validator_config.rpc_config.enable_validator_exit = matches.is_present("enable_rpc_exit"); |
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 rebase error here
core/src/validator.rs
Outdated
account.iter().find(|(pubkey, (stake, account))| { | ||
*pubkey == &keypair.pubkey() | ||
&& *stake > 0 | ||
&& Ok(vote_state) == VoteState::deserialize(&account.data) |
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.
@mvines I got this error here Ok(vote_state) == VoteState::deserialize(&account.data) ) | ^^^^^^^^^^ not found in this scope
How can I fix it?
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.
You'll need to bring it into scope with use solana_vote_api::vote_state::VoteState;
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 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.
Is it maybe the vote_state
variable that's underlined in the error message?
I think this line can be instead:
&& VoteState::deserialize(&account.data).is_ok()
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.
@CriesofCarrots thank you
It would be good to squash the 27 commits here into 1 single commit eventually |
@mvines i have squashed multiple commits in one |
Hey looks like the rebase isn't quite right. Look at the diff in the PR, there's a ton of changes that essentially roll back numerous recent commits. I can't really review this unfortunately. Please ping me here once you get the rebase right. Thanks! |
Obsoleted by #6874 |
|Fixes] #5773
Summary of Changes
Questions:
I need some guidance to proceed further.