Rename bootstrap leader (#7906)

* Rename bootstrap leader to bootstrap validator

It's a normal validator as soon as other validators enter the
leader schedule.

* cargo fmt

* Fix build

Thanks @CriesofCarrots!
This commit is contained in:
Greg Fitzgerald 2020-01-22 09:22:09 -07:00 committed by GitHub
parent 65f5885bce
commit 3aabeb2b81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 158 additions and 155 deletions

View File

@ -4,7 +4,7 @@ A Solana cluster is a set of validators working together to serve client transac
## Creating a Cluster
Before starting any validators, one first needs to create a _genesis config_. The config references two public keys, a _mint_ and a _bootstrap leader_. The validator holding the bootstrap leader's private key is responsible for appending the first entries to the ledger. It initializes its internal state with the mint's account. That account will hold the number of native tokens defined by the genesis config. The second validator then contacts the bootstrap leader to register as a _validator_ or _archiver_. Additional validators then register with any registered member of the cluster.
Before starting any validators, one first needs to create a _genesis config_. The config references two public keys, a _mint_ and a _bootstrap validator_. The validator holding the bootstrap validator's private key is responsible for appending the first entries to the ledger. It initializes its internal state with the mint's account. That account will hold the number of native tokens defined by the genesis config. The second validator then contacts the bootstrap validator to register as a _validator_ or _archiver_. Additional validators then register with any registered member of the cluster.
A validator receives all entries from the leader and submits votes confirming those entries are valid. After voting, the validator is expected to store those entries until archiver nodes submit proofs that they have stored copies of it. Once the validator observes a sufficient number of copies exist, it deletes its copy.

View File

@ -52,12 +52,12 @@ $ NDEBUG=1 ./multinode-demo/faucet.sh
### Singlenode Testnet
Before you start a validator, make sure you know the IP address of the machine you want to be the bootstrap leader for the demo, and make sure that udp ports 8000-10000 are open on all the machines you want to test with.
Before you start a validator, make sure you know the IP address of the machine you want to be the bootstrap validator for the demo, and make sure that udp ports 8000-10000 are open on all the machines you want to test with.
Now start the bootstrap leader in a separate shell:
Now start the bootstrap validator in a separate shell:
```bash
$ NDEBUG=1 ./multinode-demo/bootstrap-leader.sh
$ NDEBUG=1 ./multinode-demo/bootstrap-validator.sh
```
Wait a few seconds for the server to initialize. It will print "leader ready..." when it's ready to receive transactions. The leader will request some tokens from the faucet if it doesn't have any. The faucet does not need to be running for subsequent leader starts.
@ -74,7 +74,7 @@ To run a performance-enhanced validator on Linux, [CUDA 10.0](https://developer.
```bash
$ ./fetch-perf-libs.sh
$ NDEBUG=1 SOLANA_CUDA=1 ./multinode-demo/bootstrap-leader.sh
$ NDEBUG=1 SOLANA_CUDA=1 ./multinode-demo/bootstrap-validator.sh
$ NDEBUG=1 SOLANA_CUDA=1 ./multinode-demo/validator.sh
```

View File

@ -26,7 +26,7 @@ A preimage resistant [hash](terminology.md#hash) of the [ledger](terminology.md#
The number of [blocks](terminology.md#block) beneath the current block. The first block after the [genesis block](terminology.md#genesis-block) has height one.
## bootstrap leader
## bootstrap validator
The first [validator](terminology.md#validator) to produce a [block](terminology.md#block).

View File

@ -29,7 +29,7 @@ Start a local cluster and run sanity on it
-x - Add an extra validator (may be supplied multiple times)
-r - Select the RPC endpoint hosted by a node that starts as
a validator node. If unspecified the RPC endpoint hosted by
the bootstrap leader will be used.
the bootstrap validator will be used.
-c - Reuse existing node/ledger configuration from a previous sanity
run
@ -74,7 +74,7 @@ source multinode-demo/common.sh
nodes=(
"multinode-demo/faucet.sh"
"multinode-demo/bootstrap-leader.sh \
"multinode-demo/bootstrap-validator.sh \
--no-restart \
--init-complete-file init-complete-node1.log \
--dynamic-port-range 8000-8050"
@ -170,7 +170,7 @@ startNodes() {
logs+=("$(getNodeLogFile "$i" "$cmd")")
fi
# 1 == bootstrap leader, wait until it boots before starting
# 1 == bootstrap validator, wait until it boots before starting
# other validators
if [[ "$i" -eq 1 ]]; then
SECONDS=
@ -178,7 +178,7 @@ startNodes() {
(
set -x
$solana_cli --keypair config/bootstrap-leader/identity-keypair.json \
$solana_cli --keypair config/bootstrap-validator/identity-keypair.json \
--url http://127.0.0.1:8899 genesis-hash
) | tee genesis-hash.log
maybeExpectedGenesisHash="--expected-genesis-hash $(tail -n1 genesis-hash.log)"
@ -277,7 +277,7 @@ rollingNodeRestart() {
}
verifyLedger() {
for ledger in bootstrap-leader validator; do
for ledger in bootstrap-validator validator; do
echo "--- $ledger ledger verification"
(
set -x
@ -331,7 +331,7 @@ while [[ $iteration -le $iterations ]]; do
rm -rf $client_keypair
) || flag_error
echo "--- RPC API: bootstrap-leader getTransactionCount ($iteration)"
echo "--- RPC API: bootstrap-validator getTransactionCount ($iteration)"
(
set -x
curl --retry 5 --retry-delay 2 --retry-connrefused \
@ -351,7 +351,7 @@ while [[ $iteration -le $iterations ]]; do
http://localhost:18899
) || flag_error
# Verify transaction count as reported by the bootstrap-leader node is advancing
# Verify transaction count as reported by the bootstrap-validator node is advancing
transactionCount=$(sed -e 's/{"jsonrpc":"2.0","result":\([0-9]*\),"id":1}/\1/' log-transactionCount.txt)
if [[ -n $lastTransactionCount ]]; then
echo "--- Transaction count check: $lastTransactionCount < $transactionCount"

View File

@ -2293,7 +2293,7 @@ pub mod tests {
.expect("process transaction");
assert_eq!(bank.vote_accounts().len(), 2);
// Check getVoteAccounts: the bootstrap leader vote account will be delinquent as it has
// Check getVoteAccounts: the bootstrap validator vote account will be delinquent as it has
// stake but has never voted, and the vote account with no stake should not be present.
{
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getVoteAccounts"}}"#);

View File

@ -288,7 +288,7 @@ impl Validator {
);
// Insert the entrypoint info, should only be None if this node
// is the bootstrap leader
// is the bootstrap validator
if let Some(entrypoint_info) = entrypoint_info_option {
cluster_info
.write()

View File

@ -121,11 +121,11 @@ fn main() -> Result<(), Box<dyn error::Error>> {
)
};
// vote account
let default_bootstrap_leader_lamports = &sol_to_lamports(500.0)
let default_bootstrap_validator_lamports = &sol_to_lamports(500.0)
.max(VoteState::get_rent_exempt_reserve(&rent))
.to_string();
// stake account
let default_bootstrap_leader_stake_lamports = &sol_to_lamports(0.5)
let default_bootstrap_validator_stake_lamports = &sol_to_lamports(0.5)
.max(StakeState::get_rent_exempt_reserve(&rent))
.to_string();
@ -143,16 +143,16 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.value_name("RFC3339 DATE TIME")
.validator(is_rfc3339_datetime)
.takes_value(true)
.help("Time when the bootstrap leader will start the cluster [default: current system time]"),
.help("Time when the bootstrap validator will start the cluster [default: current system time]"),
)
.arg(
Arg::with_name("bootstrap_leader_pubkey_file")
Arg::with_name("bootstrap_validator_pubkey_file")
.short("b")
.long("bootstrap-leader-pubkey")
.value_name("BOOTSTRAP LEADER PUBKEY")
.long("bootstrap-validator-pubkey")
.value_name("BOOTSTRAP VALIDATOR PUBKEY")
.takes_value(true)
.required(true)
.help("Path to file containing the bootstrap leader's pubkey"),
.help("Path to file containing the bootstrap validator's pubkey"),
)
.arg(
Arg::with_name("ledger_path")
@ -187,7 +187,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.value_name("BOOTSTRAP VOTE PUBKEY")
.takes_value(true)
.required(true)
.help("Path to file containing the bootstrap leader's voting pubkey"),
.help("Path to file containing the bootstrap validator's voting pubkey"),
)
.arg(
Arg::with_name("bootstrap_stake_pubkey_file")
@ -195,39 +195,39 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.value_name("BOOTSTRAP STAKE PUBKEY")
.takes_value(true)
.required(true)
.help("Path to file containing the bootstrap leader's staking pubkey"),
.help("Path to file containing the bootstrap validator's staking pubkey"),
)
.arg(
Arg::with_name("bootstrap_stake_authorized_pubkey_file")
.long("bootstrap-stake-authorized-pubkey")
.value_name("BOOTSTRAP STAKE AUTHORIZED PUBKEY")
.takes_value(true)
.help("Path to file containing the pubkey authorized to manage the bootstrap leader's stake [default: --bootstrap-leader-pubkey]"),
.help("Path to file containing the pubkey authorized to manage the bootstrap validator's stake [default: --bootstrap-validator-pubkey]"),
)
.arg(
Arg::with_name("bootstrap_storage_pubkey_file")
.long("bootstrap-storage-pubkey")
.value_name("BOOTSTRAP STORAGE PUBKEY")
.takes_value(true)
.help("Path to file containing the bootstrap leader's storage pubkey"),
.help("Path to file containing the bootstrap validator's storage pubkey"),
)
.arg(
Arg::with_name("bootstrap_leader_lamports")
.long("bootstrap-leader-lamports")
Arg::with_name("bootstrap_validator_lamports")
.long("bootstrap-validator-lamports")
.value_name("LAMPORTS")
.takes_value(true)
.default_value(default_bootstrap_leader_lamports)
.default_value(default_bootstrap_validator_lamports)
.required(true)
.help("Number of lamports to assign to the bootstrap leader"),
.help("Number of lamports to assign to the bootstrap validator"),
)
.arg(
Arg::with_name("bootstrap_leader_stake_lamports")
.long("bootstrap-leader-stake-lamports")
Arg::with_name("bootstrap_validator_stake_lamports")
.long("bootstrap-validator-stake-lamports")
.value_name("LAMPORTS")
.takes_value(true)
.default_value(default_bootstrap_leader_stake_lamports)
.default_value(default_bootstrap_validator_stake_lamports)
.required(true)
.help("Number of lamports to assign to the bootstrap leader's stake account"),
.help("Number of lamports to assign to the bootstrap validator's stake account"),
)
.arg(
Arg::with_name("target_lamports_per_signature")
@ -366,15 +366,16 @@ fn main() -> Result<(), Box<dyn error::Error>> {
}
}
let bootstrap_leader_lamports = value_t_or_exit!(matches, "bootstrap_leader_lamports", u64);
let bootstrap_validator_lamports =
value_t_or_exit!(matches, "bootstrap_validator_lamports", u64);
let bootstrap_leader_stake_lamports = rent_exempt_check(
let bootstrap_validator_stake_lamports = rent_exempt_check(
&matches,
"bootstrap_leader_stake_lamports",
"bootstrap_validator_stake_lamports",
StakeState::get_rent_exempt_reserve(&rent),
)?;
let bootstrap_leader_pubkey = required_pubkey(&matches, "bootstrap_leader_pubkey_file")?;
let bootstrap_validator_pubkey = required_pubkey(&matches, "bootstrap_validator_pubkey_file")?;
let bootstrap_vote_pubkey = required_pubkey(&matches, "bootstrap_vote_pubkey_file")?;
let bootstrap_stake_pubkey = required_pubkey(&matches, "bootstrap_stake_pubkey_file")?;
let bootstrap_stake_authorized_pubkey =
@ -382,33 +383,33 @@ fn main() -> Result<(), Box<dyn error::Error>> {
let bootstrap_storage_pubkey = pubkey_of(&matches, "bootstrap_storage_pubkey_file");
let faucet_pubkey = pubkey_of(&matches, "faucet_pubkey_file");
let bootstrap_leader_vote_account = vote_state::create_account(
let bootstrap_validator_vote_account = vote_state::create_account(
&bootstrap_vote_pubkey,
&bootstrap_leader_pubkey,
&bootstrap_validator_pubkey,
100,
VoteState::get_rent_exempt_reserve(&rent).max(1),
);
let bootstrap_leader_stake_account = stake_state::create_account(
let bootstrap_validator_stake_account = stake_state::create_account(
bootstrap_stake_authorized_pubkey
.as_ref()
.unwrap_or(&bootstrap_leader_pubkey),
.unwrap_or(&bootstrap_validator_pubkey),
&bootstrap_vote_pubkey,
&bootstrap_leader_vote_account,
&bootstrap_validator_vote_account,
&rent,
bootstrap_leader_stake_lamports,
bootstrap_validator_stake_lamports,
);
let mut accounts: BTreeMap<Pubkey, Account> = [
// node needs an account to issue votes from
(
bootstrap_leader_pubkey,
Account::new(bootstrap_leader_lamports, 0, &system_program::id()),
bootstrap_validator_pubkey,
Account::new(bootstrap_validator_lamports, 0, &system_program::id()),
),
// where votes go to
(bootstrap_vote_pubkey, bootstrap_leader_vote_account),
// bootstrap leader stake
(bootstrap_stake_pubkey, bootstrap_leader_stake_account),
(bootstrap_vote_pubkey, bootstrap_validator_vote_account),
// bootstrap validator stake
(bootstrap_stake_pubkey, bootstrap_validator_stake_account),
]
.iter()
.cloned()
@ -417,7 +418,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
if let Some(bootstrap_storage_pubkey) = bootstrap_storage_pubkey {
accounts.insert(
bootstrap_storage_pubkey,
storage_contract::create_validator_storage_account(bootstrap_leader_pubkey, 1),
storage_contract::create_validator_storage_account(bootstrap_validator_pubkey, 1),
);
}

View File

@ -1,14 +1,14 @@
pub use solana_runtime::genesis_utils::{
create_genesis_config_with_leader, GenesisConfigInfo, BOOTSTRAP_LEADER_LAMPORTS,
create_genesis_config_with_leader, GenesisConfigInfo, BOOTSTRAP_VALIDATOR_LAMPORTS,
};
use solana_sdk::pubkey::Pubkey;
// same as genesis_config::create_genesis_config, but with bootstrap_leader staking logic
// same as genesis_config::create_genesis_config, but with bootstrap_validator staking logic
// for the core crate tests
pub fn create_genesis_config(mint_lamports: u64) -> GenesisConfigInfo {
create_genesis_config_with_leader(
mint_lamports,
&Pubkey::new_rand(),
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
)
}

View File

@ -258,7 +258,7 @@ mod tests {
blockstore::make_slot_entries,
genesis_utils::{
create_genesis_config, create_genesis_config_with_leader, GenesisConfigInfo,
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
},
get_tmp_ledger_path,
staking_utils::tests::setup_vote_and_stake_accounts,
@ -376,9 +376,9 @@ mod tests {
fn test_next_leader_slot() {
let pubkey = Pubkey::new_rand();
let mut genesis_config = create_genesis_config_with_leader(
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
&pubkey,
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
)
.genesis_config;
genesis_config.epoch_schedule = EpochSchedule::custom(
@ -427,9 +427,9 @@ mod tests {
fn test_next_leader_slot_blockstore() {
let pubkey = Pubkey::new_rand();
let mut genesis_config = create_genesis_config_with_leader(
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
&pubkey,
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
)
.genesis_config;
genesis_config.epoch_schedule.warmup = false;
@ -525,7 +525,7 @@ mod tests {
&mint_keypair,
&vote_account,
&node_pubkey,
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
);
// Have to wait until the epoch at after the epoch stakes generated at genesis

View File

@ -55,14 +55,15 @@ fn sort_stakes(stakes: &mut Vec<(Pubkey, u64)>) {
mod tests {
use super::*;
use solana_runtime::genesis_utils::{
create_genesis_config_with_leader, BOOTSTRAP_LEADER_LAMPORTS,
create_genesis_config_with_leader, BOOTSTRAP_VALIDATOR_LAMPORTS,
};
#[test]
fn test_leader_schedule_via_bank() {
let pubkey = Pubkey::new_rand();
let genesis_config =
create_genesis_config_with_leader(0, &pubkey, BOOTSTRAP_LEADER_LAMPORTS).genesis_config;
create_genesis_config_with_leader(0, &pubkey, BOOTSTRAP_VALIDATOR_LAMPORTS)
.genesis_config;
let bank = Bank::new(&genesis_config);
let pubkeys_and_stakes: Vec<_> = staking_utils::staked_nodes(&bank).into_iter().collect();
@ -83,9 +84,9 @@ mod tests {
fn test_leader_scheduler1_basic() {
let pubkey = Pubkey::new_rand();
let genesis_config = create_genesis_config_with_leader(
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
&pubkey,
BOOTSTRAP_LEADER_LAMPORTS,
BOOTSTRAP_VALIDATOR_LAMPORTS,
)
.genesis_config;
let bank = Bank::new(&genesis_config);

View File

@ -101,7 +101,7 @@ where
pub(crate) mod tests {
use super::*;
use crate::genesis_utils::{
create_genesis_config, GenesisConfigInfo, BOOTSTRAP_LEADER_LAMPORTS,
create_genesis_config, GenesisConfigInfo, BOOTSTRAP_VALIDATOR_LAMPORTS,
};
use solana_sdk::{
clock::Clock,
@ -183,10 +183,10 @@ pub(crate) mod tests {
#[test]
fn test_epoch_stakes_and_lockouts() {
solana_logger::setup();
let stake = BOOTSTRAP_LEADER_LAMPORTS * 100;
let stake = BOOTSTRAP_VALIDATOR_LAMPORTS * 100;
let leader_stake = Stake {
delegation: Delegation {
stake: BOOTSTRAP_LEADER_LAMPORTS,
stake: BOOTSTRAP_VALIDATOR_LAMPORTS,
activation_epoch: std::u64::MAX, // mark as bootstrap
..Delegation::default()
},
@ -205,7 +205,7 @@ pub(crate) mod tests {
let vote_account = Keypair::new();
// Give the validator some stake but don't setup a staking account
// Validator has no lamports staked, so they get filtered out. Only the bootstrap leader
// Validator has no lamports staked, so they get filtered out. Only the bootstrap validator
// created by the genesis config will get included
bank.transfer(1, &mint_keypair, &validator.pubkey())
.unwrap();

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Start the bootstrap leader node
# Start the bootstrap validator node
#
set -e
@ -61,11 +61,11 @@ while [[ -n $1 ]]; do
done
# These keypairs are created by ./setup.sh and included in the genesis config
identity_keypair=$SOLANA_CONFIG_DIR/bootstrap-leader/identity-keypair.json
vote_keypair="$SOLANA_CONFIG_DIR"/bootstrap-leader/vote-keypair.json
storage_keypair=$SOLANA_CONFIG_DIR/bootstrap-leader/storage-keypair.json
identity_keypair=$SOLANA_CONFIG_DIR/bootstrap-validator/identity-keypair.json
vote_keypair="$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json
storage_keypair=$SOLANA_CONFIG_DIR/bootstrap-validator/storage-keypair.json
ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-leader
ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-validator
[[ -d "$ledger_dir" ]] || {
echo "$ledger_dir does not exist"
echo
@ -74,7 +74,7 @@ ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-leader
}
args+=(
--accounts "$SOLANA_CONFIG_DIR"/bootstrap-leader/accounts
--accounts "$SOLANA_CONFIG_DIR"/bootstrap-validator/accounts
--enable-rpc-exit
--ledger "$ledger_dir"
--rpc-port 8899

View File

@ -6,8 +6,8 @@ source "$here"/common.sh
set -e
rm -rf "$SOLANA_CONFIG_DIR"/bootstrap-leader
mkdir -p "$SOLANA_CONFIG_DIR"/bootstrap-leader
rm -rf "$SOLANA_CONFIG_DIR"/bootstrap-validator
mkdir -p "$SOLANA_CONFIG_DIR"/bootstrap-validator
# Create genesis ledger
if [[ -r $FAUCET_KEYPAIR ]]; then
@ -16,22 +16,22 @@ else
$solana_keygen new --no-passphrase -fso "$SOLANA_CONFIG_DIR"/faucet-keypair.json
fi
if [[ -f $BOOTSTRAP_LEADER_IDENTITY_KEYPAIR ]]; then
cp -f "$BOOTSTRAP_LEADER_IDENTITY_KEYPAIR" "$SOLANA_CONFIG_DIR"/bootstrap-leader/identity-keypair.json
if [[ -f $BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR ]]; then
cp -f "$BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR" "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json
else
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-leader/identity-keypair.json
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json
fi
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-leader/vote-keypair.json
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-leader/stake-keypair.json
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-leader/storage-keypair.json
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/storage-keypair.json
args=("$@")
default_arg --bootstrap-leader-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-leader/identity-keypair.json
default_arg --bootstrap-vote-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-leader/vote-keypair.json
default_arg --bootstrap-stake-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-leader/stake-keypair.json
default_arg --bootstrap-storage-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-leader/storage-keypair.json
default_arg --ledger "$SOLANA_CONFIG_DIR"/bootstrap-leader
default_arg --bootstrap-validator-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json
default_arg --bootstrap-vote-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json
default_arg --bootstrap-stake-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json
default_arg --bootstrap-storage-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/storage-keypair.json
default_arg --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator
default_arg --faucet-pubkey "$SOLANA_CONFIG_DIR"/faucet-keypair.json
default_arg --faucet-lamports 500000000000000000
default_arg --hashes-per-tick auto

View File

@ -152,7 +152,7 @@ Manage testnet instances
Only supported on GCE.
--dedicated - Use dedicated instances for additional validators
(by default preemptible instances are used to reduce
cost). Note that the bootstrap leader, archiver,
cost). Note that the bootstrap validator, archiver,
blockstreamer and client nodes are always dedicated.
--self-destruct-hours [number]
- Specify lifetime of the allocated instances in hours. 0 to
@ -514,12 +514,12 @@ EOF
}
if $externalNodes; then
echo "Bootstrap leader is already configured"
echo "Bootstrap validator is already configured"
else
echo "Looking for bootstrap leader instance..."
cloud_FindInstance "$prefix-bootstrap-leader"
echo "Looking for bootstrap validator instance..."
cloud_FindInstance "$prefix-bootstrap-validator"
[[ ${#instances[@]} -eq 1 ]] || {
echo "Unable to find bootstrap leader"
echo "Unable to find bootstrap validator"
exit 1
}
@ -649,7 +649,7 @@ create)
printNetworkInfo() {
cat <<EOF
==[ Network composition ]===============================================================
Bootstrap leader = $bootstrapLeaderMachineType (GPU=$enableGpu)
Bootstrap validator = $bootstrapLeaderMachineType (GPU=$enableGpu)
Additional validators = $additionalValidatorCount x $validatorMachineType
Client(s) = $clientNodeCount x $clientMachineType
Archivers(s) = $archiverNodeCount x $archiverMachineType
@ -812,9 +812,9 @@ EOF
done
if $externalNodes; then
echo "Bootstrap leader is already configured"
echo "Bootstrap validator is already configured"
else
cloud_CreateInstances "$prefix" "$prefix-bootstrap-leader" 1 \
cloud_CreateInstances "$prefix" "$prefix-bootstrap-validator" 1 \
"$enableGpu" "$bootstrapLeaderMachineType" "${zones[0]}" "$validatorBootDiskSizeInGb" \
"$startupScript" "$bootstrapLeaderAddress" "$bootDiskType" "$validatorAdditionalDiskSizeInGb" \
"never preemptible" "$sshPrivateKey"
@ -890,7 +890,7 @@ info)
echo "-------------------+-----------------+-----------------+--------------"
fi
nodeType=bootstrap-leader
nodeType=bootstrap-validator
if [[ ${#validatorIpList[@]} -gt 0 ]]; then
for i in $(seq 0 $(( ${#validatorIpList[@]} - 1)) ); do
ipAddress=${validatorIpList[$i]}

View File

@ -472,7 +472,7 @@ startBootstrapLeader() {
declare ipAddress=$1
declare nodeIndex="$2"
declare logFile="$3"
echo "--- Starting bootstrap leader: $ipAddress"
echo "--- Starting bootstrap validator: $ipAddress"
echo "start log: $logFile"
# Deploy local binaries to bootstrap validator. Other validators and clients later fetch the
@ -501,7 +501,7 @@ startBootstrapLeader() {
ssh "${sshOptions[@]}" -n "$ipAddress" \
"./solana/net/remote/remote-node.sh \
$deployMethod \
bootstrap-leader \
bootstrap-validator \
$entrypointIp \
$((${#validatorIpList[@]} + ${#blockstreamerIpList[@]} + ${#archiverIpList[@]})) \
\"$RUST_LOG\" \
@ -781,7 +781,7 @@ deploy() {
if $bootstrapLeader; then
SECONDS=0
declare bootstrapNodeDeployTime=
startBootstrapLeader "$nodeAddress" $nodeIndex "$netLogDir/bootstrap-leader-$ipAddress.log"
startBootstrapLeader "$nodeAddress" $nodeIndex "$netLogDir/bootstrap-validator-$ipAddress.log"
bootstrapNodeDeployTime=$SECONDS
$metricsWriteDatapoint "testnet-deploy net-bootnode-leader-started=1"
@ -819,7 +819,7 @@ deploy() {
annotateBlockexplorerUrl
sanity skipBlockstreamerSanity # skip sanity on blockstreamer node, it may not
# have caught up to the bootstrap leader yet
# have caught up to the bootstrap validator yet
echo "--- Sleeping $clientDelayStart seconds after validators are started before starting clients"
sleep "$clientDelayStart"
@ -861,7 +861,7 @@ deploy() {
echo
echo "+++ Deployment Successful"
echo "Bootstrap leader deployment took $bootstrapNodeDeployTime seconds"
echo "Bootstrap validator deployment took $bootstrapNodeDeployTime seconds"
echo "Additional validator deployment (${#validatorIpList[@]} validators, ${#blockstreamerIpList[@]} blockstreamer nodes, ${#archiverIpList[@]} archivers) took $additionalNodeDeployTime seconds"
echo "Client deployment (${#clientIpList[@]} instances) took $clientDeployTime seconds"
echo "Network start logs in $netLogDir"

View File

@ -144,7 +144,7 @@ cat >> ~/solana/on-reboot <<EOF
EOF
case $nodeType in
bootstrap-leader)
bootstrap-validator)
set -x
if [[ $skipSetup != true ]]; then
clear_config_dir "$SOLANA_CONFIG_DIR"
@ -213,10 +213,10 @@ EOF
fi
if [[ -n $internalNodesStakeLamports ]]; then
args+=(--bootstrap-leader-stake-lamports "$internalNodesStakeLamports")
args+=(--bootstrap-validator-stake-lamports "$internalNodesStakeLamports")
fi
if [[ -n $internalNodesLamports ]]; then
args+=(--bootstrap-leader-lamports "$internalNodesLamports")
args+=(--bootstrap-validator-lamports "$internalNodesLamports")
fi
# shellcheck disable=SC2206 # Do not want to quote $genesisOptions
args+=($genesisOptions)
@ -224,8 +224,8 @@ EOF
if [[ -f net/keypairs/mint.json ]]; then
export FAUCET_KEYPAIR=net/keypairs/mint.json
fi
if [[ -f net/keypairs/bootstrap-leader-identity.json ]]; then
export BOOTSTRAP_LEADER_IDENTITY_KEYPAIR=net/keypairs/bootstrap-leader-identity.json
if [[ -f net/keypairs/bootstrap-validator-identity.json ]]; then
export BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR=net/keypairs/bootstrap-validator-identity.json
fi
multinode-demo/setup.sh "${args[@]}"
fi
@ -244,7 +244,7 @@ EOF
args+=($extraNodeArgs)
cat >> ~/solana/on-reboot <<EOF
nohup ./multinode-demo/bootstrap-leader.sh ${args[@]} > validator.log.\$now 2>&1 &
nohup ./multinode-demo/bootstrap-validator.sh ${args[@]} > validator.log.\$now 2>&1 &
pid=\$!
oom_score_adj "\$pid" 1000
disown
@ -254,7 +254,7 @@ EOF
if [[ $skipSetup != true ]]; then
solana --url http://"$entrypointIp":8899 \
--keypair ~/solana/config/bootstrap-leader/identity-keypair.json \
--keypair ~/solana/config/bootstrap-validator/identity-keypair.json \
validator-info publish "$(hostname)" -n team/solana --force || true
fi
;;
@ -373,7 +373,7 @@ EOF
waitForNodeToInit
if [[ $skipSetup != true && $nodeType != blockstreamer ]]; then
# Wait for the validator to catch up to the bootstrap leader before
# Wait for the validator to catch up to the bootstrap validator before
# delegating stake to it
solana --url http://"$entrypointIp":8899 catchup config/validator-identity.json

2
run.sh
View File

@ -84,7 +84,7 @@ else
--hashes-per-tick sleep \
--faucet-pubkey "$dataDir"/faucet-keypair.json \
--faucet-lamports 500000000000000000 \
--bootstrap-leader-pubkey "$dataDir"/leader-keypair.json \
--bootstrap-validator-pubkey "$dataDir"/leader-keypair.json \
--bootstrap-vote-pubkey "$dataDir"/leader-vote-account-keypair.json \
--bootstrap-stake-pubkey "$dataDir"/leader-stake-account-keypair.json \
--bootstrap-storage-pubkey "$dataDir"/leader-storage-account-keypair.json \

View File

@ -741,7 +741,7 @@ impl Bank {
}
fn process_genesis_config(&mut self, genesis_config: &GenesisConfig) {
// Bootstrap leader collects fees until `new_from_parent` is called.
// Bootstrap validator collects fees until `new_from_parent` is called.
self.fee_calculator = genesis_config.fee_calculator.clone();
self.update_fees();
@ -1957,7 +1957,7 @@ mod tests {
accounts_db::get_temp_accounts_paths,
accounts_db::tests::copy_append_vecs,
genesis_utils::{
create_genesis_config_with_leader, GenesisConfigInfo, BOOTSTRAP_LEADER_LAMPORTS,
create_genesis_config_with_leader, GenesisConfigInfo, BOOTSTRAP_VALIDATOR_LAMPORTS,
},
status_cache::MAX_CACHE_ENTRIES,
};
@ -2019,7 +2019,7 @@ mod tests {
#[test]
fn test_bank_new() {
let dummy_leader_pubkey = Pubkey::new_rand();
let dummy_leader_lamports = BOOTSTRAP_LEADER_LAMPORTS;
let dummy_leader_lamports = BOOTSTRAP_VALIDATOR_LAMPORTS;
let mint_lamports = 10_000;
let GenesisConfigInfo {
mut genesis_config,
@ -2443,12 +2443,12 @@ mod tests {
#[test]
fn test_rent_distribution() {
let bootstrap_leader_pubkey = Pubkey::new_rand();
let bootstrap_leader_stake_lamports = 30;
let bootstrap_validator_pubkey = Pubkey::new_rand();
let bootstrap_validator_stake_lamports = 30;
let mut genesis_config = create_genesis_config_with_leader(
10,
&bootstrap_leader_pubkey,
bootstrap_leader_stake_lamports,
&bootstrap_validator_pubkey,
bootstrap_validator_stake_lamports,
)
.genesis_config;
@ -2584,7 +2584,7 @@ mod tests {
let payee_account = Account::new(70, 1, &system_program::id());
bank.store_account(&payee.pubkey(), &payee_account);
let bootstrap_leader_initial_balance = bank.get_balance(&bootstrap_leader_pubkey);
let bootstrap_validator_initial_balance = bank.get_balance(&bootstrap_validator_pubkey);
let tx = system_transaction::transfer(&payer, &payee.pubkey(), 180, genesis_config.hash());
@ -2614,11 +2614,12 @@ mod tests {
total_rent_deducted * u64::from(bank.rent_collector.rent.burn_percent) / 100;
let rent_to_be_distributed = total_rent_deducted - burned_portion;
let bootstrap_leader_portion =
((bootstrap_leader_stake_lamports * rent_to_be_distributed) as f64 / 100.0) as u64 + 1; // Leftover lamport
let bootstrap_validator_portion =
((bootstrap_validator_stake_lamports * rent_to_be_distributed) as f64 / 100.0) as u64
+ 1; // Leftover lamport
assert_eq!(
bank.get_balance(&bootstrap_leader_pubkey),
bootstrap_leader_portion + bootstrap_leader_initial_balance
bank.get_balance(&bootstrap_validator_pubkey),
bootstrap_validator_portion + bootstrap_validator_initial_balance
);
// Since, validator 1 and validator 2 has equal smallest stake, it comes down to comparison
@ -4233,7 +4234,7 @@ mod tests {
let bank = Arc::new(Bank::new(&genesis_config));
let vote_accounts = bank.vote_accounts();
assert_eq!(vote_accounts.len(), 1); // bootstrap leader has
assert_eq!(vote_accounts.len(), 1); // bootstrap validator has
// to have a vote account
let vote_keypair = Keypair::new();
@ -4280,7 +4281,7 @@ mod tests {
let bank = Arc::new(Bank::new(&genesis_config));
let stake_delegations = bank.stake_delegations();
assert_eq!(stake_delegations.len(), 1); // bootstrap leader has
assert_eq!(stake_delegations.len(), 1); // bootstrap validator has
// to have a stake delegation
let vote_keypair = Keypair::new();

View File

@ -10,8 +10,8 @@ use solana_sdk::{
use solana_stake_program::stake_state;
use solana_vote_program::vote_state;
// The default stake placed with the bootstrap leader
pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 42;
// The default stake placed with the bootstrap validator
pub const BOOTSTRAP_VALIDATOR_LAMPORTS: u64 = 42;
pub struct GenesisConfigInfo {
pub genesis_config: GenesisConfig,
@ -25,28 +25,28 @@ pub fn create_genesis_config(mint_lamports: u64) -> GenesisConfigInfo {
pub fn create_genesis_config_with_leader(
mint_lamports: u64,
bootstrap_leader_pubkey: &Pubkey,
bootstrap_leader_stake_lamports: u64,
bootstrap_validator_pubkey: &Pubkey,
bootstrap_validator_stake_lamports: u64,
) -> GenesisConfigInfo {
let mint_keypair = Keypair::new();
let bootstrap_leader_voting_keypair = Keypair::new();
let bootstrap_leader_staking_keypair = Keypair::new();
let bootstrap_validator_voting_keypair = Keypair::new();
let bootstrap_validator_staking_keypair = Keypair::new();
let bootstrap_leader_vote_account = vote_state::create_account(
&bootstrap_leader_voting_keypair.pubkey(),
&bootstrap_leader_pubkey,
let bootstrap_validator_vote_account = vote_state::create_account(
&bootstrap_validator_voting_keypair.pubkey(),
&bootstrap_validator_pubkey,
0,
bootstrap_leader_stake_lamports,
bootstrap_validator_stake_lamports,
);
let rent = Rent::free();
let bootstrap_leader_stake_account = stake_state::create_account(
&bootstrap_leader_staking_keypair.pubkey(),
&bootstrap_leader_voting_keypair.pubkey(),
&bootstrap_leader_vote_account,
let bootstrap_validator_stake_account = stake_state::create_account(
&bootstrap_validator_staking_keypair.pubkey(),
&bootstrap_validator_voting_keypair.pubkey(),
&bootstrap_validator_vote_account,
&rent,
bootstrap_leader_stake_lamports,
bootstrap_validator_stake_lamports,
);
let accounts = [
@ -55,16 +55,16 @@ pub fn create_genesis_config_with_leader(
Account::new(mint_lamports, 0, &system_program::id()),
),
(
*bootstrap_leader_pubkey,
Account::new(BOOTSTRAP_LEADER_LAMPORTS, 0, &system_program::id()),
*bootstrap_validator_pubkey,
Account::new(BOOTSTRAP_VALIDATOR_LAMPORTS, 0, &system_program::id()),
),
(
bootstrap_leader_voting_keypair.pubkey(),
bootstrap_leader_vote_account,
bootstrap_validator_voting_keypair.pubkey(),
bootstrap_validator_vote_account,
),
(
bootstrap_leader_staking_keypair.pubkey(),
bootstrap_leader_stake_account,
bootstrap_validator_staking_keypair.pubkey(),
bootstrap_validator_stake_account,
),
]
.iter()
@ -94,6 +94,6 @@ pub fn create_genesis_config_with_leader(
GenesisConfigInfo {
genesis_config,
mint_keypair,
voting_keypair: bootstrap_leader_voting_keypair,
voting_keypair: bootstrap_validator_voting_keypair,
}
}

View File

@ -31,7 +31,7 @@ pub enum OperatingMode {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GenesisConfig {
/// when the network (bootstrap leader) was started relative to the UNIX Epoch
/// when the network (bootstrap validator) was started relative to the UNIX Epoch
pub creation_time: UnixTimestamp,
/// initial accounts
pub accounts: BTreeMap<Pubkey, Account>,

View File

@ -53,20 +53,20 @@ function analyze_packet_loss {
)
}
function wait_for_bootstrap_leader_stake_drop {
function wait_for_bootstrap_validator_stake_drop {
max_stake="$1"
source net/common.sh
loadConfigFile
while true; do
bootstrap_leader_validator_info="$(ssh "${sshOptions[@]}" "${validatorIpList[0]}" '$HOME/.cargo/bin/solana validators | grep "$($HOME/.cargo/bin/solana-keygen pubkey ~/solana/config/bootstrap-leader/identity-keypair.json)"')"
bootstrap_leader_stake_percentage="$(echo "$bootstrap_leader_validator_info" | awk '{gsub(/[\(,\),\%]/,""); print $9}')"
bootstrap_validator_validator_info="$(ssh "${sshOptions[@]}" "${validatorIpList[0]}" '$HOME/.cargo/bin/solana validators | grep "$($HOME/.cargo/bin/solana-keygen pubkey ~/solana/config/bootstrap-validator/identity-keypair.json)"')"
bootstrap_validator_stake_percentage="$(echo "$bootstrap_validator_validator_info" | awk '{gsub(/[\(,\),\%]/,""); print $9}')"
if [[ $(echo "$bootstrap_leader_stake_percentage < $max_stake" | bc) -ne 0 ]]; then
echo "Bootstrap leader stake has fallen below $max_stake to $bootstrap_leader_stake_percentage"
if [[ $(echo "$bootstrap_validator_stake_percentage < $max_stake" | bc) -ne 0 ]]; then
echo "Bootstrap validator stake has fallen below $max_stake to $bootstrap_validator_stake_percentage"
break
fi
echo "Max bootstrap leader stake: $max_stake. Current stake: $bootstrap_leader_stake_percentage. Sleeping 30s for stake to distribute."
echo "Max bootstrap validator stake: $max_stake. Current stake: $bootstrap_validator_stake_percentage. Sleeping 30s for stake to distribute."
sleep 30
done
}
@ -197,8 +197,8 @@ function launchTestnet() {
--gpu-mode $startGpuMode --client-delay-start $CLIENT_DELAY_START
fi
execution_step "Waiting for bootstrap leader's stake percentage to fall below $BOOTSTRAP_LEADER_MAX_STAKE_THRESHOLD %"
wait_for_bootstrap_leader_stake_drop "$BOOTSTRAP_LEADER_MAX_STAKE_THRESHOLD"
execution_step "Waiting for bootstrap validator's stake percentage to fall below $BOOTSTRAP_VALIDATOR_MAX_STAKE_THRESHOLD %"
wait_for_bootstrap_validator_stake_drop "$BOOTSTRAP_VALIDATOR_MAX_STAKE_THRESHOLD"
execution_step "Wait ${TEST_DURATION_SECONDS} seconds to complete test"
sleep "$TEST_DURATION_SECONDS"
@ -257,7 +257,7 @@ cd "$(dirname "$0")/.."
[[ -n $TESTNET_TAG ]] || TESTNET_TAG=testnet-automation
[[ -n $INFLUX_HOST ]] || INFLUX_HOST=https://metrics.solana.com:8086
[[ -n $BOOTSTRAP_LEADER_MAX_STAKE_THRESHOLD ]] || BOOTSTRAP_LEADER_MAX_STAKE_THRESHOLD=66
[[ -n $BOOTSTRAP_VALIDATOR_MAX_STAKE_THRESHOLD ]] || BOOTSTRAP_VALIDATOR_MAX_STAKE_THRESHOLD=66
if [[ -z $TEST_DURATION_SECONDS ]] ; then
echo TEST_DURATION_SECONDS not defined