Add FeeCalculator to the genesis block (#4196)

This commit is contained in:
Michael Vines 2019-05-07 20:28:41 -07:00 committed by GitHub
parent 674a49f8d7
commit 7609a007c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 62 deletions

View File

@ -3,6 +3,7 @@
use clap::{crate_description, crate_name, crate_version, value_t_or_exit, App, Arg}; use clap::{crate_description, crate_name, crate_version, value_t_or_exit, App, Arg};
use solana::blocktree::create_new_ledger; use solana::blocktree::create_new_ledger;
use solana_sdk::account::Account; use solana_sdk::account::Account;
use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::signature::{read_keypair, KeypairUtil}; use solana_sdk::signature::{read_keypair, KeypairUtil};
use solana_sdk::system_program; use solana_sdk::system_program;
@ -13,6 +14,9 @@ pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 42;
fn main() -> Result<(), Box<dyn error::Error>> { fn main() -> Result<(), Box<dyn error::Error>> {
let default_bootstrap_leader_lamports = &BOOTSTRAP_LEADER_LAMPORTS.to_string(); let default_bootstrap_leader_lamports = &BOOTSTRAP_LEADER_LAMPORTS.to_string();
let default_lamports_per_signature =
&format!("{}", FeeCalculator::default().lamports_per_signature);
let matches = App::new(crate_name!()) let matches = App::new(crate_name!())
.about(crate_description!()) .about(crate_description!())
.version(crate_version!()) .version(crate_version!())
@ -70,6 +74,14 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.required(true) .required(true)
.help("Number of lamports to assign to the bootstrap leader"), .help("Number of lamports to assign to the bootstrap leader"),
) )
.arg(
Arg::with_name("lamports_per_signature")
.long("lamports-per-signature")
.value_name("LAMPORTS")
.takes_value(true)
.default_value(default_lamports_per_signature)
.help("Number of lamports the cluster will charge for signature verification"),
)
.get_matches(); .get_matches();
let bootstrap_leader_keypair_file = matches.value_of("bootstrap_leader_keypair_file").unwrap(); let bootstrap_leader_keypair_file = matches.value_of("bootstrap_leader_keypair_file").unwrap();
@ -83,7 +95,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
let bootstrap_vote_keypair = read_keypair(bootstrap_vote_keypair_file)?; let bootstrap_vote_keypair = read_keypair(bootstrap_vote_keypair_file)?;
let mint_keypair = read_keypair(mint_keypair_file)?; let mint_keypair = read_keypair(mint_keypair_file)?;
let genesis_block = GenesisBlock::new( let mut genesis_block = GenesisBlock::new(
&bootstrap_leader_keypair.pubkey(), &bootstrap_leader_keypair.pubkey(),
&[ &[
( (
@ -120,6 +132,8 @@ fn main() -> Result<(), Box<dyn error::Error>> {
), ),
], ],
); );
genesis_block.fee_calculator.lamports_per_signature =
value_t_or_exit!(matches, "lamports_per_signature", u64);
create_new_ledger(ledger_path, &genesis_block)?; create_new_ledger(ledger_path, &genesis_block)?;
Ok(()) Ok(())

View File

@ -154,7 +154,7 @@ default_fullnode_arg() {
extra_fullnode_args=() extra_fullnode_args=()
bootstrap_leader=false bootstrap_leader=false
stake=43 # number of lamports to assign as stake (plus transaction fee to setup the stake) stake=42 # number of lamports to assign as stake
poll_for_new_genesis_block=0 poll_for_new_genesis_block=0
label= label=

View File

@ -4,46 +4,6 @@ here=$(dirname "$0")
# shellcheck source=multinode-demo/common.sh # shellcheck source=multinode-demo/common.sh
source "$here"/common.sh source "$here"/common.sh
lamports=100000000000000
bootstrap_leader_lamports=
usage () {
exitcode=0
if [[ -n "$1" ]]; then
exitcode=1
echo "Error: $*"
fi
cat <<EOF
usage: $0 [-n lamports] [-b lamports]
Create a cluster configuration
-n lamports - Number of lamports to create [default: $lamports]
-b lamports - Override the number of lamports for the bootstrap leader's stake
EOF
exit $exitcode
}
while getopts "h?n:b:" opt; do
case $opt in
h|\?)
usage
exit 0
;;
n)
lamports="$OPTARG"
;;
b)
bootstrap_leader_lamports="$OPTARG"
;;
*)
usage "Error: unhandled option: $opt"
;;
esac
done
set -e set -e
"$here"/clear-fullnode-config.sh "$here"/clear-fullnode-config.sh
@ -52,17 +12,32 @@ $solana_keygen -o "$SOLANA_CONFIG_DIR"/mint-id.json
$solana_keygen -o "$SOLANA_CONFIG_DIR"/bootstrap-leader-id.json $solana_keygen -o "$SOLANA_CONFIG_DIR"/bootstrap-leader-id.json
$solana_keygen -o "$SOLANA_CONFIG_DIR"/bootstrap-leader-vote-id.json $solana_keygen -o "$SOLANA_CONFIG_DIR"/bootstrap-leader-vote-id.json
args=(
--bootstrap-leader-keypair "$SOLANA_CONFIG_DIR"/bootstrap-leader-id.json
--bootstrap-vote-keypair "$SOLANA_CONFIG_DIR"/bootstrap-leader-vote-id.json
--ledger "$SOLANA_RSYNC_CONFIG_DIR"/ledger
--mint "$SOLANA_CONFIG_DIR"/mint-id.json
--lamports "$lamports"
)
if [[ -n $bootstrap_leader_lamports ]]; then default_arg() {
args+=(--bootstrap-leader-lamports "$bootstrap_leader_lamports") declare name=$1
fi declare value=$2
for arg in "${args[@]}"; do
if [[ $arg = "$name" ]]; then
return
fi
done
if [[ -n $value ]]; then
args+=("$name" "$value")
else
args+=("$name")
fi
}
args=("$@")
default_arg --bootstrap-leader-keypair "$SOLANA_CONFIG_DIR"/bootstrap-leader-id.json
default_arg --bootstrap-vote-keypair "$SOLANA_CONFIG_DIR"/bootstrap-leader-vote-id.json
default_arg --ledger "$SOLANA_RSYNC_CONFIG_DIR"/ledger
default_arg --mint "$SOLANA_CONFIG_DIR"/mint-id.json
default_arg --lamports 100000000000000
$solana_genesis "${args[@]}" $solana_genesis "${args[@]}"
test -d "$SOLANA_RSYNC_CONFIG_DIR"/ledger
cp -a "$SOLANA_RSYNC_CONFIG_DIR"/ledger "$SOLANA_CONFIG_DIR"/bootstrap-leader-ledger cp -a "$SOLANA_RSYNC_CONFIG_DIR"/ledger "$SOLANA_CONFIG_DIR"/bootstrap-leader-ledger

