Skip to content

Commit

Permalink
fix: Use current validator for tracked shards check (#11828)
Browse files Browse the repository at this point in the history
See #11821 for context.

Check if this is a current validator using current epoch info, not
merely the fact that validator key exists.

# Testing

## Current Mainnet (protocol version 67)
Pre-requirements for the check to kick-in:
* `tracked_shards=[]` in `config.json`
* `validator_key.json` exists

Tested with different validator IDs:
* `node` - dummy validator ID, it **did not** crash
* `gritsly.poolv1.near` - existing validator with the lowest stake, not
marked as `CP` in the debug page, it **did not** crash
* `solidstate.poolv1.near` - existing validator with the lowest stake
that was marked as `CP` in the debug page, it **crashed**

## Current Testnet (protocol version 69)
Pre-requirements for the check to kick-in:
* `tracked_shards=[0]` in `config.json`
* `validator_key.json` exists

Tested with different validator IDs:
* `node` - dummy validator ID, it **did not** crash
* `lavenderfive.pool.f863973.m0` - existing validator with the lowest
stake, not marked as `CV` in the debug page, it **did not** crash
* `snsmlnn.pool.f863973.m0` - existing validator with the lowest stake
that was marked as `CV` in the debug page, it **crashed**
  • Loading branch information
staffik authored Jul 23, 2024
1 parent f29029a commit 3eb30ba
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions chain/client/src/client_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use near_primitives::block::Tip;
use near_primitives::block_header::ApprovalType;
use near_primitives::hash::CryptoHash;
use near_primitives::network::{AnnounceAccount, PeerId};
use near_primitives::types::{BlockHeight, EpochId};
use near_primitives::types::{AccountId, BlockHeight, EpochId};
use near_primitives::unwrap_or_return;
use near_primitives::utils::MaybeValidated;
use near_primitives::validator_signer::ValidatorSigner;
Expand Down Expand Up @@ -300,17 +300,27 @@ impl messaging::Actor for ClientActorInner {
}

/// Before stateless validation we require validators to track all shards, see
/// https://github.com/near/nearcore/issues/7388
fn check_validator_tracked_shards(client: &Client) -> Result<(), Error> {
/// https://github.com/near/nearcore/issues/7388.
/// Since stateless validation we use single shard tracking.
fn check_validator_tracked_shards(client: &Client, validator_id: &AccountId) -> Result<(), Error> {
if !matches!(
client.config.chain_id.as_ref(),
near_primitives::chains::MAINNET | near_primitives::chains::TESTNET
) {
return Ok(());
}
let head = client.chain.head()?;
let protocol_version =
client.epoch_manager.get_epoch_protocol_version(&head.epoch_id).into_chain_error()?;

let epoch_id = client.chain.head()?.epoch_id;
let epoch_info = client.epoch_manager.get_epoch_info(&epoch_id).into_chain_error()?;

// We do not apply the check if this is not a current validator, see
// https://github.com/near/nearcore/issues/11821.
if epoch_info.get_validator_by_account(validator_id).is_none() {
warn!(target: "client", "The account '{}' is not a current validator, this node won't be validating in the current epoch", validator_id);
return Ok(());
}

let protocol_version = epoch_info.protocol_version();

if !ProtocolFeature::StatelessValidation.enabled(protocol_version)
&& client.config.tracked_shards.is_empty()
Expand Down Expand Up @@ -343,7 +353,7 @@ impl ClientActorInner {
) -> Result<Self, Error> {
if let Some(vs) = &client.validator_signer.get() {
info!(target: "client", "Starting validator node: {}", vs.validator_id());
check_validator_tracked_shards(&client)?;
check_validator_tracked_shards(&client, vs.validator_id())?;
}
let info_helper = InfoHelper::new(clock.clone(), telemetry_sender, &client.config);

Expand Down Expand Up @@ -1196,9 +1206,14 @@ impl ClientActorInner {
},
&|validator_signer| self.client.update_validator_signer(validator_signer),
);

if update_result.validator_signer_updated {
check_validator_tracked_shards(&self.client)
let validator_signer =
self.client.validator_signer.get().expect("Validator signer just updated");

check_validator_tracked_shards(&self.client, validator_signer.validator_id())
.expect("Could not check validator tracked shards");

// Request PeerManager to advertise tier1 proxies.
// It is needed to advertise that our validator key changed.
self.network_adapter.send(PeerManagerMessageRequest::AdvertiseTier1Proxies);
Expand Down

0 comments on commit 3eb30ba

Please sign in to comment.