tower consensus naming (#4598)

s/locktower/tower/g
This commit is contained in:
anatoly yakovenko 2019-06-24 13:41:23 -07:00 committed by GitHub
parent 407b1d3e6f
commit 29611fb61d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 152 additions and 159 deletions

View File

@ -62,11 +62,11 @@
- [Blocktree](blocktree.md) - [Blocktree](blocktree.md)
- [Cluster Software Installation and Updates](installer.md) - [Cluster Software Installation and Updates](installer.md)
- [Deterministic Transaction Fees](transaction-fees.md) - [Deterministic Transaction Fees](transaction-fees.md)
- [Fork Selection](fork-selection.md) - [Tower BFT](tower-bft.md)
- [Leader-to-Leader Transition](leader-leader-transition.md) - [Leader-to-Leader Transition](leader-leader-transition.md)
- [Leader-to-Validator Transition](leader-validator-transition.md) - [Leader-to-Validator Transition](leader-validator-transition.md)
- [Passive Stake Delegation and Rewards](passive-stake-delegation-and-rewards.md) - [Passive Stake Delegation and Rewards](passive-stake-delegation-and-rewards.md)
- [Persistent Account Storage](persistent-account-storage.md) - [Persistent Account Storage](persistent-account-storage.md)
- [Reliable Vote Transmission](reliable-vote-transmission.md) - [Reliable Vote Transmission](reliable-vote-transmission.md)
- [Repair Service](repair-service.md) - [Repair Service](repair-service.md)
- [Testing Programs](testing-programs.md) - [Testing Programs](testing-programs.md)

View File

@ -4,7 +4,7 @@ A validator votes on a PoH hash for two purposes. First, the vote indicates it
believes the ledger is valid up until that point in time. Second, since many believes the ledger is valid up until that point in time. Second, since many
valid forks may exist at a given height, the vote also indicates exclusive valid forks may exist at a given height, the vote also indicates exclusive
support for the fork. This document describes only the former. The latter is support for the fork. This document describes only the former. The latter is
described in [fork selection](fork-selection.md). described in [Tower BFT](tower-bft.md).
## Current Design ## Current Design
@ -50,12 +50,11 @@ log the time since the NewBlock transaction was submitted.
### Finality and Payouts ### Finality and Payouts
Locktower is the proposed [fork selection](fork-selection.md) algorithm. It [Tower BFT](tower-bft.md) is the proposed fork selection algorithm. It proposes
proposes that payment to miners be postponed until the *stack* of validator that payment to miners be postponed until the *stack* of validator votes reaches
votes reaches a certain depth, at which point rollback is not economically a certain depth, at which point rollback is not economically feasible. The vote
feasible. The vote program may therefore implement locktower. Vote instructions program may therefore implement Tower BFT. Vote instructions would need to
would need to reference a global locktower account so that it can track reference a global Tower account so that it can track cross-block state.
cross-block state.
## Challenges ## Challenges

View File

@ -55,7 +55,7 @@ Validators can ignore forks at other points (e.g. from the wrong leader), or
slash the leader responsible for the fork. slash the leader responsible for the fork.
Validators vote based on a greedy choice to maximize their reward described in Validators vote based on a greedy choice to maximize their reward described in
[forks selection](fork-selection.md). [Tower BFT](tower-bft.md).
### Validator's View ### Validator's View

View File

@ -96,7 +96,7 @@ ends up scheduled for the first two epochs because the leader schedule is also
generated at slot 0 for the next epoch. The length of the first two epochs can generated at slot 0 for the next epoch. The length of the first two epochs can
be specified in the genesis block as well. The minimum length of the first be specified in the genesis block as well. The minimum length of the first
epochs must be greater than or equal to the maximum rollback depth as defined in epochs must be greater than or equal to the maximum rollback depth as defined in
[fork selection](fork-selection.md). [Tower BFT](tower-bft.md).
## Leader Schedule Generation Algorithm ## Leader Schedule Generation Algorithm

View File

@ -74,7 +74,7 @@ The program should have a list of slots which are valid storage mining slots.
This list should be maintained by keeping track of slots which are rooted slots in which a significant This list should be maintained by keeping track of slots which are rooted slots in which a significant
portion of the network has voted on with a high lockout value, maybe 32-votes old. Every SLOTS\_PER\_SEGMENT portion of the network has voted on with a high lockout value, maybe 32-votes old. Every SLOTS\_PER\_SEGMENT
number of slots would be added to this set. The program should check that the slot is in this set. The set can number of slots would be added to this set. The program should check that the slot is in this set. The set can
be maintained by receiving a AdvertiseStorageRecentBlockHash and checking with its bank/locktower state. be maintained by receiving a AdvertiseStorageRecentBlockHash and checking with its bank/Tower BFT state.
The program should do a signature verify check on the signature, public key from the transaction submitter and the message of The program should do a signature verify check on the signature, public key from the transaction submitter and the message of
the previous storage epoch PoH value. the previous storage epoch PoH value.

View File

@ -60,7 +60,7 @@ The read is satisfied by pointing to a memory-mapped location in the
## Root Forks ## Root Forks
The [fork selection algorithm](fork-selection.md) eventually selects a fork as a [Tower BFT](tower-bft.md) eventually selects a fork as a
root fork and the fork is squashed. A squashed/root fork cannot be rolled back. root fork and the fork is squashed. A squashed/root fork cannot be rolled back.
When a fork is squashed, all accounts in its parents not already present in the When a fork is squashed, all accounts in its parents not already present in the

View File

@ -77,7 +77,7 @@ count as stakes.
### VoteInstruction::Vote(Vec<Vote>) ### VoteInstruction::Vote(Vec<Vote>)
* `account[0]` - RW - The VoteState * `account[0]` - RW - The VoteState
`VoteState::lockouts` and `VoteState::credits` are updated according to voting lockout rules see [Fork Selection](fork-selection.md) `VoteState::lockouts` and `VoteState::credits` are updated according to voting lockout rules see [Tower BFT](tower-bft.md)
* `account[1]` - RO - A list of some N most recent slots and their hashes for the vote to be verified against. * `account[1]` - RO - A list of some N most recent slots and their hashes for the vote to be verified against.

View File

@ -1,7 +1,7 @@
# Fork Selection # Tower BFT
This design describes a *Fork Selection* algorithm. It addresses the following This design describes Solana's *Tower BFT* algorithm. It addresses the
problems: following problems:
* Some forks may not end up accepted by the super-majority of the cluster, and * Some forks may not end up accepted by the super-majority of the cluster, and
voters need to recover from voting on such forks. voters need to recover from voting on such forks.

View File

@ -85,7 +85,7 @@ impl Service for ClusterInfoVoteListener {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::locktower::MAX_RECENT_VOTES; use crate::consensus::MAX_RECENT_VOTES;
use crate::packet; use crate::packet;
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};

View File

@ -4,10 +4,10 @@ use crate::blocktree::Blocktree;
/// All tests must start from an entry point and a funding keypair and /// All tests must start from an entry point and a funding keypair and
/// discover the rest of the network. /// discover the rest of the network.
use crate::cluster_info::FULLNODE_PORT_RANGE; use crate::cluster_info::FULLNODE_PORT_RANGE;
use crate::consensus::VOTE_THRESHOLD_DEPTH;
use crate::contact_info::ContactInfo; use crate::contact_info::ContactInfo;
use crate::entry::{Entry, EntrySlice}; use crate::entry::{Entry, EntrySlice};
use crate::gossip_service::discover_cluster; use crate::gossip_service::discover_cluster;
use crate::locktower::VOTE_THRESHOLD_DEPTH;
use hashbrown::HashSet; use hashbrown::HashSet;
use solana_client::thin_client::create_client; use solana_client::thin_client::create_client;
use solana_runtime::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH; use solana_runtime::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH;

View File

@ -29,7 +29,7 @@ pub struct StakeLockout {
} }
#[derive(Default)] #[derive(Default)]
pub struct Locktower { pub struct Tower {
epoch_stakes: EpochStakes, epoch_stakes: EpochStakes,
threshold_depth: usize, threshold_depth: usize,
threshold_size: f64, threshold_size: f64,
@ -68,7 +68,7 @@ impl EpochStakes {
} }
} }
impl Locktower { impl Tower {
pub fn new_from_forks(bank_forks: &BankForks, my_pubkey: &Pubkey) -> Self { pub fn new_from_forks(bank_forks: &BankForks, my_pubkey: &Pubkey) -> Self {
let mut frozen_banks: Vec<_> = bank_forks.frozen_banks().values().cloned().collect(); let mut frozen_banks: Vec<_> = bank_forks.frozen_banks().values().cloned().collect();
frozen_banks.sort_by_key(|b| (b.parents().len(), b.slot())); frozen_banks.sort_by_key(|b| (b.parents().len(), b.slot()));
@ -80,7 +80,7 @@ impl Locktower {
} }
}; };
let mut locktower = Self { let mut tower = Self {
epoch_stakes, epoch_stakes,
threshold_depth: VOTE_THRESHOLD_DEPTH, threshold_depth: VOTE_THRESHOLD_DEPTH,
threshold_size: VOTE_THRESHOLD_SIZE, threshold_size: VOTE_THRESHOLD_SIZE,
@ -88,10 +88,9 @@ impl Locktower {
recent_votes: VecDeque::default(), recent_votes: VecDeque::default(),
}; };
let bank = locktower.find_heaviest_bank(bank_forks).unwrap(); let bank = tower.find_heaviest_bank(bank_forks).unwrap();
locktower.lockouts = tower.lockouts = Self::initialize_lockouts_from_bank(&bank, tower.epoch_stakes.epoch);
Self::initialize_lockouts_from_bank(&bank, locktower.epoch_stakes.epoch); tower
locktower
} }
pub fn new(epoch_stakes: EpochStakes, threshold_depth: usize, threshold_size: f64) -> Self { pub fn new(epoch_stakes: EpochStakes, threshold_depth: usize, threshold_size: f64) -> Self {
Self { Self {
@ -120,7 +119,7 @@ impl Locktower {
let vote_state = VoteState::from(&account); let vote_state = VoteState::from(&account);
if vote_state.is_none() { if vote_state.is_none() {
datapoint_warn!( datapoint_warn!(
"locktower_warn", "tower_warn",
( (
"warn", "warn",
format!("Unable to get vote_state from account {}", key), format!("Unable to get vote_state from account {}", key),
@ -141,7 +140,7 @@ impl Locktower {
); );
debug!("observed root {}", vote_state.root_slot.unwrap_or(0) as i64); debug!("observed root {}", vote_state.root_slot.unwrap_or(0) as i64);
datapoint_info!( datapoint_info!(
"locktower-observed", "tower-observed",
( (
"slot", "slot",
vote_state.nth_recent_vote(0).map(|v| v.slot).unwrap_or(0), vote_state.nth_recent_vote(0).map(|v| v.slot).unwrap_or(0),
@ -223,14 +222,14 @@ impl Locktower {
"epoch_stakes cannot move backwards" "epoch_stakes cannot move backwards"
); );
info!( info!(
"Locktower updated epoch bank slot: {} epoch: {}", "Tower updated epoch bank slot: {} epoch: {}",
bank.slot(), bank.slot(),
self.epoch_stakes.epoch self.epoch_stakes.epoch
); );
self.epoch_stakes = self.epoch_stakes =
EpochStakes::new_from_bank(bank, &self.epoch_stakes.delegate_pubkey); EpochStakes::new_from_bank(bank, &self.epoch_stakes.delegate_pubkey);
datapoint_info!( datapoint_info!(
"locktower-epoch", "tower-epoch",
("epoch", self.epoch_stakes.epoch, i64), ("epoch", self.epoch_stakes.epoch, i64),
("self_staked", self.epoch_stakes.self_staked, i64), ("self_staked", self.epoch_stakes.self_staked, i64),
("total_staked", self.epoch_stakes.total_staked, i64) ("total_staked", self.epoch_stakes.total_staked, i64)
@ -256,7 +255,7 @@ impl Locktower {
.retain(|vote| slots.iter().any(|slot| vote.slot == *slot)); .retain(|vote| slots.iter().any(|slot| vote.slot == *slot));
datapoint_info!( datapoint_info!(
"locktower-vote", "tower-vote",
("latest", slot, i64), ("latest", slot, i64),
("root", self.lockouts.root_slot.unwrap_or(0), i64) ("root", self.lockouts.root_slot.unwrap_or(0), i64)
); );
@ -429,11 +428,11 @@ mod test {
fn test_collect_vote_lockouts_no_epoch_stakes() { fn test_collect_vote_lockouts_no_epoch_stakes() {
let accounts = gen_stakes(&[(1, &[0])]); let accounts = gen_stakes(&[(1, &[0])]);
let epoch_stakes = EpochStakes::new_for_tests(2); let epoch_stakes = EpochStakes::new_for_tests(2);
let locktower = Locktower::new(epoch_stakes, 0, 0.67); let tower = Tower::new(epoch_stakes, 0, 0.67);
let ancestors = vec![(1, vec![0].into_iter().collect()), (0, HashSet::new())] let ancestors = vec![(1, vec![0].into_iter().collect()), (0, HashSet::new())]
.into_iter() .into_iter()
.collect(); .collect();
let staked_lockouts = locktower.collect_vote_lockouts(1, accounts.into_iter(), &ancestors); let staked_lockouts = tower.collect_vote_lockouts(1, accounts.into_iter(), &ancestors);
assert!(staked_lockouts.is_empty()); assert!(staked_lockouts.is_empty());
} }
@ -442,11 +441,11 @@ mod test {
//two accounts voting for slot 0 with 1 token staked //two accounts voting for slot 0 with 1 token staked
let accounts = gen_stakes(&[(1, &[0]), (1, &[0])]); let accounts = gen_stakes(&[(1, &[0]), (1, &[0])]);
let epoch_stakes = EpochStakes::new_from_stakes(0, &accounts); let epoch_stakes = EpochStakes::new_from_stakes(0, &accounts);
let locktower = Locktower::new(epoch_stakes, 0, 0.67); let tower = Tower::new(epoch_stakes, 0, 0.67);
let ancestors = vec![(1, vec![0].into_iter().collect()), (0, HashSet::new())] let ancestors = vec![(1, vec![0].into_iter().collect()), (0, HashSet::new())]
.into_iter() .into_iter()
.collect(); .collect();
let staked_lockouts = locktower.collect_vote_lockouts(1, accounts.into_iter(), &ancestors); let staked_lockouts = tower.collect_vote_lockouts(1, accounts.into_iter(), &ancestors);
assert_eq!(staked_lockouts[&0].stake, 2); assert_eq!(staked_lockouts[&0].stake, 2);
assert_eq!(staked_lockouts[&0].lockout, 2 + 2 + 4 + 4); assert_eq!(staked_lockouts[&0].lockout, 2 + 2 + 4 + 4);
} }
@ -457,14 +456,14 @@ mod test {
//two accounts voting for slot 0 with 1 token staked //two accounts voting for slot 0 with 1 token staked
let accounts = gen_stakes(&[(1, &votes), (1, &votes)]); let accounts = gen_stakes(&[(1, &votes), (1, &votes)]);
let epoch_stakes = EpochStakes::new_from_stakes(0, &accounts); let epoch_stakes = EpochStakes::new_from_stakes(0, &accounts);
let mut locktower = Locktower::new(epoch_stakes, 0, 0.67); let mut tower = Tower::new(epoch_stakes, 0, 0.67);
let mut ancestors = HashMap::new(); let mut ancestors = HashMap::new();
for i in 0..(MAX_LOCKOUT_HISTORY + 1) { for i in 0..(MAX_LOCKOUT_HISTORY + 1) {
locktower.record_vote(i as u64, Hash::default()); tower.record_vote(i as u64, Hash::default());
ancestors.insert(i as u64, (0..i as u64).into_iter().collect()); ancestors.insert(i as u64, (0..i as u64).into_iter().collect());
} }
assert_eq!(locktower.lockouts.root_slot, Some(0)); assert_eq!(tower.lockouts.root_slot, Some(0));
let staked_lockouts = locktower.collect_vote_lockouts( let staked_lockouts = tower.collect_vote_lockouts(
MAX_LOCKOUT_HISTORY as u64, MAX_LOCKOUT_HISTORY as u64,
accounts.into_iter(), accounts.into_iter(),
&ancestors, &ancestors,
@ -478,8 +477,8 @@ mod test {
#[test] #[test]
fn test_calculate_weight_skips_root() { fn test_calculate_weight_skips_root() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
locktower.lockouts.root_slot = Some(1); tower.lockouts.root_slot = Some(1);
let stakes = vec![ let stakes = vec![
( (
0, 0,
@ -498,12 +497,12 @@ mod test {
] ]
.into_iter() .into_iter()
.collect(); .collect();
assert_eq!(locktower.calculate_weight(&stakes), 0u128); assert_eq!(tower.calculate_weight(&stakes), 0u128);
} }
#[test] #[test]
fn test_calculate_weight() { fn test_calculate_weight() {
let locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -513,12 +512,12 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
assert_eq!(locktower.calculate_weight(&stakes), 8u128); assert_eq!(tower.calculate_weight(&stakes), 8u128);
} }
#[test] #[test]
fn test_check_vote_threshold_without_votes() { fn test_check_vote_threshold_without_votes() {
let locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -528,12 +527,12 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
assert!(locktower.check_vote_stake_threshold(0, &stakes)); assert!(tower.check_vote_stake_threshold(0, &stakes));
} }
#[test] #[test]
fn test_is_slot_confirmed_not_enough_stake_failure() { fn test_is_slot_confirmed_not_enough_stake_failure() {
let locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -543,19 +542,19 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
assert!(!locktower.is_slot_confirmed(0, &stakes)); assert!(!tower.is_slot_confirmed(0, &stakes));
} }
#[test] #[test]
fn test_is_slot_confirmed_unknown_slot() { fn test_is_slot_confirmed_unknown_slot() {
let locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = HashMap::new(); let stakes = HashMap::new();
assert!(!locktower.is_slot_confirmed(0, &stakes)); assert!(!tower.is_slot_confirmed(0, &stakes));
} }
#[test] #[test]
fn test_is_slot_confirmed_pass() { fn test_is_slot_confirmed_pass() {
let locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -565,68 +564,68 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
assert!(locktower.is_slot_confirmed(0, &stakes)); assert!(tower.is_slot_confirmed(0, &stakes));
} }
#[test] #[test]
fn test_is_locked_out_empty() { fn test_is_locked_out_empty() {
let locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = HashMap::new(); let descendants = HashMap::new();
assert!(!locktower.is_locked_out(0, &descendants)); assert!(!tower.is_locked_out(0, &descendants));
} }
#[test] #[test]
fn test_is_locked_out_root_slot_child_pass() { fn test_is_locked_out_root_slot_child_pass() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = vec![(0, vec![1].into_iter().collect())] let descendants = vec![(0, vec![1].into_iter().collect())]
.into_iter() .into_iter()
.collect(); .collect();
locktower.lockouts.root_slot = Some(0); tower.lockouts.root_slot = Some(0);
assert!(!locktower.is_locked_out(1, &descendants)); assert!(!tower.is_locked_out(1, &descendants));
} }
#[test] #[test]
fn test_is_locked_out_root_slot_sibling_fail() { fn test_is_locked_out_root_slot_sibling_fail() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = vec![(0, vec![1].into_iter().collect())] let descendants = vec![(0, vec![1].into_iter().collect())]
.into_iter() .into_iter()
.collect(); .collect();
locktower.lockouts.root_slot = Some(0); tower.lockouts.root_slot = Some(0);
assert!(locktower.is_locked_out(2, &descendants)); assert!(tower.is_locked_out(2, &descendants));
} }
#[test] #[test]
fn test_check_already_voted() { fn test_check_already_voted() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
assert!(locktower.has_voted(0)); assert!(tower.has_voted(0));
assert!(!locktower.has_voted(1)); assert!(!tower.has_voted(1));
} }
#[test] #[test]
fn test_is_locked_out_double_vote() { fn test_is_locked_out_double_vote() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = vec![(0, vec![1].into_iter().collect()), (1, HashSet::new())] let descendants = vec![(0, vec![1].into_iter().collect()), (1, HashSet::new())]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
locktower.record_vote(1, Hash::default()); tower.record_vote(1, Hash::default());
assert!(locktower.is_locked_out(0, &descendants)); assert!(tower.is_locked_out(0, &descendants));
} }
#[test] #[test]
fn test_is_locked_out_child() { fn test_is_locked_out_child() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = vec![(0, vec![1].into_iter().collect())] let descendants = vec![(0, vec![1].into_iter().collect())]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
assert!(!locktower.is_locked_out(1, &descendants)); assert!(!tower.is_locked_out(1, &descendants));
} }
#[test] #[test]
fn test_is_locked_out_sibling() { fn test_is_locked_out_sibling() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = vec![ let descendants = vec![
(0, vec![1, 2].into_iter().collect()), (0, vec![1, 2].into_iter().collect()),
(1, HashSet::new()), (1, HashSet::new()),
@ -634,30 +633,30 @@ mod test {
] ]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
locktower.record_vote(1, Hash::default()); tower.record_vote(1, Hash::default());
assert!(locktower.is_locked_out(2, &descendants)); assert!(tower.is_locked_out(2, &descendants));
} }
#[test] #[test]
fn test_is_locked_out_last_vote_expired() { fn test_is_locked_out_last_vote_expired() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 0, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 0, 0.67);
let descendants = vec![(0, vec![1, 4].into_iter().collect()), (1, HashSet::new())] let descendants = vec![(0, vec![1, 4].into_iter().collect()), (1, HashSet::new())]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
locktower.record_vote(1, Hash::default()); tower.record_vote(1, Hash::default());
assert!(!locktower.is_locked_out(4, &descendants)); assert!(!tower.is_locked_out(4, &descendants));
locktower.record_vote(4, Hash::default()); tower.record_vote(4, Hash::default());
assert_eq!(locktower.lockouts.votes[0].slot, 0); assert_eq!(tower.lockouts.votes[0].slot, 0);
assert_eq!(locktower.lockouts.votes[0].confirmation_count, 2); assert_eq!(tower.lockouts.votes[0].confirmation_count, 2);
assert_eq!(locktower.lockouts.votes[1].slot, 4); assert_eq!(tower.lockouts.votes[1].slot, 4);
assert_eq!(locktower.lockouts.votes[1].confirmation_count, 1); assert_eq!(tower.lockouts.votes[1].confirmation_count, 1);
} }
#[test] #[test]
fn test_check_vote_threshold_below_threshold() { fn test_check_vote_threshold_below_threshold() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -667,12 +666,12 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
assert!(!locktower.check_vote_stake_threshold(1, &stakes)); assert!(!tower.check_vote_stake_threshold(1, &stakes));
} }
#[test] #[test]
fn test_check_vote_threshold_above_threshold() { fn test_check_vote_threshold_above_threshold() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -682,13 +681,13 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
assert!(locktower.check_vote_stake_threshold(1, &stakes)); assert!(tower.check_vote_stake_threshold(1, &stakes));
} }
#[test] #[test]
fn test_check_vote_threshold_above_threshold_after_pop() { fn test_check_vote_threshold_above_threshold_after_pop() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = vec![( let stakes = vec![(
0, 0,
StakeLockout { StakeLockout {
@ -698,18 +697,18 @@ mod test {
)] )]
.into_iter() .into_iter()
.collect(); .collect();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
locktower.record_vote(1, Hash::default()); tower.record_vote(1, Hash::default());
locktower.record_vote(2, Hash::default()); tower.record_vote(2, Hash::default());
assert!(locktower.check_vote_stake_threshold(6, &stakes)); assert!(tower.check_vote_stake_threshold(6, &stakes));
} }
#[test] #[test]
fn test_check_vote_threshold_above_threshold_no_stake() { fn test_check_vote_threshold_above_threshold_no_stake() {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let stakes = HashMap::new(); let stakes = HashMap::new();
locktower.record_vote(0, Hash::default()); tower.record_vote(0, Hash::default());
assert!(!locktower.check_vote_stake_threshold(1, &stakes)); assert!(!tower.check_vote_stake_threshold(1, &stakes));
} }
#[test] #[test]
@ -724,7 +723,7 @@ mod test {
ancestors.insert(2, set); ancestors.insert(2, set);
let set: HashSet<u64> = vec![0u64].into_iter().collect(); let set: HashSet<u64> = vec![0u64].into_iter().collect();
ancestors.insert(1, set); ancestors.insert(1, set);
Locktower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors); Tower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors);
assert_eq!(stake_lockouts[&0].lockout, 2); assert_eq!(stake_lockouts[&0].lockout, 2);
assert_eq!(stake_lockouts[&1].lockout, 2); assert_eq!(stake_lockouts[&1].lockout, 2);
assert_eq!(stake_lockouts[&2].lockout, 2); assert_eq!(stake_lockouts[&2].lockout, 2);
@ -742,12 +741,12 @@ mod test {
slot: 2, slot: 2,
confirmation_count: 1, confirmation_count: 1,
}; };
Locktower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors); Tower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors);
let vote = Lockout { let vote = Lockout {
slot: 1, slot: 1,
confirmation_count: 2, confirmation_count: 2,
}; };
Locktower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors); Tower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors);
assert_eq!(stake_lockouts[&0].lockout, 2 + 4); assert_eq!(stake_lockouts[&0].lockout, 2 + 4);
assert_eq!(stake_lockouts[&1].lockout, 2 + 4); assert_eq!(stake_lockouts[&1].lockout, 2 + 4);
assert_eq!(stake_lockouts[&2].lockout, 2); assert_eq!(stake_lockouts[&2].lockout, 2);
@ -760,7 +759,7 @@ mod test {
account.lamports = 1; account.lamports = 1;
let set: HashSet<u64> = vec![0u64, 1u64].into_iter().collect(); let set: HashSet<u64> = vec![0u64, 1u64].into_iter().collect();
let ancestors: HashMap<u64, HashSet<u64>> = [(2u64, set)].into_iter().cloned().collect(); let ancestors: HashMap<u64, HashSet<u64>> = [(2u64, set)].into_iter().cloned().collect();
Locktower::update_ancestor_stakes(&mut stake_lockouts, 2, account.lamports, &ancestors); Tower::update_ancestor_stakes(&mut stake_lockouts, 2, account.lamports, &ancestors);
assert_eq!(stake_lockouts[&0].stake, 1); assert_eq!(stake_lockouts[&0].stake, 1);
assert_eq!(stake_lockouts[&1].stake, 1); assert_eq!(stake_lockouts[&1].stake, 1);
assert_eq!(stake_lockouts[&2].stake, 1); assert_eq!(stake_lockouts[&2].stake, 1);
@ -782,51 +781,48 @@ mod test {
let total_stake = 4; let total_stake = 4;
let threshold_size = 0.67; let threshold_size = 0.67;
let threshold_stake = (f64::ceil(total_stake as f64 * threshold_size)) as u64; let threshold_stake = (f64::ceil(total_stake as f64 * threshold_size)) as u64;
let locktower_votes: Vec<u64> = (0..VOTE_THRESHOLD_DEPTH as u64).collect(); let tower_votes: Vec<u64> = (0..VOTE_THRESHOLD_DEPTH as u64).collect();
let accounts = gen_stakes(&[ let accounts = gen_stakes(&[
(threshold_stake, &[(VOTE_THRESHOLD_DEPTH - 2) as u64]), (threshold_stake, &[(VOTE_THRESHOLD_DEPTH - 2) as u64]),
(total_stake - threshold_stake, &locktower_votes[..]), (total_stake - threshold_stake, &tower_votes[..]),
]); ]);
// Initialize locktower // Initialize tower
let stakes: HashMap<_, _> = accounts.iter().map(|(pk, (s, _))| (*pk, *s)).collect(); let stakes: HashMap<_, _> = accounts.iter().map(|(pk, (s, _))| (*pk, *s)).collect();
let epoch_stakes = EpochStakes::new(0, stakes, &Pubkey::default()); let epoch_stakes = EpochStakes::new(0, stakes, &Pubkey::default());
let mut locktower = Locktower::new(epoch_stakes, VOTE_THRESHOLD_DEPTH, threshold_size); let mut tower = Tower::new(epoch_stakes, VOTE_THRESHOLD_DEPTH, threshold_size);
// CASE 1: Record the first VOTE_THRESHOLD locktower votes for fork 2. We want to // CASE 1: Record the first VOTE_THRESHOLD tower votes for fork 2. We want to
// evaluate a vote on slot VOTE_THRESHOLD_DEPTH. The nth most recent vote should be // evaluate a vote on slot VOTE_THRESHOLD_DEPTH. The nth most recent vote should be
// for slot 0, which is common to all account vote states, so we should pass the // for slot 0, which is common to all account vote states, so we should pass the
// threshold check // threshold check
let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64; let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64;
for vote in &locktower_votes { for vote in &tower_votes {
locktower.record_vote(*vote, Hash::default()); tower.record_vote(*vote, Hash::default());
} }
let stakes_lockouts = locktower.collect_vote_lockouts( let stakes_lockouts =
vote_to_evaluate, tower.collect_vote_lockouts(vote_to_evaluate, accounts.clone().into_iter(), &ancestors);
accounts.clone().into_iter(), assert!(tower.check_vote_stake_threshold(vote_to_evaluate, &stakes_lockouts));
&ancestors,
);
assert!(locktower.check_vote_stake_threshold(vote_to_evaluate, &stakes_lockouts));
// CASE 2: Now we want to evaluate a vote for slot VOTE_THRESHOLD_DEPTH + 1. This slot // CASE 2: Now we want to evaluate a vote for slot VOTE_THRESHOLD_DEPTH + 1. This slot
// will expire the vote in one of the vote accounts, so we should have insufficient // will expire the vote in one of the vote accounts, so we should have insufficient
// stake to pass the threshold // stake to pass the threshold
let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64 + 1; let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64 + 1;
let stakes_lockouts = let stakes_lockouts =
locktower.collect_vote_lockouts(vote_to_evaluate, accounts.into_iter(), &ancestors); tower.collect_vote_lockouts(vote_to_evaluate, accounts.into_iter(), &ancestors);
assert!(!locktower.check_vote_stake_threshold(vote_to_evaluate, &stakes_lockouts)); assert!(!tower.check_vote_stake_threshold(vote_to_evaluate, &stakes_lockouts));
} }
fn vote_and_check_recent(num_votes: usize) { fn vote_and_check_recent(num_votes: usize) {
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67); let mut tower = Tower::new(EpochStakes::new_for_tests(2), 1, 0.67);
let start = num_votes.saturating_sub(MAX_RECENT_VOTES); let start = num_votes.saturating_sub(MAX_RECENT_VOTES);
let expected: Vec<_> = (start..num_votes) let expected: Vec<_> = (start..num_votes)
.map(|i| Vote::new(i as u64, Hash::default())) .map(|i| Vote::new(i as u64, Hash::default()))
.collect(); .collect();
for i in 0..num_votes { for i in 0..num_votes {
locktower.record_vote(i as u64, Hash::default()); tower.record_vote(i as u64, Hash::default());
} }
assert_eq!(expected, locktower.recent_votes()) assert_eq!(expected, tower.recent_votes())
} }
#[test] #[test]

View File

@ -30,6 +30,7 @@ pub mod cluster;
pub mod cluster_info; pub mod cluster_info;
pub mod cluster_info_repair_listener; pub mod cluster_info_repair_listener;
pub mod cluster_tests; pub mod cluster_tests;
pub mod consensus;
pub mod entry; pub mod entry;
pub mod erasure; pub mod erasure;
pub mod fetch_stage; pub mod fetch_stage;
@ -41,7 +42,6 @@ pub mod leader_schedule_cache;
pub mod leader_schedule_utils; pub mod leader_schedule_utils;
pub mod local_cluster; pub mod local_cluster;
pub mod local_vote_signer_service; pub mod local_vote_signer_service;
pub mod locktower;
pub mod packet; pub mod packet;
pub mod poh; pub mod poh;
pub mod poh_recorder; pub mod poh_recorder;

View File

@ -4,10 +4,10 @@ use crate::bank_forks::BankForks;
use crate::blocktree::Blocktree; use crate::blocktree::Blocktree;
use crate::blocktree_processor; use crate::blocktree_processor;
use crate::cluster_info::ClusterInfo; use crate::cluster_info::ClusterInfo;
use crate::consensus::{StakeLockout, Tower};
use crate::entry::{Entry, EntrySlice}; use crate::entry::{Entry, EntrySlice};
use crate::leader_schedule_cache::LeaderScheduleCache; use crate::leader_schedule_cache::LeaderScheduleCache;
use crate::leader_schedule_utils; use crate::leader_schedule_utils;
use crate::locktower::{Locktower, StakeLockout};
use crate::packet::BlobError; use crate::packet::BlobError;
use crate::poh_recorder::PohRecorder; use crate::poh_recorder::PohRecorder;
use crate::result::{Error, Result}; use crate::result::{Error, Result};
@ -102,7 +102,7 @@ impl ReplayStage {
let poh_recorder = poh_recorder.clone(); let poh_recorder = poh_recorder.clone();
let my_pubkey = *my_pubkey; let my_pubkey = *my_pubkey;
let mut ticks_per_slot = 0; let mut ticks_per_slot = 0;
let mut locktower = Locktower::new_from_forks(&bank_forks.read().unwrap(), &my_pubkey); let mut tower = Tower::new_from_forks(&bank_forks.read().unwrap(), &my_pubkey);
// Start the replay stage loop // Start the replay stage loop
let leader_schedule_cache = leader_schedule_cache.clone(); let leader_schedule_cache = leader_schedule_cache.clone();
let vote_account = *vote_account; let vote_account = *vote_account;
@ -142,8 +142,7 @@ impl ReplayStage {
ticks_per_slot = bank.ticks_per_slot(); ticks_per_slot = bank.ticks_per_slot();
} }
let votable = let votable = Self::generate_votable_banks(&bank_forks, &tower, &mut progress);
Self::generate_votable_banks(&bank_forks, &locktower, &mut progress);
if let Some((_, bank)) = votable.last() { if let Some((_, bank)) = votable.last() {
subscriptions.notify_subscribers(bank.slot(), &bank_forks); subscriptions.notify_subscribers(bank.slot(), &bank_forks);
@ -151,7 +150,7 @@ impl ReplayStage {
Self::handle_votable_bank( Self::handle_votable_bank(
&bank, &bank,
&bank_forks, &bank_forks,
&mut locktower, &mut tower,
&mut progress, &mut progress,
&vote_account, &vote_account,
&voting_keypair, &voting_keypair,
@ -318,7 +317,7 @@ impl ReplayStage {
fn handle_votable_bank<T>( fn handle_votable_bank<T>(
bank: &Arc<Bank>, bank: &Arc<Bank>,
bank_forks: &Arc<RwLock<BankForks>>, bank_forks: &Arc<RwLock<BankForks>>,
locktower: &mut Locktower, tower: &mut Tower,
progress: &mut HashMap<u64, ForkProgress>, progress: &mut HashMap<u64, ForkProgress>,
vote_account: &Pubkey, vote_account: &Pubkey,
voting_keypair: &Option<Arc<T>>, voting_keypair: &Option<Arc<T>>,
@ -330,7 +329,7 @@ impl ReplayStage {
where where
T: 'static + KeypairUtil + Send + Sync, T: 'static + KeypairUtil + Send + Sync,
{ {
if let Some(new_root) = locktower.record_vote(bank.slot(), bank.hash()) { if let Some(new_root) = tower.record_vote(bank.slot(), bank.hash()) {
// get the root bank before squash // get the root bank before squash
let root_bank = bank_forks let root_bank = bank_forks
.read() .read()
@ -352,7 +351,7 @@ impl ReplayStage {
Self::handle_new_root(&bank_forks, progress); Self::handle_new_root(&bank_forks, progress);
root_bank_sender.send(rooted_banks)?; root_bank_sender.send(rooted_banks)?;
} }
locktower.update_epoch(&bank); tower.update_epoch(&bank);
if let Some(ref voting_keypair) = voting_keypair { if let Some(ref voting_keypair) = voting_keypair {
let node_keypair = cluster_info.read().unwrap().keypair.clone(); let node_keypair = cluster_info.read().unwrap().keypair.clone();
@ -360,7 +359,7 @@ impl ReplayStage {
let vote_ix = vote_instruction::vote( let vote_ix = vote_instruction::vote(
&vote_account, &vote_account,
&voting_keypair.pubkey(), &voting_keypair.pubkey(),
locktower.recent_votes(), tower.recent_votes(),
); );
let mut vote_tx = let mut vote_tx =
@ -438,11 +437,11 @@ impl ReplayStage {
fn generate_votable_banks( fn generate_votable_banks(
bank_forks: &Arc<RwLock<BankForks>>, bank_forks: &Arc<RwLock<BankForks>>,
locktower: &Locktower, tower: &Tower,
progress: &mut HashMap<u64, ForkProgress>, progress: &mut HashMap<u64, ForkProgress>,
) -> Vec<(u128, Arc<Bank>)> { ) -> Vec<(u128, Arc<Bank>)> {
let locktower_start = Instant::now(); let tower_start = Instant::now();
// Locktower voting // Tower voting
let descendants = bank_forks.read().unwrap().descendants(); let descendants = bank_forks.read().unwrap().descendants();
let ancestors = bank_forks.read().unwrap().ancestors(); let ancestors = bank_forks.read().unwrap().ancestors();
let frozen_banks = bank_forks.read().unwrap().frozen_banks(); let frozen_banks = bank_forks.read().unwrap().frozen_banks();
@ -456,24 +455,24 @@ impl ReplayStage {
is_votable is_votable
}) })
.filter(|b| { .filter(|b| {
let is_recent_epoch = locktower.is_recent_epoch(b); let is_recent_epoch = tower.is_recent_epoch(b);
trace!("bank is is_recent_epoch: {} {}", b.slot(), is_recent_epoch); trace!("bank is is_recent_epoch: {} {}", b.slot(), is_recent_epoch);
is_recent_epoch is_recent_epoch
}) })
.filter(|b| { .filter(|b| {
let has_voted = locktower.has_voted(b.slot()); let has_voted = tower.has_voted(b.slot());
trace!("bank is has_voted: {} {}", b.slot(), has_voted); trace!("bank is has_voted: {} {}", b.slot(), has_voted);
!has_voted !has_voted
}) })
.filter(|b| { .filter(|b| {
let is_locked_out = locktower.is_locked_out(b.slot(), &descendants); let is_locked_out = tower.is_locked_out(b.slot(), &descendants);
trace!("bank is is_locked_out: {} {}", b.slot(), is_locked_out); trace!("bank is is_locked_out: {} {}", b.slot(), is_locked_out);
!is_locked_out !is_locked_out
}) })
.map(|bank| { .map(|bank| {
( (
bank, bank,
locktower.collect_vote_lockouts( tower.collect_vote_lockouts(
bank.slot(), bank.slot(),
bank.vote_accounts().into_iter(), bank.vote_accounts().into_iter(),
&ancestors, &ancestors,
@ -481,43 +480,42 @@ impl ReplayStage {
) )
}) })
.filter(|(b, stake_lockouts)| { .filter(|(b, stake_lockouts)| {
let vote_threshold = let vote_threshold = tower.check_vote_stake_threshold(b.slot(), &stake_lockouts);
locktower.check_vote_stake_threshold(b.slot(), &stake_lockouts); Self::confirm_forks(tower, stake_lockouts, progress, bank_forks);
Self::confirm_forks(locktower, stake_lockouts, progress, bank_forks);
debug!("bank vote_threshold: {} {}", b.slot(), vote_threshold); debug!("bank vote_threshold: {} {}", b.slot(), vote_threshold);
vote_threshold vote_threshold
}) })
.map(|(b, stake_lockouts)| (locktower.calculate_weight(&stake_lockouts), b.clone())) .map(|(b, stake_lockouts)| (tower.calculate_weight(&stake_lockouts), b.clone()))
.collect(); .collect();
votable.sort_by_key(|b| b.0); votable.sort_by_key(|b| b.0);
let ms = timing::duration_as_ms(&locktower_start.elapsed()); let ms = timing::duration_as_ms(&tower_start.elapsed());
trace!("votable_banks {}", votable.len()); trace!("votable_banks {}", votable.len());
if !votable.is_empty() { if !votable.is_empty() {
let weights: Vec<u128> = votable.iter().map(|x| x.0).collect(); let weights: Vec<u128> = votable.iter().map(|x| x.0).collect();
info!( info!(
"@{:?} locktower duration: {:?} len: {} weights: {:?}", "@{:?} tower duration: {:?} len: {} weights: {:?}",
timing::timestamp(), timing::timestamp(),
ms, ms,
votable.len(), votable.len(),
weights weights
); );
} }
inc_new_counter_info!("replay_stage-locktower_duration", ms as usize); inc_new_counter_info!("replay_stage-tower_duration", ms as usize);
votable votable
} }
fn confirm_forks( fn confirm_forks(
locktower: &Locktower, tower: &Tower,
stake_lockouts: &HashMap<u64, StakeLockout>, stake_lockouts: &HashMap<u64, StakeLockout>,
progress: &mut HashMap<u64, ForkProgress>, progress: &mut HashMap<u64, ForkProgress>,
bank_forks: &Arc<RwLock<BankForks>>, bank_forks: &Arc<RwLock<BankForks>>,
) { ) {
progress.retain(|slot, prog| { progress.retain(|slot, prog| {
let duration = timing::timestamp() - prog.started_ms; let duration = timing::timestamp() - prog.started_ms;
if locktower.is_slot_confirmed(*slot, stake_lockouts) if tower.is_slot_confirmed(*slot, stake_lockouts)
&& bank_forks && bank_forks
.read() .read()
.unwrap() .unwrap()

View File

@ -5366,8 +5366,8 @@
{ {
"aliasColors": { "aliasColors": {
"cluster-info.repair": "#ba43a9", "cluster-info.repair": "#ba43a9",
"locktower-observed.squash_account": "#0a437c", "tower-observed.squash_account": "#0a437c",
"locktower-observed.squash_cache": "#ea6460", "tower-observed.squash_cache": "#ea6460",
"replay_stage-new_leader.last": "#00ffbb", "replay_stage-new_leader.last": "#00ffbb",
"window-service.receive": "#b7dbab", "window-service.receive": "#b7dbab",
"window-stage.consumed": "#5195ce" "window-stage.consumed": "#5195ce"
@ -5465,7 +5465,7 @@
"measurement": "cluster_info-vote-count", "measurement": "cluster_info-vote-count",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "autogen", "policy": "autogen",
"query": "SELECT mean(\"squash_accounts_ms\") AS \"squash_account\" FROM \"$testnet\".\"autogen\".\"locktower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)", "query": "SELECT mean(\"squash_accounts_ms\") AS \"squash_account\" FROM \"$testnet\".\"autogen\".\"tower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)",
"rawQuery": true, "rawQuery": true,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@ -5504,7 +5504,7 @@
"measurement": "cluster_info-vote-count", "measurement": "cluster_info-vote-count",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "autogen", "policy": "autogen",
"query": "SELECT mean(\"squash_cache_ms\") AS \"squash_cache\" FROM \"$testnet\".\"autogen\".\"locktower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)", "query": "SELECT mean(\"squash_cache_ms\") AS \"squash_cache\" FROM \"$testnet\".\"autogen\".\"tower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)",
"rawQuery": true, "rawQuery": true,
"refId": "C", "refId": "C",
"resultFormat": "time_series", "resultFormat": "time_series",
@ -5576,7 +5576,7 @@
"cluster-info.repair": "#ba43a9", "cluster-info.repair": "#ba43a9",
"fetch_stage-discard_forwards.sum": "#00ffbb", "fetch_stage-discard_forwards.sum": "#00ffbb",
"fetch_stage-honor_forwards.sum": "#bf1b00", "fetch_stage-honor_forwards.sum": "#bf1b00",
"locktower-vote.last": "#00ffbb", "tower-vote.last": "#00ffbb",
"replay_stage-new_leader.last": "#00ffbb", "replay_stage-new_leader.last": "#00ffbb",
"window-service.receive": "#b7dbab", "window-service.receive": "#b7dbab",
"window-stage.consumed": "#5195ce" "window-stage.consumed": "#5195ce"
@ -5892,7 +5892,7 @@
"cluster-info.repair": "#ba43a9", "cluster-info.repair": "#ba43a9",
"fetch_stage-discard_forwards.sum": "#00ffbb", "fetch_stage-discard_forwards.sum": "#00ffbb",
"fetch_stage-honor_forwards.sum": "#bf1b00", "fetch_stage-honor_forwards.sum": "#bf1b00",
"locktower-vote.last": "#00ffbb", "tower-vote.last": "#00ffbb",
"poh_recorder-record_lock_contention.sum": "#5195ce", "poh_recorder-record_lock_contention.sum": "#5195ce",
"poh_recorder-tick_lock_contention.sum": "#962d82", "poh_recorder-tick_lock_contention.sum": "#962d82",
"replay_stage-new_leader.last": "#00ffbb", "replay_stage-new_leader.last": "#00ffbb",
@ -7089,7 +7089,7 @@
"measurement": "cluster_info-vote-count", "measurement": "cluster_info-vote-count",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "autogen", "policy": "autogen",
"query": "SELECT last(\"latest\") - last(\"root\") FROM \"$testnet\".\"autogen\".\"locktower-vote\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)", "query": "SELECT last(\"latest\") - last(\"root\") FROM \"$testnet\".\"autogen\".\"tower-vote\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)",
"rawQuery": true, "rawQuery": true,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@ -7126,7 +7126,7 @@
], ],
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT last(\"slot\") - last(\"root\") FROM \"$testnet\".\"autogen\".\"locktower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)", "query": "SELECT last(\"slot\") - last(\"root\") FROM \"$testnet\".\"autogen\".\"tower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)",
"rawQuery": true, "rawQuery": true,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@ -7190,7 +7190,7 @@
{ {
"aliasColors": { "aliasColors": {
"cluster-info.repair": "#ba43a9", "cluster-info.repair": "#ba43a9",
"locktower-vote.last": "#00ffbb", "tower-vote.last": "#00ffbb",
"replay_stage-new_leader.last": "#00ffbb", "replay_stage-new_leader.last": "#00ffbb",
"window-service.receive": "#b7dbab", "window-service.receive": "#b7dbab",
"window-stage.consumed": "#5195ce" "window-stage.consumed": "#5195ce"
@ -7249,7 +7249,7 @@
"measurement": "cluster_info-vote-count", "measurement": "cluster_info-vote-count",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "autogen", "policy": "autogen",
"query": "SELECT last(\"root\") FROM \"$testnet\".\"autogen\".\"locktower-vote\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)", "query": "SELECT last(\"root\") FROM \"$testnet\".\"autogen\".\"tower-vote\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)",
"rawQuery": true, "rawQuery": true,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@ -7286,7 +7286,7 @@
], ],
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT last(\"root\") FROM \"$testnet\".\"autogen\".\"locktower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)", "query": "SELECT last(\"root\") FROM \"$testnet\".\"autogen\".\"tower-observed\" WHERE host_id =~ /$hostid/ AND $timeFilter GROUP BY time($__interval)",
"rawQuery": true, "rawQuery": true,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@ -8100,4 +8100,4 @@
"title": "Testnet Monitor (edge)", "title": "Testnet Monitor (edge)",
"uid": "testnet-edge", "uid": "testnet-edge",
"version": 3 "version": 3
} }

View File

@ -525,7 +525,7 @@ impl Bank {
let squash_cache_ms = duration_as_ms(&squash_cache_start.elapsed()); let squash_cache_ms = duration_as_ms(&squash_cache_start.elapsed());
datapoint_info!( datapoint_info!(
"locktower-observed", "tower-observed",
("squash_accounts_ms", squash_accounts_ms, i64), ("squash_accounts_ms", squash_accounts_ms, i64),
("squash_cache_ms", squash_cache_ms, i64) ("squash_cache_ms", squash_cache_ms, i64)
); );