View File

@ -78,7 +78,7 @@ local|tar)
fi fi
set -x set -x
if [[ $skipSetup != true ]]; then if [[ $skipSetup != true ]]; then
./multinode-demo/setup.sh -b $stake ./multinode-demo/setup.sh --bootstrap-leader-lamports $stake
fi fi
./multinode-demo/drone.sh > drone.log 2>&1 & ./multinode-demo/drone.sh > drone.log 2>&1 &

2
run.sh
View File

@ -51,6 +51,8 @@ leaderVoteAccountPubkey=$(\
solana-genesis \ solana-genesis \
--lamports 1000000000 \ --lamports 1000000000 \
--bootstrap-leader-lamports 10000000 \
--lamports-per-signature 1 \
--mint "$dataDir"/config/drone-keypair.json \ --mint "$dataDir"/config/drone-keypair.json \
--bootstrap-leader-keypair "$dataDir"/config/leader-keypair.json \ --bootstrap-leader-keypair "$dataDir"/config/leader-keypair.json \
--bootstrap-vote-keypair "$dataDir"/config/leader-vote-account-keypair.json \ --bootstrap-vote-keypair "$dataDir"/config/leader-vote-account-keypair.json \

View File

@ -221,6 +221,7 @@ impl Bank {
bank.blockhash_queue = RwLock::new(parent.blockhash_queue.read().unwrap().clone()); bank.blockhash_queue = RwLock::new(parent.blockhash_queue.read().unwrap().clone());
bank.status_cache = parent.status_cache.clone(); bank.status_cache = parent.status_cache.clone();
bank.bank_height = parent.bank_height + 1; bank.bank_height = parent.bank_height + 1;
bank.fee_calculator = parent.fee_calculator.clone();
bank.transaction_count bank.transaction_count
.store(parent.transaction_count() as usize, Ordering::Relaxed); .store(parent.transaction_count() as usize, Ordering::Relaxed);
@ -340,6 +341,7 @@ impl Bank {
fn process_genesis_block(&mut self, genesis_block: &GenesisBlock) { fn process_genesis_block(&mut self, genesis_block: &GenesisBlock) {
// Bootstrap leader collects fees until `new_from_parent` is called. // Bootstrap leader collects fees until `new_from_parent` is called.
self.collector_id = genesis_block.bootstrap_leader_id; self.collector_id = genesis_block.bootstrap_leader_id;
self.fee_calculator = genesis_block.fee_calculator.clone();
for (pubkey, account) in genesis_block.accounts.iter() { for (pubkey, account) in genesis_block.accounts.iter() {
self.store(pubkey, account); self.store(pubkey, account);
@ -1881,6 +1883,18 @@ pub(crate) mod tests {
assert_eq!(bank6.transaction_count(), 1); assert_eq!(bank6.transaction_count(), 1);
} }
#[test]
fn test_bank_inherit_fee_calculator() {
let (mut genesis_block, _mint_keypair) = create_genesis_block(500);
genesis_block.fee_calculator.lamports_per_signature = 123;
let bank0 = Arc::new(Bank::new(&genesis_block));
let bank1 = Arc::new(new_from_parent(&bank0));
assert_eq!(
bank0.fee_calculator.lamports_per_signature,
bank1.fee_calculator.lamports_per_signature
);
}
#[test] #[test]
fn test_bank_vote_accounts() { fn test_bank_vote_accounts() {
let (genesis_block, mint_keypair, _voting_keypair) = let (genesis_block, mint_keypair, _voting_keypair) =

View File

@ -1,6 +1,6 @@
use crate::message::Message; use crate::message::Message;
#[derive(Default)] #[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct FeeCalculator { pub struct FeeCalculator {
pub lamports_per_signature: u64, pub lamports_per_signature: u64,
} }

View File

@ -1,6 +1,7 @@
//! The `genesis_block` module is a library for generating the chain's genesis block. //! The `genesis_block` module is a library for generating the chain's genesis block.
use crate::account::Account; use crate::account::Account;
use crate::fee_calculator::FeeCalculator;
use crate::hash::{hash, Hash}; use crate::hash::{hash, Hash};
use crate::pubkey::Pubkey; use crate::pubkey::Pubkey;
use crate::signature::{Keypair, KeypairUtil}; use crate::signature::{Keypair, KeypairUtil};
@ -12,13 +13,14 @@ use std::path::Path;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct GenesisBlock { pub struct GenesisBlock {
pub accounts: Vec<(Pubkey, Account)>,
pub bootstrap_leader_id: Pubkey, pub bootstrap_leader_id: Pubkey,
pub ticks_per_slot: u64, pub epoch_warmup: bool,
pub fee_calculator: FeeCalculator,
pub native_instruction_processors: Vec<(String, Pubkey)>,
pub slots_per_epoch: u64, pub slots_per_epoch: u64,
pub stakers_slot_offset: u64, pub stakers_slot_offset: u64,
pub epoch_warmup: bool, pub ticks_per_slot: u64,
pub accounts: Vec<(Pubkey, Account)>,
pub native_instruction_processors: Vec<(String, Pubkey)>,
} }
// useful for basic tests // useful for basic tests
@ -44,13 +46,14 @@ impl GenesisBlock {
native_instruction_processors: &[(String, Pubkey)], native_instruction_processors: &[(String, Pubkey)],
) -> Self { ) -> Self {
Self { Self {
accounts: accounts.to_vec(),
bootstrap_leader_id: *bootstrap_leader_id, // TODO: leader_schedule to derive from actual stakes, instead ;) bootstrap_leader_id: *bootstrap_leader_id, // TODO: leader_schedule to derive from actual stakes, instead ;)
ticks_per_slot: DEFAULT_TICKS_PER_SLOT, epoch_warmup: true,
fee_calculator: FeeCalculator::default(),
native_instruction_processors: native_instruction_processors.to_vec(),
slots_per_epoch: DEFAULT_SLOTS_PER_EPOCH, slots_per_epoch: DEFAULT_SLOTS_PER_EPOCH,
stakers_slot_offset: DEFAULT_SLOTS_PER_EPOCH, stakers_slot_offset: DEFAULT_SLOTS_PER_EPOCH,
epoch_warmup: true, ticks_per_slot: DEFAULT_TICKS_PER_SLOT,
accounts: accounts.to_vec(),
native_instruction_processors: native_instruction_processors.to_vec(),
} }
} }