Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Warn validators about stake deactivation #5955

Closed
wants to merge 1 commit into from
Closed

Warn validators about stake deactivation #5955

wants to merge 1 commit into from

Conversation

cyberbono3
Copy link

|Fixes] #5773

Summary of Changes

  1. validators_current_stakes
  2. ctrlc::set_handler

Questions:

  1. Should i match vote_state.node_pubkey and validator public key here ?
  2. if we vote_state.node_pubkey == validator.publickey so i can warn this validator in ctrlc::set_handler right?

I need some guidance to proceed further.

@sakridge sakridge changed the title Warn validators aboiut stake deactivation Warn validators about stake deactivation Sep 18, 2019
Copy link
Contributor

@mvines mvines left a 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!

core/src/validator.rs Outdated Show resolved Hide resolved
@cyberbono3
Copy link
Author

@mvines could you leave a feedback, please?

core/src/validator.rs Outdated Show resolved Hide resolved
core/src/validator.rs Outdated Show resolved Hide resolved
@cyberbono3
Copy link
Author

@mvines I added a counter and put logic inside set_handler. Does it look good?

Copy link
Contributor

@mvines mvines left a 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 Show resolved Hide resolved
core/src/validator.rs Outdated Show resolved Hide resolved
.map(|accounts| {
accounts
.iter()
.filter_map(|(pubkey, (stake, account))| {
Copy link
Contributor

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
                        })

Copy link
Contributor

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?

Copy link
Author

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?

Copy link
Contributor

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

.collect()
})
.unwrap();
if current_stakes.len() > 0 {
Copy link
Contributor

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.

core/src/validator.rs Outdated Show resolved Hide resolved
core/src/validator.rs Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Sep 24, 2019

Codecov Report

Merging #5955 into master will decrease coverage by 4.8%.
The diff coverage is n/a.

@@           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

@cyberbono3
Copy link
Author

@mvines ready for review

Copy link
Contributor

@mvines mvines left a 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!

validator/src/main.rs Outdated Show resolved Hide resolved
core/src/validator.rs Outdated Show resolved Hide resolved
core/src/validator.rs Outdated Show resolved Hide resolved
@cyberbono3
Copy link
Author

@mvines, thanks for your guidance

@cyberbono3
Copy link
Author

I just copied programs/bpf/Cargo.lock from solana master branch. I hope it works.

Copy link
Contributor

@mvines mvines left a 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.

.map(|accounts| {
accounts
.iter()
.filter_map(|(pubkey, (stake, account))| {
Copy link
Contributor

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?

@@ -168,7 +173,36 @@ impl Validator {
config.storage_slots_per_turn,
bank.slots_per_segment(),
);

let bf = bank_forks.clone();
Copy link
Contributor

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();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


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")

Copy link
Contributor

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

Copy link
Author

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")"

@mvines mvines added the CI Pull Request is ready to enter CI label Sep 30, 2019
@solana-grimes solana-grimes removed the CI Pull Request is ready to enter CI label Sep 30, 2019
@mvines
Copy link
Contributor

mvines commented Sep 30, 2019

Please feel free to promote this PR from "Draft" to a normal PR. I think this is almost ready to land!

Copy link
Author

@cyberbono3 cyberbono3 left a 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)"

warn!("Validator exits..");
// run vvalidator exit
}
*counter_ref += 1;
*c += 1;
Copy link
Author

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()?

Copy link
Contributor

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?

Copy link
Author

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

@mvines
Copy link
Contributor

mvines commented Sep 30, 2019

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)"

Ah, got it. Yep that's fine thanks :)

@cyberbono3
Copy link
Author

I ran cargo test in solana/core and got a following error

@cyberbono3
Copy link
Author

@mvines, you wrote :
.map(|accounts| { accounts .iter() .filter_map(|(pubkey, (stake, account))| {

Does this approach not work well?

What do you mean by that?

@cyberbono3 cyberbono3 marked this pull request as ready for review October 1, 2019 03:16
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" }
Copy link
Contributor

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

Copy link
Contributor

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

.map(|accounts| {
accounts
.iter()
.filter_map(|(pubkey, (stake, account))| {
Copy link
Contributor

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

Comment on lines 183 to 184
let bank_forks = bank_forks.clone();
let counter = Arc::new(AtomicUsize::new(0));
Copy link
Contributor

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()
}
Copy link
Contributor

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

@cyberbono3
Copy link
Author

i hope no more errors left. @mvines, could you review it, please?

@mvines
Copy link
Contributor

mvines commented Oct 3, 2019

Looks super close, thanks for your patience. I see two issues:

  • Your changes to validator/src/main.rs should go into validator/src/lib.rs instead
  • Can you please run cargo fmt, which will format the new code you're adding into the standard style

@cyberbono3
Copy link
Author

@mvines, I applied changes to validator/src/lib.rs and ran cargo fmt.

.send()
.and_then(|response| response.error_for_status())
.map_err(|err| format!("Unable to get: {:?}", err))?;
let client = ureq::agent();
Copy link
Contributor

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.

Copy link
Author

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?

Copy link
Contributor

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)

std::process::exit(1);
}
let bank = bank_forks.read().unwrap().working_bank();
let _: Vec<_> = bank
Copy link
Contributor

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

@cyberbono3
Copy link
Author

@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" }
Copy link
Contributor

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 Show resolved Hide resolved
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);
Copy link
Author

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?

Copy link
Contributor

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

  1. value None if the node is not stake, in which can we can std::process::exit(1)
  2. Some(stake) representing the current stake of the node, in which can we can warn! the user

@cyberbono3
Copy link
Author

in /core ran cargo test , it raised the following error

@mvines mvines added the CI Pull Request is ready to enter CI label Oct 16, 2019
@solana-grimes solana-grimes removed the CI Pull Request is ready to enter CI label Oct 16, 2019
@mvines
Copy link
Contributor

mvines commented Oct 16, 2019

Hey looks like there's some compile errors with the latest commits

.filter_map(|account| match account {
pubkey, (stake, accoount) => {
.filter_map(|account| match (account) {
Some(pubkey, (stake, account)) => {
Copy link
Author

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?

Copy link
Contributor

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.

Copy link
Author

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"

@cyberbono3
Copy link
Author

@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.

@mvines mvines added the CI Pull Request is ready to enter CI label Oct 31, 2019
@solana-grimes solana-grimes removed the CI Pull Request is ready to enter CI label Oct 31, 2019
Copy link
Contributor

@mvines mvines left a 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!

.filter_map(|account| match account {
pubkey, (stake, accoount) => {
.filter_map(|account| match (account) {
Some(pubkey, (stake, account)) => {
Copy link
Contributor

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");
Copy link
Contributor

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");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed rebase error here

account.iter().find(|(pubkey, (stake, account))| {
*pubkey == &keypair.pubkey()
&& *stake > 0
&& Ok(vote_state) == VoteState::deserialize(&account.data)
Copy link
Author

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?

Copy link
Contributor

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;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mvines it is already here

Copy link
Contributor

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()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CriesofCarrots thank you

@mvines
Copy link
Contributor

mvines commented Nov 5, 2019

It would be good to squash the 27 commits here into 1 single commit eventually

@cyberbono3
Copy link
Author

@mvines i have squashed multiple commits in one

@mvines
Copy link
Contributor

mvines commented Nov 9, 2019

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!

@mvines
Copy link
Contributor

mvines commented Nov 14, 2019

Obsoleted by #6874

@mvines mvines closed this Nov 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants