parent
81c44c605b
commit
b5006b8f2b
|
@ -37,10 +37,6 @@ path = "src/bin/fullnode-config.rs"
|
||||||
name = "solana-genesis"
|
name = "solana-genesis"
|
||||||
path = "src/bin/genesis.rs"
|
path = "src/bin/genesis.rs"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "solana-mint"
|
|
||||||
path = "src/bin/mint.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "solana-drone"
|
name = "solana-drone"
|
||||||
path = "src/bin/drone.rs"
|
path = "src/bin/drone.rs"
|
||||||
|
|
|
@ -23,7 +23,7 @@ fi
|
||||||
|
|
||||||
client_json="$SOLANA_CONFIG_CLIENT_DIR"/client.json
|
client_json="$SOLANA_CONFIG_CLIENT_DIR"/client.json
|
||||||
if [[ ! -r $client_json ]]; then
|
if [[ ! -r $client_json ]]; then
|
||||||
$solana_mint <<<0 > "$client_json"
|
$solana_keygen > "$client_json"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# shellcheck disable=SC2086 # $solana_client_demo should not be quoted
|
# shellcheck disable=SC2086 # $solana_client_demo should not be quoted
|
||||||
|
|
|
@ -53,7 +53,7 @@ solana_fullnode=$(solana_program fullnode)
|
||||||
solana_fullnode_config=$(solana_program fullnode-config)
|
solana_fullnode_config=$(solana_program fullnode-config)
|
||||||
solana_fullnode_cuda=$(solana_program fullnode-cuda)
|
solana_fullnode_cuda=$(solana_program fullnode-cuda)
|
||||||
solana_genesis=$(solana_program genesis)
|
solana_genesis=$(solana_program genesis)
|
||||||
solana_mint=$(solana_program mint)
|
solana_keygen=$(solana_program keygen)
|
||||||
|
|
||||||
export RUST_LOG=${RUST_LOG:-solana=info} # if RUST_LOG is unset, default to info
|
export RUST_LOG=${RUST_LOG:-solana=info} # if RUST_LOG is unset, default to info
|
||||||
export RUST_BACKTRACE=1
|
export RUST_BACKTRACE=1
|
||||||
|
|
|
@ -84,10 +84,10 @@ if $node_type_leader; then
|
||||||
mkdir -p "$SOLANA_CONFIG_PRIVATE_DIR"
|
mkdir -p "$SOLANA_CONFIG_PRIVATE_DIR"
|
||||||
|
|
||||||
echo "Creating $SOLANA_CONFIG_DIR/mint.json with $num_tokens tokens"
|
echo "Creating $SOLANA_CONFIG_DIR/mint.json with $num_tokens tokens"
|
||||||
$solana_mint <<<"$num_tokens" > "$SOLANA_CONFIG_PRIVATE_DIR"/mint.json
|
$solana_keygen > "$SOLANA_CONFIG_PRIVATE_DIR"/mint.json
|
||||||
|
|
||||||
echo "Creating $SOLANA_CONFIG_DIR/genesis.log"
|
echo "Creating $SOLANA_CONFIG_DIR/genesis.log"
|
||||||
$solana_genesis < "$SOLANA_CONFIG_PRIVATE_DIR"/mint.json > "$SOLANA_CONFIG_DIR"/genesis.log
|
$solana_genesis --tokens="$num_tokens" < "$SOLANA_CONFIG_PRIVATE_DIR"/mint.json > "$SOLANA_CONFIG_DIR"/genesis.log
|
||||||
|
|
||||||
echo "Creating $SOLANA_CONFIG_DIR/leader.json"
|
echo "Creating $SOLANA_CONFIG_DIR/leader.json"
|
||||||
$solana_fullnode_config "${leader_address_args[@]}" > "$SOLANA_CONFIG_DIR"/leader.json
|
$solana_fullnode_config "${leader_address_args[@]}" > "$SOLANA_CONFIG_DIR"/leader.json
|
||||||
|
|
|
@ -38,7 +38,7 @@ fi
|
||||||
|
|
||||||
client_json="$SOLANA_CONFIG_CLIENT_DIR"/client.json
|
client_json="$SOLANA_CONFIG_CLIENT_DIR"/client.json
|
||||||
if [[ ! -r $client_json ]]; then
|
if [[ ! -r $client_json ]]; then
|
||||||
$solana_mint <<<0 > "$client_json"
|
$solana_keygen > "$client_json"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
|
@ -39,8 +39,8 @@ apps:
|
||||||
- network-bind
|
- network-bind
|
||||||
genesis:
|
genesis:
|
||||||
command: solana-genesis
|
command: solana-genesis
|
||||||
mint:
|
keygen:
|
||||||
command: solana-mint
|
command: solana-keygen
|
||||||
client-demo:
|
client-demo:
|
||||||
command: solana-client-demo
|
command: solana-client-demo
|
||||||
wallet:
|
wallet:
|
||||||
|
|
|
@ -16,7 +16,7 @@ use solana::mint::Mint;
|
||||||
use solana::nat::{udp_public_bind, udp_random_bind};
|
use solana::nat::{udp_public_bind, udp_random_bind};
|
||||||
use solana::ncp::Ncp;
|
use solana::ncp::Ncp;
|
||||||
use solana::service::Service;
|
use solana::service::Service;
|
||||||
use solana::signature::{GenKeys, KeyPair, KeyPairUtil};
|
use solana::signature::{read_keypair, GenKeys, KeyPair, KeyPairUtil};
|
||||||
use solana::streamer::default_window;
|
use solana::streamer::default_window;
|
||||||
use solana::thin_client::ThinClient;
|
use solana::thin_client::ThinClient;
|
||||||
use solana::timing::{duration_as_ms, duration_as_s};
|
use solana::timing::{duration_as_ms, duration_as_s};
|
||||||
|
@ -77,7 +77,7 @@ fn sample_tx_count(
|
||||||
fn generate_and_send_txs(
|
fn generate_and_send_txs(
|
||||||
client: &mut ThinClient,
|
client: &mut ThinClient,
|
||||||
tx_clients: &[ThinClient],
|
tx_clients: &[ThinClient],
|
||||||
id: &Mint,
|
id: &KeyPair,
|
||||||
keypairs: &[KeyPair],
|
keypairs: &[KeyPair],
|
||||||
leader: &NodeInfo,
|
leader: &NodeInfo,
|
||||||
txs: i64,
|
txs: i64,
|
||||||
|
@ -91,7 +91,7 @@ fn generate_and_send_txs(
|
||||||
let transactions: Vec<_> = if !reclaim {
|
let transactions: Vec<_> = if !reclaim {
|
||||||
keypairs
|
keypairs
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|keypair| Transaction::new(&id.keypair(), keypair.pubkey(), 1, *last_id))
|
.map(|keypair| Transaction::new(&id, keypair.pubkey(), 1, *last_id))
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
keypairs
|
keypairs
|
||||||
|
@ -171,6 +171,14 @@ fn main() {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("/path/to/mint.json"),
|
.help("/path/to/mint.json"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("keypair")
|
||||||
|
.short("k")
|
||||||
|
.long("keypair")
|
||||||
|
.value_name("PATH")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("/path/to/id.json"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("num_nodes")
|
Arg::with_name("num_nodes")
|
||||||
.short("n")
|
.short("n")
|
||||||
|
@ -205,12 +213,12 @@ fn main() {
|
||||||
leader = NodeInfo::new_leader(&server_addr);
|
leader = NodeInfo::new_leader(&server_addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
let id: Mint;
|
let id = if let Some(m) = matches.value_of("keypair") {
|
||||||
if let Some(m) = matches.value_of("mint") {
|
read_keypair(m).expect("client keypair")
|
||||||
id = read_mint(m).expect("client mint");
|
} else if let Some(m) = matches.value_of("mint") {
|
||||||
|
read_mint(m).expect("client mint").keypair()
|
||||||
} else {
|
} else {
|
||||||
eprintln!("No mint found!");
|
read_keypair("~/.config/solana/id.json").expect("default keypair")
|
||||||
exit(1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(t) = matches.value_of("threads") {
|
if let Some(t) = matches.value_of("threads") {
|
||||||
|
@ -259,7 +267,7 @@ fn main() {
|
||||||
println!("Got last ID {:?}", last_id);
|
println!("Got last ID {:?}", last_id);
|
||||||
|
|
||||||
let mut seed = [0u8; 32];
|
let mut seed = [0u8; 32];
|
||||||
seed.copy_from_slice(&id.keypair().public_key_bytes()[..32]);
|
seed.copy_from_slice(&id.public_key_bytes()[..32]);
|
||||||
let rnd = GenKeys::new(seed);
|
let rnd = GenKeys::new(seed);
|
||||||
|
|
||||||
println!("Creating keypairs...");
|
println!("Creating keypairs...");
|
||||||
|
@ -441,7 +449,7 @@ fn read_mint(path: &str) -> Result<Mint, Box<error::Error>> {
|
||||||
|
|
||||||
fn request_airdrop(
|
fn request_airdrop(
|
||||||
drone_addr: &SocketAddr,
|
drone_addr: &SocketAddr,
|
||||||
id: &Mint,
|
id: &KeyPair,
|
||||||
tokens: u64,
|
tokens: u64,
|
||||||
) -> Result<(), Box<error::Error>> {
|
) -> Result<(), Box<error::Error>> {
|
||||||
let mut stream = TcpStream::connect(drone_addr)?;
|
let mut stream = TcpStream::connect(drone_addr)?;
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
//! A command-line executable for generating the chain's genesis block.
|
//! A command-line executable for generating the chain's genesis block.
|
||||||
|
|
||||||
extern crate atty;
|
extern crate atty;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate clap;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate solana;
|
extern crate solana;
|
||||||
|
|
||||||
use atty::{is, Stream};
|
use atty::{is, Stream};
|
||||||
|
use clap::{App, Arg};
|
||||||
use solana::entry_writer::EntryWriter;
|
use solana::entry_writer::EntryWriter;
|
||||||
use solana::mint::Mint;
|
use solana::mint::Mint;
|
||||||
use std::error;
|
use std::error;
|
||||||
|
@ -12,6 +15,21 @@ use std::io::{stdin, stdout, Read};
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<error::Error>> {
|
fn main() -> Result<(), Box<error::Error>> {
|
||||||
|
let matches = App::new("solana-genesis")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("tokens")
|
||||||
|
.short("t")
|
||||||
|
.long("tokens")
|
||||||
|
.value_name("NUMBER")
|
||||||
|
.takes_value(true)
|
||||||
|
.required(true)
|
||||||
|
.default_value("0")
|
||||||
|
.help("Number of tokens with which to initialize mint"),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
let tokens = value_t_or_exit!(matches, "tokens", i64);
|
||||||
|
|
||||||
if is(Stream::Stdin) {
|
if is(Stream::Stdin) {
|
||||||
eprintln!("nothing found on stdin, expected a json file");
|
eprintln!("nothing found on stdin, expected a json file");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -24,7 +42,9 @@ fn main() -> Result<(), Box<error::Error>> {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mint: Mint = serde_json::from_str(&buffer)?;
|
let pkcs8: Vec<u8> = serde_json::from_str(&buffer)?;
|
||||||
|
let mint = Mint::new_with_pkcs8(tokens, pkcs8);
|
||||||
|
|
||||||
let mut writer = stdout();
|
let mut writer = stdout();
|
||||||
EntryWriter::write_entries(&mut writer, mint.create_entries())?;
|
EntryWriter::write_entries(&mut writer, mint.create_entries())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
15
src/mint.rs
15
src/mint.rs
|
@ -15,11 +15,7 @@ pub struct Mint {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mint {
|
impl Mint {
|
||||||
pub fn new(tokens: i64) -> Self {
|
pub fn new_with_pkcs8(tokens: i64, pkcs8: Vec<u8>) -> Self {
|
||||||
let rnd = SystemRandom::new();
|
|
||||||
let pkcs8 = KeyPair::generate_pkcs8(&rnd)
|
|
||||||
.expect("generate_pkcs8 in mint pub fn new")
|
|
||||||
.to_vec();
|
|
||||||
let keypair =
|
let keypair =
|
||||||
KeyPair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in mint pub fn new");
|
KeyPair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in mint pub fn new");
|
||||||
let pubkey = keypair.pubkey();
|
let pubkey = keypair.pubkey();
|
||||||
|
@ -29,6 +25,15 @@ impl Mint {
|
||||||
tokens,
|
tokens,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new(tokens: i64) -> Self {
|
||||||
|
let rnd = SystemRandom::new();
|
||||||
|
let pkcs8 = KeyPair::generate_pkcs8(&rnd)
|
||||||
|
.expect("generate_pkcs8 in mint pub fn new")
|
||||||
|
.to_vec();
|
||||||
|
Self::new_with_pkcs8(tokens, pkcs8)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn seed(&self) -> Hash {
|
pub fn seed(&self) -> Hash {
|
||||||
hash(&self.pkcs8)
|
hash(&self.pkcs8)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,11 @@ use ring::error::Unspecified;
|
||||||
use ring::rand::SecureRandom;
|
use ring::rand::SecureRandom;
|
||||||
use ring::signature::Ed25519KeyPair;
|
use ring::signature::Ed25519KeyPair;
|
||||||
use ring::{rand, signature};
|
use ring::{rand, signature};
|
||||||
|
use serde_json;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use untrusted;
|
use std::error;
|
||||||
|
use std::fs::File;
|
||||||
|
use untrusted::Input;
|
||||||
|
|
||||||
pub type KeyPair = Ed25519KeyPair;
|
pub type KeyPair = Ed25519KeyPair;
|
||||||
pub type PublicKey = GenericArray<u8, U32>;
|
pub type PublicKey = GenericArray<u8, U32>;
|
||||||
|
@ -24,10 +27,8 @@ impl KeyPairUtil for Ed25519KeyPair {
|
||||||
/// Return a new ED25519 keypair
|
/// Return a new ED25519 keypair
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let rng = rand::SystemRandom::new();
|
let rng = rand::SystemRandom::new();
|
||||||
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)
|
let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rng).expect("generate_pkcs8");
|
||||||
.expect("generate_pkcs8 in signature pb fn new");
|
Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8_bytes)).expect("from_pcks8")
|
||||||
signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes))
|
|
||||||
.expect("from_pcks8 in signature pb fn new")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the public key for the given keypair
|
/// Return the public key for the given keypair
|
||||||
|
@ -42,9 +43,9 @@ pub trait SignatureUtil {
|
||||||
|
|
||||||
impl SignatureUtil for GenericArray<u8, U64> {
|
impl SignatureUtil for GenericArray<u8, U64> {
|
||||||
fn verify(&self, peer_public_key_bytes: &[u8], msg_bytes: &[u8]) -> bool {
|
fn verify(&self, peer_public_key_bytes: &[u8], msg_bytes: &[u8]) -> bool {
|
||||||
let peer_public_key = untrusted::Input::from(peer_public_key_bytes);
|
let peer_public_key = Input::from(peer_public_key_bytes);
|
||||||
let msg = untrusted::Input::from(msg_bytes);
|
let msg = Input::from(msg_bytes);
|
||||||
let sig = untrusted::Input::from(self);
|
let sig = Input::from(self);
|
||||||
signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok()
|
signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,7 @@ impl GenKeys {
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|seed| {
|
.map(|seed| {
|
||||||
let pkcs8 = GenKeys::new(seed).new_key();
|
let pkcs8 = GenKeys::new(seed).new_key();
|
||||||
KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8)).unwrap()
|
KeyPair::from_pkcs8(Input::from(&pkcs8)).unwrap()
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -91,6 +92,13 @@ impl SecureRandom for GenKeys {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_keypair(path: &str) -> Result<KeyPair, Box<error::Error>> {
|
||||||
|
let file = File::open(path.to_string())?;
|
||||||
|
let pkcs8: Vec<u8> = serde_json::from_reader(file)?;
|
||||||
|
let keypair = Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8))?;
|
||||||
|
Ok(keypair)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Reference in New Issue