Remove airdrop from fullnode
This commit is contained in:
parent
1576072edb
commit
a0dd8617be
|
@ -60,6 +60,7 @@ if ((!self_setup)); then
|
|||
echo " ${here}/setup.sh"
|
||||
exit 1
|
||||
}
|
||||
validator_id_path=$SOLANA_CONFIG_PRIVATE_DIR/validator-id.json
|
||||
validator_json_path=$SOLANA_CONFIG_VALIDATOR_DIR/validator.json
|
||||
SOLANA_LEADER_CONFIG_DIR=$SOLANA_CONFIG_VALIDATOR_DIR/leader-config
|
||||
else
|
||||
|
@ -78,6 +79,22 @@ else
|
|||
SOLANA_LEADER_CONFIG_DIR=$SOLANA_CONFIG_VALIDATOR_DIR/leader-config-x$$
|
||||
fi
|
||||
|
||||
[[ -r $validator_id_path ]] || {
|
||||
echo "$validator_id_path does not exist"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# A fullnode requires 2 tokens to function:
|
||||
# - one token to create an instance of the vote_program with
|
||||
# - one second token to keep the node identity public key valid.
|
||||
(
|
||||
set -x
|
||||
$solana_wallet \
|
||||
--keypair "$validator_id_path" \
|
||||
--network "$leader_address" \
|
||||
airdrop 2
|
||||
)
|
||||
|
||||
rsync_leader_url=$(rsync_url "$leader")
|
||||
|
||||
tune_networking
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#[macro_use]
|
||||
extern crate clap;
|
||||
extern crate dirs;
|
||||
extern crate ring;
|
||||
extern crate serde_json;
|
||||
extern crate solana;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use ring::rand::SystemRandom;
|
||||
use ring::signature::Ed25519KeyPair;
|
||||
use solana::cluster_info::FULLNODE_PORT_RANGE;
|
||||
use solana::fullnode::Config;
|
||||
use solana::logger;
|
||||
|
@ -67,9 +70,12 @@ fn main() {
|
|||
};
|
||||
let pkcs8 = read_pkcs8(id_path).expect("client keypair");
|
||||
|
||||
let rnd = SystemRandom::new();
|
||||
let vote_account_pkcs8 = Ed25519KeyPair::generate_pkcs8(&rnd).unwrap();
|
||||
|
||||
// we need all the receiving sockets to be bound within the expected
|
||||
// port range that we open on aws
|
||||
let config = Config::new(&bind_addr, pkcs8);
|
||||
let config = Config::new(&bind_addr, pkcs8, vote_account_pkcs8.to_vec());
|
||||
let stdout = io::stdout();
|
||||
serde_json::to_writer(stdout, &config).expect("serialize");
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ extern crate solana;
|
|||
use clap::{App, Arg};
|
||||
use solana::client::mk_client;
|
||||
use solana::cluster_info::{Node, FULLNODE_PORT_RANGE};
|
||||
use solana::drone::{request_airdrop_transaction, DRONE_PORT};
|
||||
use solana::fullnode::{Config, Fullnode, FullnodeReturnType};
|
||||
use solana::leader_scheduler::LeaderScheduler;
|
||||
use solana::logger;
|
||||
|
@ -19,6 +18,7 @@ use solana::netutil::find_available_port_in_range;
|
|||
use solana::signature::{Keypair, KeypairUtil};
|
||||
use solana::thin_client::poll_gossip_for_leader;
|
||||
use solana::vote_program::VoteProgram;
|
||||
use solana::vote_transaction::VoteTransaction;
|
||||
use std::fs::File;
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::process::exit;
|
||||
|
@ -61,12 +61,16 @@ fn main() {
|
|||
.help("Custom RPC port for this node"),
|
||||
).get_matches();
|
||||
|
||||
let (keypair, ncp) = if let Some(i) = matches.value_of("identity") {
|
||||
let (keypair, vote_account_keypair, ncp) = if let Some(i) = matches.value_of("identity") {
|
||||
let path = i.to_string();
|
||||
if let Ok(file) = File::open(path.clone()) {
|
||||
let parse: serde_json::Result<Config> = serde_json::from_reader(file);
|
||||
if let Ok(data) = parse {
|
||||
(data.keypair(), data.node_info.ncp)
|
||||
(
|
||||
data.keypair(),
|
||||
data.vote_account_keypair(),
|
||||
data.node_info.ncp,
|
||||
)
|
||||
} else {
|
||||
eprintln!("failed to parse {}", path);
|
||||
exit(1);
|
||||
|
@ -76,7 +80,7 @@ fn main() {
|
|||
exit(1);
|
||||
}
|
||||
} else {
|
||||
(Keypair::new(), socketaddr!(0, 8000))
|
||||
(Keypair::new(), Keypair::new(), socketaddr!(0, 8000))
|
||||
};
|
||||
|
||||
let ledger_path = matches.value_of("ledger").unwrap();
|
||||
|
@ -91,7 +95,7 @@ fn main() {
|
|||
// save off some stuff for airdrop
|
||||
let mut node_info = node.info.clone();
|
||||
|
||||
let vote_account_keypair = Arc::new(Keypair::new());
|
||||
let vote_account_keypair = Arc::new(vote_account_keypair);
|
||||
let vote_account_id = vote_account_keypair.pubkey();
|
||||
let keypair = Arc::new(keypair);
|
||||
let pubkey = keypair.pubkey();
|
||||
|
@ -133,7 +137,7 @@ fn main() {
|
|||
node,
|
||||
ledger_path,
|
||||
keypair.clone(),
|
||||
vote_account_keypair,
|
||||
vote_account_keypair.clone(),
|
||||
network,
|
||||
false,
|
||||
leader_scheduler,
|
||||
|
@ -141,66 +145,43 @@ fn main() {
|
|||
);
|
||||
let mut client = mk_client(&leader);
|
||||
|
||||
// TODO: maybe have the drone put itself in gossip somewhere instead of hardcoding?
|
||||
let drone_addr = match network {
|
||||
Some(network) => SocketAddr::new(network.ip(), DRONE_PORT),
|
||||
None => SocketAddr::new(ncp.ip(), DRONE_PORT),
|
||||
};
|
||||
|
||||
loop {
|
||||
let balance = client.poll_get_balance(&pubkey).unwrap_or(0);
|
||||
info!("balance is {}", balance);
|
||||
|
||||
if balance >= 50 {
|
||||
info!("good to go!");
|
||||
break;
|
||||
if balance < 1 {
|
||||
error!("insufficient tokens");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
info!("requesting airdrop from {}", drone_addr);
|
||||
// Create the vote account if necessary
|
||||
if client.poll_get_balance(&vote_account_id).unwrap_or(0) == 0 {
|
||||
// Need at least two tokens as one token will be spent on a vote_account_new() transaction
|
||||
if balance < 2 {
|
||||
error!("insufficient tokens");
|
||||
exit(1);
|
||||
}
|
||||
loop {
|
||||
let last_id = client.get_last_id();
|
||||
if let Ok(transaction) = request_airdrop_transaction(&drone_addr, &pubkey, 50, last_id)
|
||||
{
|
||||
let signature = client.transfer_signed(&transaction).unwrap();
|
||||
if client.poll_for_signature(&signature).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
info!(
|
||||
"airdrop request, is the drone address correct {:?}, drone running?",
|
||||
drone_addr
|
||||
);
|
||||
sleep(Duration::from_secs(2));
|
||||
}
|
||||
}
|
||||
|
||||
// Create the vote account
|
||||
loop {
|
||||
let last_id = client.get_last_id();
|
||||
if client
|
||||
.create_vote_account(&keypair, vote_account_id, &last_id, 1)
|
||||
.is_err()
|
||||
{
|
||||
let transaction =
|
||||
VoteTransaction::vote_account_new(&keypair, vote_account_id, last_id, 1);
|
||||
if client.transfer_signed(&transaction).is_err() {
|
||||
sleep(Duration::from_secs(2));
|
||||
continue;
|
||||
}
|
||||
|
||||
let balance = client.poll_get_balance(&vote_account_id).unwrap_or(0);
|
||||
|
||||
if balance > 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
sleep(Duration::from_secs(2));
|
||||
}
|
||||
}
|
||||
|
||||
// Register the vote account to this node
|
||||
loop {
|
||||
let last_id = client.get_last_id();
|
||||
if client
|
||||
.register_vote_account(&keypair, vote_account_id, &last_id)
|
||||
.is_err()
|
||||
{
|
||||
let transaction =
|
||||
VoteTransaction::vote_account_register(&keypair, vote_account_id, last_id, 0);
|
||||
if client.transfer_signed(&transaction).is_err() {
|
||||
sleep(Duration::from_secs(2));
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,13 @@ use std::error;
|
|||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
/**
|
||||
* Bootstrap leader gets two tokens:
|
||||
* - one token to create an instance of the vote_program with
|
||||
* - one second token to keep the node identity public key valid
|
||||
*/
|
||||
pub const BOOTSTRAP_LEADER_TOKENS: u64 = 2;
|
||||
|
||||
fn main() -> Result<(), Box<error::Error>> {
|
||||
let matches = App::new("solana-genesis")
|
||||
.version(crate_version!())
|
||||
|
@ -62,7 +69,12 @@ fn main() -> Result<(), Box<error::Error>> {
|
|||
let num_tokens = value_t_or_exit!(matches, "num_tokens", u64);
|
||||
let file = File::open(Path::new(&matches.value_of("mint").unwrap())).unwrap();
|
||||
let pkcs8: Vec<u8> = serde_json::from_reader(&file)?;
|
||||
let mint = Mint::new_with_pkcs8(num_tokens, pkcs8, leader_keypair.pubkey(), 1);
|
||||
let mint = Mint::new_with_pkcs8(
|
||||
num_tokens,
|
||||
pkcs8,
|
||||
leader_keypair.pubkey(),
|
||||
BOOTSTRAP_LEADER_TOKENS,
|
||||
);
|
||||
|
||||
// Write the ledger entries
|
||||
let ledger_path = matches.value_of("ledger").unwrap();
|
||||
|
|
|
@ -110,20 +110,29 @@ pub struct Fullnode {
|
|||
pub struct Config {
|
||||
pub node_info: NodeInfo,
|
||||
pkcs8: Vec<u8>,
|
||||
vote_account_pkcs8: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(bind_addr: &SocketAddr, pkcs8: Vec<u8>) -> Self {
|
||||
pub fn new(bind_addr: &SocketAddr, pkcs8: Vec<u8>, vote_account_pkcs8: Vec<u8>) -> Self {
|
||||
let keypair =
|
||||
Keypair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in fullnode::Config new");
|
||||
let pubkey = keypair.pubkey();
|
||||
let node_info = NodeInfo::new_with_pubkey_socketaddr(pubkey, bind_addr);
|
||||
Config { node_info, pkcs8 }
|
||||
Config {
|
||||
node_info,
|
||||
pkcs8,
|
||||
vote_account_pkcs8,
|
||||
}
|
||||
}
|
||||
pub fn keypair(&self) -> Keypair {
|
||||
Keypair::from_pkcs8(Input::from(&self.pkcs8))
|
||||
.expect("from_pkcs8 in fullnode::Config keypair")
|
||||
}
|
||||
pub fn vote_account_keypair(&self) -> Keypair {
|
||||
Keypair::from_pkcs8(Input::from(&self.vote_account_pkcs8))
|
||||
.expect("from_pkcs8 in fullnode::Config vote_account_keypair")
|
||||
}
|
||||
}
|
||||
|
||||
impl Fullnode {
|
||||
|
|
|
@ -29,7 +29,6 @@ use std::time::Instant;
|
|||
use system_transaction::SystemTransaction;
|
||||
use timing;
|
||||
use transaction::Transaction;
|
||||
use vote_transaction::VoteTransaction;
|
||||
|
||||
use influx_db_client as influxdb;
|
||||
use metrics;
|
||||
|
@ -99,29 +98,6 @@ impl ThinClient {
|
|||
))
|
||||
}
|
||||
|
||||
pub fn create_vote_account(
|
||||
&self,
|
||||
node_keypair: &Keypair,
|
||||
vote_account_id: Pubkey,
|
||||
last_id: &Hash,
|
||||
num_tokens: u64,
|
||||
) -> io::Result<Signature> {
|
||||
let tx =
|
||||
Transaction::vote_account_new(&node_keypair, vote_account_id, *last_id, num_tokens);
|
||||
self.transfer_signed(&tx)
|
||||
}
|
||||
|
||||
/// Creates, signs, and processes a vote Transaction. Useful for writing unit-tests.
|
||||
pub fn register_vote_account(
|
||||
&self,
|
||||
node_keypair: &Keypair,
|
||||
vote_account_id: Pubkey,
|
||||
last_id: &Hash,
|
||||
) -> io::Result<Signature> {
|
||||
let tx = Transaction::vote_account_register(node_keypair, vote_account_id, *last_id, 0);
|
||||
self.transfer_signed(&tx)
|
||||
}
|
||||
|
||||
/// Creates, signs, and processes a Transaction. Useful for writing unit-tests.
|
||||
pub fn transfer(
|
||||
&self,
|
||||
|
@ -445,6 +421,7 @@ mod tests {
|
|||
use std::fs::remove_dir_all;
|
||||
use system_program::SystemProgram;
|
||||
use vote_program::VoteProgram;
|
||||
use vote_transaction::VoteTransaction;
|
||||
|
||||
#[test]
|
||||
fn test_thin_client() {
|
||||
|
@ -650,20 +627,21 @@ mod tests {
|
|||
let validator_vote_account_keypair = Keypair::new();
|
||||
let vote_account_id = validator_vote_account_keypair.pubkey();
|
||||
let last_id = client.get_last_id();
|
||||
let signature = client
|
||||
.create_vote_account(&validator_keypair, vote_account_id, &last_id, 1)
|
||||
.unwrap();
|
||||
|
||||
let transaction =
|
||||
VoteTransaction::vote_account_new(&validator_keypair, vote_account_id, last_id, 1);
|
||||
let signature = client.transfer_signed(&transaction).unwrap();
|
||||
assert!(client.poll_for_signature(&signature).is_ok());
|
||||
|
||||
let balance = retry_get_balance(&mut client, &vote_account_id, Some(1))
|
||||
.expect("Expected balance for new account to exist");
|
||||
assert_eq!(balance, 1);
|
||||
|
||||
// Register the vote account to the validator
|
||||
let last_id = client.get_last_id();
|
||||
let signature = client
|
||||
.register_vote_account(&validator_keypair, vote_account_id, &last_id)
|
||||
.unwrap();
|
||||
let transaction =
|
||||
VoteTransaction::vote_account_register(&validator_keypair, vote_account_id, last_id, 0);
|
||||
let signature = client.transfer_signed(&transaction).unwrap();
|
||||
assert!(client.poll_for_signature(&signature).is_ok());
|
||||
|
||||
const LAST: usize = 30;
|
||||
|
|
Loading…
Reference in New Issue