Rework validator vote account defaults to half voting fees

This commit is contained in:
Michael Vines 2020-03-13 11:41:18 -07:00
parent 5c2cf04e10
commit 29fb79382c
20 changed files with 140 additions and 134 deletions

View File

@ -28,7 +28,7 @@ fn main() {
.arg( .arg(
Arg::with_name("identity_keypair") Arg::with_name("identity_keypair")
.short("i") .short("i")
.long("identity-keypair") .long("identity")
.value_name("PATH") .value_name("PATH")
.takes_value(true) .takes_value(true)
.validator(is_keypair_or_ask_keyword) .validator(is_keypair_or_ask_keyword)

View File

@ -178,7 +178,7 @@ startNodes() {
( (
set -x set -x
$solana_cli --keypair config/bootstrap-validator/identity-keypair.json \ $solana_cli --keypair config/bootstrap-validator/identity.json \
--url http://127.0.0.1:8899 genesis-hash --url http://127.0.0.1:8899 genesis-hash
) | tee genesis-hash.log ) | tee genesis-hash.log
maybeExpectedGenesisHash="--expected-genesis-hash $(tail -n1 genesis-hash.log)" maybeExpectedGenesisHash="--expected-genesis-hash $(tail -n1 genesis-hash.log)"

View File

@ -684,7 +684,7 @@ pub fn parse_command(
}, },
// Vote Commands // Vote Commands
("create-vote-account", Some(matches)) => { ("create-vote-account", Some(matches)) => {
parse_vote_create_account(matches, default_signer_path, wallet_manager) parse_create_vote_account(matches, default_signer_path, wallet_manager)
} }
("vote-update-validator", Some(matches)) => { ("vote-update-validator", Some(matches)) => {
parse_vote_update_validator(matches, default_signer_path, wallet_manager) parse_vote_update_validator(matches, default_signer_path, wallet_manager)

View File

@ -62,7 +62,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY") .value_name("PUBKEY")
.takes_value(true) .takes_value(true)
.validator(is_pubkey_or_keypair) .validator(is_pubkey_or_keypair)
.help("Public key of the authorized voter [default: vote account]"), .help("Public key of the authorized voter [default: validator identity pubkey]"),
) )
.arg( .arg(
Arg::with_name("authorized_withdrawer") Arg::with_name("authorized_withdrawer")
@ -70,7 +70,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY") .value_name("PUBKEY")
.takes_value(true) .takes_value(true)
.validator(is_pubkey_or_keypair) .validator(is_pubkey_or_keypair)
.help("Public key of the authorized withdrawer [default: cli config pubkey]"), .help("Public key of the authorized withdrawer [default: validator identity pubkey]"),
) )
.arg( .arg(
Arg::with_name("seed") Arg::with_name("seed")
@ -225,7 +225,7 @@ impl VoteSubCommands for App<'_, '_> {
} }
} }
pub fn parse_vote_create_account( pub fn parse_create_vote_account(
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
default_signer_path: &str, default_signer_path: &str,
wallet_manager: Option<&Arc<RemoteWalletManager>>, wallet_manager: Option<&Arc<RemoteWalletManager>>,
@ -404,8 +404,8 @@ pub fn process_create_vote_account(
let vote_init = VoteInit { let vote_init = VoteInit {
node_pubkey: *identity_pubkey, node_pubkey: *identity_pubkey,
authorized_voter: authorized_voter.unwrap_or(vote_account_pubkey), authorized_voter: authorized_voter.unwrap_or(*identity_pubkey),
authorized_withdrawer: authorized_withdrawer.unwrap_or(vote_account_pubkey), authorized_withdrawer: authorized_withdrawer.unwrap_or(*identity_pubkey),
commission, commission,
}; };

View File

@ -144,7 +144,7 @@ impl Validator {
keypair: &Arc<Keypair>, keypair: &Arc<Keypair>,
ledger_path: &Path, ledger_path: &Path,
vote_account: &Pubkey, vote_account: &Pubkey,
voting_keypair: &Arc<Keypair>, authorized_voter: &Arc<Keypair>,
storage_keypair: &Arc<Keypair>, storage_keypair: &Arc<Keypair>,
entrypoint_info_option: Option<&ContactInfo>, entrypoint_info_option: Option<&ContactInfo>,
poh_verify: bool, poh_verify: bool,
@ -153,8 +153,9 @@ impl Validator {
let id = keypair.pubkey(); let id = keypair.pubkey();
assert_eq!(id, node.info.id); assert_eq!(id, node.info.id);
warn!("identity pubkey: {:?}", id); warn!("identity: {}", id);
warn!("vote pubkey: {:?}", vote_account); warn!("vote account: {}", vote_account);
warn!("authorized voter: {}", authorized_voter.pubkey());
report_target_features(); report_target_features();
info!("entrypoint: {:?}", entrypoint_info_option); info!("entrypoint: {:?}", entrypoint_info_option);
@ -366,12 +367,6 @@ impl Validator {
wait_for_supermajority(config, &bank, &cluster_info); wait_for_supermajority(config, &bank, &cluster_info);
let voting_keypair = if config.voting_disabled {
None
} else {
Some(voting_keypair.clone())
};
let poh_service = PohService::new(poh_recorder.clone(), &poh_config, &exit); let poh_service = PohService::new(poh_recorder.clone(), &poh_config, &exit);
assert_eq!( assert_eq!(
blockstore.new_shreds_signals.len(), blockstore.new_shreds_signals.len(),
@ -383,7 +378,11 @@ impl Validator {
let tvu = Tvu::new( let tvu = Tvu::new(
vote_account, vote_account,
voting_keypair, if config.voting_disabled {
None
} else {
Some(authorized_voter.clone())
},
storage_keypair, storage_keypair,
&bank_forks, &bank_forks,
&cluster_info, &cluster_info,

View File

@ -233,25 +233,25 @@ done < public_keys.txt
In order to run a validator, you will need to specify an "identity keypair" In order to run a validator, you will need to specify an "identity keypair"
which will be used to fund all of the vote transactions signed by your validator. which will be used to fund all of the vote transactions signed by your validator.
Rather than specifying a path with `--identity-keypair <PATH>` you can pass Rather than specifying a path with `--identity <PATH>` you can pass
`ASK` to securely input the funding keypair. `ASK` to securely input the funding keypair.
```bash ```bash
solana-validator --identity-keypair ASK --ledger ... solana-validator --identity ASK --ledger ...
[identity-keypair] seed phrase: 🔒 [identity] seed phrase: 🔒
[identity-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue: [identity] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
``` ```
You can use this input method for your voting keypair as well: You can use this input method for your voting keypair as well:
```bash ```bash
solana-validator --identity-keypair ASK --voting-keypair ASK --ledger ... solana-validator --identity ASK --authorized-voter ASK --ledger ...
[identity-keypair] seed phrase: 🔒 [identity] seed phrase: 🔒
[identity-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue: [identity] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
[voting-keypair] seed phrase: 🔒 [authorized-voter] seed phrase: 🔒
[voting-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue: [authorized-voter] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
``` ```
Refer to the following page for a comprehensive guide on running a validator: Refer to the following page for a comprehensive guide on running a validator:

View File

@ -137,16 +137,16 @@ Read more about the [difference between SOL and lamports here](../introduction.m
If you havent already done so, create a vote-account keypair and create the If you havent already done so, create a vote-account keypair and create the
vote account on the network. If you have completed this step, you should see the vote account on the network. If you have completed this step, you should see the
“validator-vote-keypair.json” in your Solana runtime directory: “vote-account-keypair.json” in your Solana runtime directory:
```bash ```bash
solana-keygen new -o ~/validator-vote-keypair.json solana-keygen new -o ~/vote-account-keypair.json
``` ```
Create your vote account on the blockchain: Create your vote account on the blockchain:
```bash ```bash
solana create-vote-account ~/validator-vote-keypair.json ~/validator-keypair.json solana create-vote-account ~/vote-account-keypair.json ~/validator-keypair.json
``` ```
## Connect Your Validator ## Connect Your Validator
@ -154,7 +154,7 @@ solana create-vote-account ~/validator-vote-keypair.json ~/validator-keypair.jso
Connect to a testnet cluster by running: Connect to a testnet cluster by running:
```bash ```bash
solana-validator --identity-keypair ~/validator-keypair.json --voting-keypair ~/validator-vote-keypair.json \ solana-validator --identity ~/validator-keypair.json --vote-account ~/vote-account-keypair.json \
--ledger ~/validator-ledger --rpc-port 8899 --entrypoint devnet.solana.com:8001 \ --ledger ~/validator-ledger --rpc-port 8899 --entrypoint devnet.solana.com:8001 \
--limit-ledger-size --limit-ledger-size
``` ```

View File

@ -4,16 +4,16 @@
Once youve confirmed the network is running, its time to connect your validator to the network. Once youve confirmed the network is running, its time to connect your validator to the network.
If you havent already done so, create a vote-account keypair and create the vote account on the network. If you have completed this step, you should see the “validator-vote-keypair.json” in your Solana runtime directory: If you havent already done so, create a vote-account keypair and create the vote account on the network. If you have completed this step, you should see the “vote-account-keypair.json” in your Solana runtime directory:
```bash ```bash
solana-keygen new -o ~/validator-vote-keypair.json solana-keygen new -o ~/vote-account-keypair.json
``` ```
Create your vote account on the blockchain: Create your vote account on the blockchain:
```bash ```bash
solana create-vote-account ~/validator-vote-keypair.json ~/validator-keypair.json solana create-vote-account ~/vote-account-keypair.json ~/validator-keypair.json
``` ```
## Connect Your Validator ## Connect Your Validator
@ -25,7 +25,7 @@ export SOLANA_METRICS_CONFIG="host=https://metrics.solana.com:8086,db=tds,u=tds_
``` ```
```bash ```bash
solana-validator --identity-keypair ~/validator-keypair.json --voting-keypair ~/validator-vote-keypair.json \ solana-validator --identity ~/validator-keypair.json --vote-account ~/vote-account-keypair.json \
--ledger ~/validator-ledger --rpc-port 8899 --entrypoint tds.solana.com:8001 \ --ledger ~/validator-ledger --rpc-port 8899 --entrypoint tds.solana.com:8001 \
--limit-ledger-size --limit-ledger-size
``` ```

View File

@ -467,8 +467,9 @@ fn main() -> Result<(), Box<dyn error::Error>> {
Account::new(bootstrap_validator_lamports, 0, &system_program::id()), Account::new(bootstrap_validator_lamports, 0, &system_program::id()),
); );
let vote_account = vote_state::create_account( let vote_account = vote_state::create_account_with_authorized(
&vote_pubkey, &identity_pubkey,
&identity_pubkey,
&identity_pubkey, &identity_pubkey,
100, 100,
VoteState::get_rent_exempt_reserve(&rent).max(1), VoteState::get_rent_exempt_reserve(&rent).max(1),

View File

@ -18,10 +18,10 @@ while [[ -n $1 ]]; do
entrypoint=$2 entrypoint=$2
args+=("$1" "$2") args+=("$1" "$2")
shift 2 shift 2
elif [[ $1 = --identity-keypair ]]; then elif [[ $1 = --identity ]]; then
identity_keypair=$2 identity=$2
[[ -r $identity_keypair ]] || { [[ -r $identity ]] || {
echo "$identity_keypair does not exist" echo "$identity does not exist"
exit 1 exit 1
} }
args+=("$1" "$2") args+=("$1" "$2")
@ -52,29 +52,29 @@ while [[ -n $1 ]]; do
fi fi
done done
: "${identity_keypair:="$SOLANA_ROOT"/farf/archiver-identity-keypair"$label".json}" : "${identity:="$SOLANA_ROOT"/farf/archiver-identity"$label".json}"
: "${storage_keypair:="$SOLANA_ROOT"/farf/archiver-storage-keypair"$label".json}" : "${storage_keypair:="$SOLANA_ROOT"/farf/archiver-storage-keypair"$label".json}"
ledger="$SOLANA_ROOT"/farf/archiver-ledger"$label" ledger="$SOLANA_ROOT"/farf/archiver-ledger"$label"
rpc_url=$($solana_gossip rpc-url --entrypoint "$entrypoint") rpc_url=$($solana_gossip rpc-url --entrypoint "$entrypoint")
if [[ ! -r $identity_keypair ]]; then if [[ ! -r $identity ]]; then
$solana_keygen new --no-passphrase -so "$identity_keypair" $solana_keygen new --no-passphrase -so "$identity"
# See https://github.com/solana-labs/solana/issues/4344 # See https://github.com/solana-labs/solana/issues/4344
$solana_cli --keypair "$identity_keypair" --url "$rpc_url" airdrop 1 $solana_cli --keypair "$identity" --url "$rpc_url" airdrop 1
fi fi
identity_pubkey=$($solana_keygen pubkey "$identity_keypair") identity_pubkey=$($solana_keygen pubkey "$identity")
if [[ ! -r $storage_keypair ]]; then if [[ ! -r $storage_keypair ]]; then
$solana_keygen new --no-passphrase -so "$storage_keypair" $solana_keygen new --no-passphrase -so "$storage_keypair"
$solana_cli --keypair "$identity_keypair" --url "$rpc_url" \ $solana_cli --keypair "$identity" --url "$rpc_url" \
create-archiver-storage-account "$identity_pubkey" "$storage_keypair" create-archiver-storage-account "$identity_pubkey" "$storage_keypair"
fi fi
default_arg --entrypoint "$entrypoint" default_arg --entrypoint "$entrypoint"
default_arg --identity-keypair "$identity_keypair" default_arg --identity "$identity"
default_arg --storage-keypair "$storage_keypair" default_arg --storage-keypair "$storage_keypair"
default_arg --ledger "$ledger" default_arg --ledger "$ledger"

View File

@ -64,8 +64,8 @@ while [[ -n $1 ]]; do
done done
# These keypairs are created by ./setup.sh and included in the genesis config # These keypairs are created by ./setup.sh and included in the genesis config
identity_keypair=$SOLANA_CONFIG_DIR/bootstrap-validator/identity-keypair.json identity=$SOLANA_CONFIG_DIR/bootstrap-validator/identity.json
vote_keypair="$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json vote_account="$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-account.json
ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-validator ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-validator
[[ -d "$ledger_dir" ]] || { [[ -d "$ledger_dir" ]] || {
@ -81,8 +81,8 @@ args+=(
--ledger "$ledger_dir" --ledger "$ledger_dir"
--rpc-port 8899 --rpc-port 8899
--snapshot-interval-slots 100 --snapshot-interval-slots 100
--identity-keypair "$identity_keypair" --identity "$identity"
--voting-keypair "$vote_keypair" --vote-account "$vote_account"
--rpc-faucet-address 127.0.0.1:9900 --rpc-faucet-address 127.0.0.1:9900
) )
default_arg --gossip-port 8001 default_arg --gossip-port 8001

View File

@ -80,16 +80,16 @@ if [[ -n ${positional_args[0]} ]]; then
fi fi
config_dir="$SOLANA_CONFIG_DIR/validator$label" config_dir="$SOLANA_CONFIG_DIR/validator$label"
vote_keypair_path="$config_dir"/vote-keypair.json vote_account="$config_dir"/vote-account.json
stake_keypair_path="$config_dir"/stake-keypair.json stake_account="$config_dir"/stake-account.json
if [[ ! -f $vote_keypair_path ]]; then if [[ ! -f $vote_account ]]; then
echo "Error: $vote_keypair_path not found" echo "Error: $vote_account not found"
exit 1 exit 1
fi fi
if [[ -f $stake_keypair_path ]]; then if [[ -f $stake_account ]]; then
echo "Error: $stake_keypair_path already exists" echo "Error: $stake_account already exists"
exit 1 exit 1
fi fi
@ -97,13 +97,13 @@ if ((airdrops_enabled)); then
$solana_cli "${common_args[@]}" airdrop "$stake_sol" $solana_cli "${common_args[@]}" airdrop "$stake_sol"
fi fi
$solana_keygen new --no-passphrase -so "$stake_keypair_path" $solana_keygen new --no-passphrase -so "$stake_account"
set -x set -x
$solana_cli "${common_args[@]}" \ $solana_cli "${common_args[@]}" \
vote-account "$vote_keypair_path" vote-account "$vote_account"
$solana_cli "${common_args[@]}" \ $solana_cli "${common_args[@]}" \
create-stake-account "$stake_keypair_path" "$stake_sol" create-stake-account "$stake_account" "$stake_sol"
$solana_cli "${common_args[@]}" \ $solana_cli "${common_args[@]}" \
delegate-stake $maybe_force "$stake_keypair_path" "$vote_keypair_path" delegate-stake $maybe_force "$stake_account" "$vote_account"
$solana_cli "${common_args[@]}" stakes "$stake_keypair_path" $solana_cli "${common_args[@]}" stakes "$stake_account"

View File

@ -7,8 +7,8 @@ here=$(dirname "$0")
# shellcheck source=multinode-demo/common.sh # shellcheck source=multinode-demo/common.sh
source "$here"/common.sh source "$here"/common.sh
[[ -f "$SOLANA_CONFIG_DIR"/faucet-keypair.json ]] || { [[ -f "$SOLANA_CONFIG_DIR"/faucet.json ]] || {
echo "$SOLANA_CONFIG_DIR/faucet-keypair.json not found, create it by running:" echo "$SOLANA_CONFIG_DIR/faucet.json not found, create it by running:"
echo echo
echo " ${here}/setup.sh" echo " ${here}/setup.sh"
exit 1 exit 1
@ -16,4 +16,4 @@ source "$here"/common.sh
set -x set -x
# shellcheck disable=SC2086 # Don't want to double quote $solana_faucet # shellcheck disable=SC2086 # Don't want to double quote $solana_faucet
exec $solana_faucet --keypair "$SOLANA_CONFIG_DIR"/faucet-keypair.json "$@" exec $solana_faucet --keypair "$SOLANA_CONFIG_DIR"/faucet.json "$@"

View File

@ -11,29 +11,29 @@ mkdir -p "$SOLANA_CONFIG_DIR"/bootstrap-validator
# Create genesis ledger # Create genesis ledger
if [[ -r $FAUCET_KEYPAIR ]]; then if [[ -r $FAUCET_KEYPAIR ]]; then
cp -f "$FAUCET_KEYPAIR" "$SOLANA_CONFIG_DIR"/faucet-keypair.json cp -f "$FAUCET_KEYPAIR" "$SOLANA_CONFIG_DIR"/faucet.json
else else
$solana_keygen new --no-passphrase -fso "$SOLANA_CONFIG_DIR"/faucet-keypair.json $solana_keygen new --no-passphrase -fso "$SOLANA_CONFIG_DIR"/faucet.json
fi fi
if [[ -f $BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR ]]; then if [[ -f $BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR ]]; then
cp -f "$BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR" "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json cp -f "$BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR" "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity.json
else else
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json $solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity.json
fi fi
$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/vote-account.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/stake-account.json
args=( args=(
"$@" "$@"
--enable-warmup-epochs --enable-warmup-epochs
--bootstrap-validator "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json --bootstrap-validator "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity.json
"$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-account.json
"$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-account.json
) )
default_arg --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator default_arg --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator
default_arg --faucet-pubkey "$SOLANA_CONFIG_DIR"/faucet-keypair.json default_arg --faucet-pubkey "$SOLANA_CONFIG_DIR"/faucet.json
default_arg --faucet-lamports 500000000000000000 default_arg --faucet-lamports 500000000000000000
default_arg --hashes-per-tick auto default_arg --hashes-per-tick auto
default_arg --operating-mode development default_arg --operating-mode development

View File

@ -10,8 +10,8 @@ args=()
airdrops_enabled=1 airdrops_enabled=1
node_sol=500 # 500 SOL: number of SOL to airdrop the node for transaction fees and vote account rent exemption (ignored if airdrops_enabled=0) node_sol=500 # 500 SOL: number of SOL to airdrop the node for transaction fees and vote account rent exemption (ignored if airdrops_enabled=0)
label= label=
identity_keypair_path= identity=
voting_keypair_path= vote_account=
no_restart=0 no_restart=0
gossip_entrypoint= gossip_entrypoint=
ledger_dir= ledger_dir=
@ -69,19 +69,19 @@ while [[ -n $1 ]]; do
elif [[ $1 = --expected-shred-version ]]; then elif [[ $1 = --expected-shred-version ]]; then
args+=("$1" "$2") args+=("$1" "$2")
shift 2 shift 2
elif [[ $1 = --identity-keypair ]]; then elif [[ $1 = --identity ]]; then
identity_keypair_path=$2 identity=$2
args+=("$1" "$2") args+=("$1" "$2")
shift 2 shift 2
elif [[ $1 = --voting-keypair ]]; then elif [[ $1 = --authorized-voter ]]; then
voting_keypair_path=$2
args+=("$1" "$2") args+=("$1" "$2")
shift 2 shift 2
elif [[ $1 = --vote-account ]]; then elif [[ $1 = --vote-account ]]; then
vote_account=$2
args+=("$1" "$2") args+=("$1" "$2")
shift 2 shift 2
elif [[ $1 = --storage-keypair ]]; then elif [[ $1 = --storage-keypair ]]; then
storage_keypair_path=$2 storage_keypair=$2
args+=("$1" "$2") args+=("$1" "$2")
shift 2 shift 2
elif [[ $1 = --init-complete-file ]]; then elif [[ $1 = --init-complete-file ]]; then
@ -174,11 +174,11 @@ if [[ -n $REQUIRE_LEDGER_DIR ]]; then
fi fi
if [[ -n $REQUIRE_KEYPAIRS ]]; then if [[ -n $REQUIRE_KEYPAIRS ]]; then
if [[ -z $identity_keypair_path ]]; then if [[ -z $identity ]]; then
usage "Error: --identity-keypair not specified" usage "Error: --identity not specified"
fi fi
if [[ -z $voting_keypair_path ]]; then if [[ -z $vote_account ]]; then
usage "Error: --voting-keypair not specified" usage "Error: --vote-account not specified"
fi fi
fi fi
@ -205,18 +205,18 @@ fi
faucet_address="${gossip_entrypoint%:*}":9900 faucet_address="${gossip_entrypoint%:*}":9900
: "${identity_keypair_path:=$ledger_dir/identity-keypair.json}" : "${identity:=$ledger_dir/identity.json}"
: "${voting_keypair_path:=$ledger_dir/vote-keypair.json}" : "${vote_account:=$ledger_dir/vote-account.json}"
: "${storage_keypair_path:=$ledger_dir/storage-keypair.json}" : "${storage_keypair:=$ledger_dir/storage-keypair.json}"
default_arg --entrypoint "$gossip_entrypoint" default_arg --entrypoint "$gossip_entrypoint"
if ((airdrops_enabled)); then if ((airdrops_enabled)); then
default_arg --rpc-faucet-address "$faucet_address" default_arg --rpc-faucet-address "$faucet_address"
fi fi
default_arg --identity-keypair "$identity_keypair_path" default_arg --identity "$identity"
default_arg --voting-keypair "$voting_keypair_path" default_arg --vote-account "$vote_account"
default_arg --storage-keypair "$storage_keypair_path" default_arg --storage-keypair "$storage_keypair"
default_arg --ledger "$ledger_dir" default_arg --ledger "$ledger_dir"
default_arg --log - default_arg --log -
default_arg --enable-rpc-exit default_arg --enable-rpc-exit
@ -254,27 +254,27 @@ trap 'kill_node_and_exit' INT TERM ERR
wallet() { wallet() {
( (
set -x set -x
$solana_cli --keypair "$identity_keypair_path" --url "$rpc_url" "$@" $solana_cli --keypair "$identity" --url "$rpc_url" "$@"
) )
} }
setup_validator_accounts() { setup_validator_accounts() {
declare node_sol=$1 declare node_sol=$1
if ! wallet vote-account "$voting_keypair_path"; then if ! wallet vote-account "$vote_account"; then
if ((airdrops_enabled)); then if ((airdrops_enabled)); then
echo "Adding $node_sol to validator identity account:" echo "Adding $node_sol to validator identity account:"
wallet airdrop "$node_sol" || return $? wallet airdrop "$node_sol" || return $?
fi fi
echo "Creating validator vote account" echo "Creating validator vote account"
wallet create-vote-account "$voting_keypair_path" "$identity_keypair_path" || return $? wallet create-vote-account "$vote_account" "$identity" || return $?
fi fi
echo "Validator vote account configured" echo "Validator vote account configured"
if ! wallet storage-account "$storage_keypair_path"; then if ! wallet storage-account "$storage_keypair"; then
echo "Creating validator storage account" echo "Creating validator storage account"
wallet create-validator-storage-account "$identity_keypair_path" "$storage_keypair_path" || return $? wallet create-validator-storage-account "$identity" "$storage_keypair" || return $?
fi fi
echo "Validator storage account configured" echo "Validator storage account configured"
@ -286,9 +286,9 @@ setup_validator_accounts() {
rpc_url=$($solana_gossip rpc-url --entrypoint "$gossip_entrypoint" --any) rpc_url=$($solana_gossip rpc-url --entrypoint "$gossip_entrypoint" --any)
[[ -r "$identity_keypair_path" ]] || $solana_keygen new --no-passphrase -so "$identity_keypair_path" [[ -r "$identity" ]] || $solana_keygen new --no-passphrase -so "$identity"
[[ -r "$voting_keypair_path" ]] || $solana_keygen new --no-passphrase -so "$voting_keypair_path" [[ -r "$vote_account" ]] || $solana_keygen new --no-passphrase -so "$vote_account"
[[ -r "$storage_keypair_path" ]] || $solana_keygen new --no-passphrase -so "$storage_keypair_path" [[ -r "$storage_keypair" ]] || $solana_keygen new --no-passphrase -so "$storage_keypair"
setup_validator_accounts "$node_sol" setup_validator_accounts "$node_sol"

View File

@ -256,7 +256,7 @@ EOF
if [[ $skipSetup != true ]]; then if [[ $skipSetup != true ]]; then
solana --url http://"$entrypointIp":8899 \ solana --url http://"$entrypointIp":8899 \
--keypair ~/solana/config/bootstrap-validator/identity-keypair.json \ --keypair ~/solana/config/bootstrap-validator/identity.json \
validator-info publish "$(hostname)" -n team/solana --force || true validator-info publish "$(hostname)" -n team/solana --force || true
fi fi
;; ;;
@ -301,7 +301,7 @@ EOF
if [[ ! -f config/validator-identity.json ]]; then if [[ ! -f config/validator-identity.json ]]; then
solana-keygen new --no-passphrase -so config/validator-identity.json solana-keygen new --no-passphrase -so config/validator-identity.json
fi fi
args+=(--identity-keypair config/validator-identity.json) args+=(--identity config/validator-identity.json)
if [[ $airdropsEnabled != true ]]; then if [[ $airdropsEnabled != true ]]; then
args+=(--no-airdrop) args+=(--no-airdrop)
@ -411,7 +411,7 @@ EOF
) )
if [[ $airdropsEnabled != true ]]; then if [[ $airdropsEnabled != true ]]; then
# If this ever becomes a problem, we need to provide the `--identity-keypair` # If this ever becomes a problem, we need to provide the `--identity`
# argument to an existing system account with lamports in it # argument to an existing system account with lamports in it
echo "Error: archivers not supported without airdrops" echo "Error: archivers not supported without airdrops"
exit 1 exit 1

View File

@ -678,10 +678,10 @@ pub fn process_vote<S: std::hash::BuildHasher>(
vote_account.set_state(&VoteStateVersions::Current(Box::new(vote_state))) vote_account.set_state(&VoteStateVersions::Current(Box::new(vote_state)))
} }
// utility function, used by Bank, tests pub fn create_account_with_authorized(
pub fn create_account(
vote_pubkey: &Pubkey,
node_pubkey: &Pubkey, node_pubkey: &Pubkey,
authorized_voter: &Pubkey,
authorized_withdrawer: &Pubkey,
commission: u8, commission: u8,
lamports: u64, lamports: u64,
) -> Account { ) -> Account {
@ -690,8 +690,8 @@ pub fn create_account(
let vote_state = VoteState::new( let vote_state = VoteState::new(
&VoteInit { &VoteInit {
node_pubkey: *node_pubkey, node_pubkey: *node_pubkey,
authorized_voter: *vote_pubkey, authorized_voter: *authorized_voter,
authorized_withdrawer: *vote_pubkey, authorized_withdrawer: *authorized_withdrawer,
commission, commission,
}, },
&Clock::default(), &Clock::default(),
@ -703,6 +703,16 @@ pub fn create_account(
vote_account vote_account
} }
// create_account() should be removed, use create_account_with_authorized() instead
pub fn create_account(
vote_pubkey: &Pubkey,
node_pubkey: &Pubkey,
commission: u8,
lamports: u64,
) -> Account {
create_account_with_authorized(node_pubkey, vote_pubkey, vote_pubkey, commission, lamports)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

4
run.sh
View File

@ -97,8 +97,8 @@ solana-faucet --keypair "$dataDir"/faucet-keypair.json &
faucet=$! faucet=$!
args=( args=(
--identity-keypair "$dataDir"/leader-keypair.json --identity "$dataDir"/leader-keypair.json
--voting-keypair "$dataDir"/leader-vote-account-keypair.json --vote-account "$dataDir"/leader-vote-account-keypair.json
--ledger "$ledgerDir" --ledger "$ledgerDir"
--gossip-port 8001 --gossip-port 8001
--rpc-port 8899 --rpc-port 8899

View File

@ -67,7 +67,7 @@ function wait_for_bootstrap_validator_stake_drop {
while true; do while true; do
# shellcheck disable=SC2154 # shellcheck disable=SC2154
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_validator_info="$(ssh "${sshOptions[@]}" "${validatorIpList[0]}" '$HOME/.cargo/bin/solana validators | grep "$($HOME/.cargo/bin/solana-keygen pubkey ~/solana/config/bootstrap-validator/identity.json)"')"
bootstrap_validator_stake_percentage="$(echo "$bootstrap_validator_validator_info" | awk '{gsub(/[\(,\),\%]/,""); print $9}')" bootstrap_validator_stake_percentage="$(echo "$bootstrap_validator_validator_info" | awk '{gsub(/[\(,\),\%]/,""); print $9}')"
if [[ $(echo "$bootstrap_validator_stake_percentage < $max_stake" | bc) -ne 0 ]]; then if [[ $(echo "$bootstrap_validator_stake_percentage < $max_stake" | bc) -ne 0 ]]; then

View File

@ -359,6 +359,7 @@ pub fn main() {
Arg::with_name("blockstream_unix_socket") Arg::with_name("blockstream_unix_socket")
.long("blockstream") .long("blockstream")
.takes_value(true) .takes_value(true)
.hidden(true) // Don't document this argument to discourage its use
.value_name("UNIX DOMAIN SOCKET") .value_name("UNIX DOMAIN SOCKET")
.help("Stream entries to this unix domain socket path") .help("Stream entries to this unix domain socket path")
) )
@ -368,21 +369,21 @@ pub fn main() {
.help(SKIP_SEED_PHRASE_VALIDATION_ARG.help), .help(SKIP_SEED_PHRASE_VALIDATION_ARG.help),
) )
.arg( .arg(
Arg::with_name("identity_keypair") Arg::with_name("identity")
.short("i") .short("i")
.long("identity-keypair") .long("identity")
.value_name("PATH") .value_name("PATH")
.takes_value(true) .takes_value(true)
.validator(is_keypair_or_ask_keyword) .validator(is_keypair_or_ask_keyword)
.help("File containing the identity keypair for the validator"), .help("Validator identity keypair"),
) )
.arg( .arg(
Arg::with_name("voting_keypair") Arg::with_name("authorized_voter")
.long("voting-keypair") .long("authorized-voter")
.value_name("PATH") .value_name("PATH")
.takes_value(true) .takes_value(true)
.validator(is_keypair_or_ask_keyword) .validator(is_keypair_or_ask_keyword)
.help("File containing the authorized voting keypair. Default is an ephemeral keypair, which may disable voting without --vote-account."), .help("Authorized voter keypair [default: value of --identity]"),
) )
.arg( .arg(
Arg::with_name("vote_account") Arg::with_name("vote_account")
@ -390,12 +391,13 @@ pub fn main() {
.value_name("PUBKEY") .value_name("PUBKEY")
.takes_value(true) .takes_value(true)
.validator(is_pubkey_or_keypair) .validator(is_pubkey_or_keypair)
.help("Public key of the vote account to vote with. Default is the public key of --voting-keypair"), .help("Validator vote account public key. If unspecified voting will be disabled")
) )
.arg( .arg(
Arg::with_name("storage_keypair") Arg::with_name("storage_keypair")
.long("storage-keypair") .long("storage-keypair")
.value_name("PATH") .value_name("PATH")
.hidden(true) // Don't document this argument to discourage its use
.takes_value(true) .takes_value(true)
.validator(is_keypair_or_ask_keyword) .validator(is_keypair_or_ask_keyword)
.help("File containing the storage account keypair. Default is an ephemeral keypair"), .help("File containing the storage account keypair. Default is an ephemeral keypair"),
@ -652,17 +654,15 @@ pub fn main() {
) )
.get_matches(); .get_matches();
let identity_keypair = let identity_keypair = Arc::new(keypair_of(&matches, "identity").unwrap_or_else(Keypair::new));
Arc::new(keypair_of(&matches, "identity_keypair").unwrap_or_else(Keypair::new));
let (voting_keypair, ephemeral_voting_keypair) = keypair_of(&matches, "voting_keypair") let authorized_voter = keypair_of(&matches, "authorized_voter")
.map(|keypair| (keypair, false)) .map(Arc::new)
.unwrap_or_else(|| (Keypair::new(), true)); .unwrap_or_else(|| identity_keypair.clone());
let storage_keypair = keypair_of(&matches, "storage_keypair").unwrap_or_else(Keypair::new); let storage_keypair = keypair_of(&matches, "storage_keypair").unwrap_or_else(Keypair::new);
let ledger_path = PathBuf::from(matches.value_of("ledger_path").unwrap()); let ledger_path = PathBuf::from(matches.value_of("ledger_path").unwrap());
let entrypoint = matches.value_of("entrypoint");
let init_complete_file = matches.value_of("init_complete_file"); let init_complete_file = matches.value_of("init_complete_file");
let skip_poh_verify = matches.is_present("skip_poh_verify"); let skip_poh_verify = matches.is_present("skip_poh_verify");
let cuda = matches.is_present("cuda"); let cuda = matches.is_present("cuda");
@ -838,13 +838,9 @@ pub fn main() {
info!("Starting validator with: {:#?}", std::env::args_os()); info!("Starting validator with: {:#?}", std::env::args_os());
let vote_account = pubkey_of(&matches, "vote_account").unwrap_or_else(|| { let vote_account = pubkey_of(&matches, "vote_account").unwrap_or_else(|| {
// Disable voting because normal (=not bootstrapping) validator rejects warn!("--vote-account not specified, validator will not vote");
// non-voting accounts (= ephemeral keypairs). validator_config.voting_disabled = true;
if ephemeral_voting_keypair && entrypoint.is_some() { Keypair::new().pubkey()
warn!("Disabled voting due to the use of ephemeral key for vote account");
validator_config.voting_disabled = true;
};
voting_keypair.pubkey()
}); });
solana_metrics::set_host_id(identity_keypair.pubkey().to_string()); solana_metrics::set_host_id(identity_keypair.pubkey().to_string());
@ -1014,7 +1010,7 @@ pub fn main() {
check_vote_account( check_vote_account(
&rpc_client, &rpc_client,
&vote_account, &vote_account,
&voting_keypair.pubkey(), &authorized_voter.pubkey(),
&identity_keypair.pubkey(), &identity_keypair.pubkey(),
) )
} else { } else {
@ -1057,7 +1053,7 @@ pub fn main() {
&identity_keypair, &identity_keypair,
&ledger_path, &ledger_path,
&vote_account, &vote_account,
&Arc::new(voting_keypair), &authorized_voter,
&Arc::new(storage_keypair), &Arc::new(storage_keypair),
cluster_entrypoint.as_ref(), cluster_entrypoint.as_ref(),
!skip_poh_verify, !skip_poh_verify,