Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
f83694f8e5 | |||
ae3d0010a3 | |||
dcffbab82e | |||
98bae5ea98 | |||
fa26cc05c3 | |||
e480e5444d | |||
cf9e6c9ab7 | |||
0a5c54a0ef | |||
7f7a868234 | |||
421ad7a0a1 | |||
139c490d1d | |||
8a873365bc | |||
fc2f922e15 | |||
4279847efd | |||
bced640541 | |||
21e8bbf955 | |||
a7c6067e59 | |||
e1475ca74b | |||
fd48ac1896 | |||
2892c36d47 | |||
c2bd971696 | |||
f324099c30 | |||
d30326ac5a | |||
0cb99e8ab8 | |||
f82f620c7e | |||
beb8e89bf4 | |||
54ff4529b1 | |||
0942cbd89b | |||
88bbaf7add | |||
d1447b5e52 | |||
c00bb42ecd | |||
1a0003fbcc | |||
a584ce6472 | |||
63d1f029a9 | |||
24ebf70016 | |||
d18dc94209 | |||
8242fd19eb | |||
469e91cd8d | |||
4889c2a29c | |||
3c6115c94a | |||
70b15317a9 | |||
a834e9ae10 |
@ -1,4 +1,3 @@
|
|||||||
os: Visual Studio 2017
|
|
||||||
version: '{build}'
|
version: '{build}'
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
@ -16,7 +15,7 @@ build_script:
|
|||||||
notifications:
|
notifications:
|
||||||
- provider: Slack
|
- provider: Slack
|
||||||
incoming_webhook:
|
incoming_webhook:
|
||||||
secure: 6HnLbeS6/Iv7JSMrrHQ7V9OSIjH/3KFzvZiinNWgQqEN0e9A6zaE4MwEXUYDWbcvVJiQneWit6dswY8Scoms2rS1PWEN5N6sjgLgyzroptc=
|
secure: GJsBey+F5apAtUm86MHVJ68Uqa6WN1SImcuIc4TsTZrDhA8K1QWUNw9FFQPybUWDyOcS5dly3kubnUqlGt9ux6Ad2efsfRIQYWv0tOVXKeY=
|
||||||
channel: ci-status
|
channel: ci-status
|
||||||
on_build_success: false
|
on_build_success: false
|
||||||
on_build_failure: true
|
on_build_failure: true
|
||||||
@ -25,16 +24,16 @@ notifications:
|
|||||||
deploy:
|
deploy:
|
||||||
- provider: S3
|
- provider: S3
|
||||||
access_key_id:
|
access_key_id:
|
||||||
secure: G6uzyGqbkMCXS2+sCeBCT/+s/11AHLWXCuGayfKcMEE=
|
secure: fTbJl6JpFebR40J7cOWZ2mXBa3kIvEiXgzxAj6L3N7A=
|
||||||
secret_access_key:
|
secret_access_key:
|
||||||
secure: Lc+aVrbcPSXoDV7h2J7gqKT+HX0n3eEzp3JIrSP2pcKxbAikGnCtOogCiHO9/er2
|
secure: vItsBXb2rEFLvkWtVn/Rcxu5a5+2EwC+b7GsA0waJy9hXh6XuBAD0lnHd9re3g/4
|
||||||
bucket: release.solana.com
|
bucket: release.solana.com
|
||||||
region: us-west-1
|
region: us-west-1
|
||||||
set_public: true
|
set_public: true
|
||||||
|
|
||||||
- provider: GitHub
|
- provider: GitHub
|
||||||
auth_token:
|
auth_token:
|
||||||
secure: JdggY+mrznklWDcV0yvetHhD9eRcNdc627q6NcZdZAJsDidYcGgZ/tgYJiXb9D1A
|
secure: 81fEmPZ0cV1wLtNuUrcmtgxKF6ROQF1+/ft5m+fHX21z6PoeCbaNo8cTyLioWBj7
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
on:
|
on:
|
||||||
|
@ -10,7 +10,13 @@
|
|||||||
set -e
|
set -e
|
||||||
cd "$(dirname "$0")"/..
|
cd "$(dirname "$0")"/..
|
||||||
|
|
||||||
buildkite-agent pipeline upload ci/buildkite.yml
|
if [[ -n $BUILDKITE_TAG ]]; then
|
||||||
|
buildkite-agent annotate --style info --context release-tag \
|
||||||
|
"https://github.com/solana-labs/solana/releases/$BUILDKITE_TAG"
|
||||||
|
buildkite-agent pipeline upload ci/buildkite-release.yml
|
||||||
|
else
|
||||||
|
buildkite-agent pipeline upload ci/buildkite.yml
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $BUILDKITE_BRANCH =~ ^pull ]]; then
|
if [[ $BUILDKITE_BRANCH =~ ^pull ]]; then
|
||||||
# Add helpful link back to the corresponding Github Pull Request
|
# Add helpful link back to the corresponding Github Pull Request
|
||||||
|
1021
Cargo.lock
generated
1021
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -3,13 +3,13 @@ members = [
|
|||||||
"bench-exchange",
|
"bench-exchange",
|
||||||
"bench-streamer",
|
"bench-streamer",
|
||||||
"bench-tps",
|
"bench-tps",
|
||||||
"sdk-c",
|
|
||||||
"chacha-sys",
|
"chacha-sys",
|
||||||
"client",
|
"client",
|
||||||
"core",
|
"core",
|
||||||
"drone",
|
"drone",
|
||||||
"validator",
|
"validator",
|
||||||
"genesis",
|
"genesis",
|
||||||
|
"genesis_programs",
|
||||||
"gossip",
|
"gossip",
|
||||||
"install",
|
"install",
|
||||||
"keygen",
|
"keygen",
|
||||||
@ -32,6 +32,7 @@ members = [
|
|||||||
"programs/failure_program",
|
"programs/failure_program",
|
||||||
"programs/move_loader_api",
|
"programs/move_loader_api",
|
||||||
"programs/move_loader_program",
|
"programs/move_loader_program",
|
||||||
|
"programs/librapay_api",
|
||||||
"programs/noop_program",
|
"programs/noop_program",
|
||||||
"programs/stake_api",
|
"programs/stake_api",
|
||||||
"programs/stake_program",
|
"programs/stake_program",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-bench-exchange"
|
name = "solana-bench-exchange"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
@ -24,16 +24,16 @@ serde_derive = "1.0.97"
|
|||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
serde_yaml = "0.8.9"
|
serde_yaml = "0.8.9"
|
||||||
# solana-runtime = { path = "../solana/runtime"}
|
# solana-runtime = { path = "../solana/runtime"}
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-client = { path = "../client", version = "0.17.0" }
|
solana-client = { path = "../client", version = "0.17.2" }
|
||||||
solana-drone = { path = "../drone", version = "0.17.0" }
|
solana-drone = { path = "../drone", version = "0.17.2" }
|
||||||
solana-exchange-api = { path = "../programs/exchange_api", version = "0.17.0" }
|
solana-exchange-api = { path = "../programs/exchange_api", version = "0.17.2" }
|
||||||
solana-exchange-program = { path = "../programs/exchange_program", version = "0.17.0" }
|
solana-exchange-program = { path = "../programs/exchange_program", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../metrics", version = "0.17.0" }
|
solana-metrics = { path = "../metrics", version = "0.17.2" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
solana-runtime = { path = "../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../runtime", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
untrusted = "0.7.0"
|
untrusted = "0.7.0"
|
||||||
ws = "0.8.1"
|
ws = "0.8.1"
|
||||||
|
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-bench-streamer"
|
name = "solana-bench-streamer"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
cuda = ["solana/cuda"]
|
cuda = ["solana/cuda"]
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-bench-tps"
|
name = "solana-bench-tps"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bincode = "1.1.4"
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
rayon = "1.1.0"
|
rayon = "1.1.0"
|
||||||
@ -15,14 +16,18 @@ serde = "1.0.97"
|
|||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
serde_yaml = "0.8.9"
|
serde_yaml = "0.8.9"
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-client = { path = "../client", version = "0.17.0" }
|
solana-client = { path = "../client", version = "0.17.2" }
|
||||||
solana-drone = { path = "../drone", version = "0.17.0" }
|
solana-drone = { path = "../drone", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-librapay-api = { path = "../programs/librapay_api", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../metrics", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-metrics = { path = "../metrics", version = "0.17.2" }
|
||||||
solana-runtime = { path = "../runtime", version = "0.17.0" }
|
solana-measure = { path = "../measure", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
|
solana-runtime = { path = "../runtime", version = "0.17.2" }
|
||||||
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
solana-move-loader-program = { path = "../programs/move_loader_program", version = "0.17.2" }
|
||||||
|
solana-move-loader-api = { path = "../programs/move_loader_api", version = "0.17.2" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
cuda = ["solana/cuda"]
|
cuda = ["solana/cuda"]
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
use solana_metrics;
|
use solana_metrics;
|
||||||
|
|
||||||
|
use bincode;
|
||||||
use log::*;
|
use log::*;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use solana::gen_keys::GenKeys;
|
use solana::gen_keys::GenKeys;
|
||||||
use solana_client::perf_utils::{sample_txs, SampleStats};
|
use solana_client::perf_utils::{sample_txs, SampleStats};
|
||||||
use solana_drone::drone::request_airdrop_transaction;
|
use solana_drone::drone::request_airdrop_transaction;
|
||||||
|
use solana_librapay_api::{create_genesis, upload_mint_program, upload_payment_program};
|
||||||
|
use solana_measure::measure::Measure;
|
||||||
use solana_metrics::datapoint_info;
|
use solana_metrics::datapoint_info;
|
||||||
use solana_sdk::client::Client;
|
use solana_sdk::client::Client;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::hash::Hash;
|
||||||
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_instruction;
|
use solana_sdk::system_instruction;
|
||||||
use solana_sdk::system_transaction;
|
use solana_sdk::system_transaction;
|
||||||
@ -24,6 +28,8 @@ use std::thread::Builder;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use solana_librapay_api::librapay_transaction;
|
||||||
|
|
||||||
pub const MAX_SPENDS_PER_TX: u64 = 4;
|
pub const MAX_SPENDS_PER_TX: u64 = 4;
|
||||||
pub const NUM_LAMPORTS_PER_ACCOUNT: u64 = 128;
|
pub const NUM_LAMPORTS_PER_ACCOUNT: u64 = 128;
|
||||||
|
|
||||||
@ -43,6 +49,7 @@ pub struct Config {
|
|||||||
pub duration: Duration,
|
pub duration: Duration,
|
||||||
pub tx_count: usize,
|
pub tx_count: usize,
|
||||||
pub sustained: bool,
|
pub sustained: bool,
|
||||||
|
pub use_move: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -54,15 +61,19 @@ impl Default for Config {
|
|||||||
duration: Duration::new(std::u64::MAX, 0),
|
duration: Duration::new(std::u64::MAX, 0),
|
||||||
tx_count: 500_000,
|
tx_count: 500_000,
|
||||||
sustained: false,
|
sustained: false,
|
||||||
|
use_move: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LibraKeys = (Keypair, Pubkey, Pubkey, Vec<Keypair>);
|
||||||
|
|
||||||
pub fn do_bench_tps<T>(
|
pub fn do_bench_tps<T>(
|
||||||
clients: Vec<T>,
|
clients: Vec<T>,
|
||||||
config: Config,
|
config: Config,
|
||||||
gen_keypairs: Vec<Keypair>,
|
gen_keypairs: Vec<Keypair>,
|
||||||
keypair0_balance: u64,
|
keypair0_balance: u64,
|
||||||
|
libra_args: Option<LibraKeys>,
|
||||||
) -> u64
|
) -> u64
|
||||||
where
|
where
|
||||||
T: 'static + Client + Send + Sync,
|
T: 'static + Client + Send + Sync,
|
||||||
@ -74,6 +85,7 @@ where
|
|||||||
duration,
|
duration,
|
||||||
tx_count,
|
tx_count,
|
||||||
sustained,
|
sustained,
|
||||||
|
..
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
let clients: Vec<_> = clients.into_iter().map(Arc::new).collect();
|
let clients: Vec<_> = clients.into_iter().map(Arc::new).collect();
|
||||||
@ -165,6 +177,7 @@ where
|
|||||||
&keypairs[len..],
|
&keypairs[len..],
|
||||||
threads,
|
threads,
|
||||||
reclaim_lamports_back_to_source_account,
|
reclaim_lamports_back_to_source_account,
|
||||||
|
&libra_args,
|
||||||
);
|
);
|
||||||
// In sustained mode overlap the transfers with generation
|
// In sustained mode overlap the transfers with generation
|
||||||
// this has higher average performance but lower peak performance
|
// this has higher average performance but lower peak performance
|
||||||
@ -221,6 +234,74 @@ fn metrics_submit_lamport_balance(lamport_balance: u64) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_move_txs(
|
||||||
|
source: &[Keypair],
|
||||||
|
dest: &[Keypair],
|
||||||
|
reclaim: bool,
|
||||||
|
move_keypairs: &[Keypair],
|
||||||
|
libra_pay_program_id: &Pubkey,
|
||||||
|
libra_mint_id: &Pubkey,
|
||||||
|
blockhash: &Hash,
|
||||||
|
) -> Vec<(Transaction, u64)> {
|
||||||
|
let count = move_keypairs.len() / 2;
|
||||||
|
let source_move = &move_keypairs[..count];
|
||||||
|
let dest_move = &move_keypairs[count..];
|
||||||
|
let pairs: Vec<_> = if !reclaim {
|
||||||
|
source_move
|
||||||
|
.iter()
|
||||||
|
.zip(dest_move.iter())
|
||||||
|
.zip(source.iter())
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
dest_move
|
||||||
|
.iter()
|
||||||
|
.zip(source_move.iter())
|
||||||
|
.zip(dest.iter())
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
pairs
|
||||||
|
.par_iter()
|
||||||
|
.map(|((from, to), payer)| {
|
||||||
|
(
|
||||||
|
librapay_transaction::transfer(
|
||||||
|
libra_pay_program_id,
|
||||||
|
libra_mint_id,
|
||||||
|
&payer,
|
||||||
|
&from,
|
||||||
|
&to.pubkey(),
|
||||||
|
1,
|
||||||
|
*blockhash,
|
||||||
|
),
|
||||||
|
timestamp(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_system_txs(
|
||||||
|
source: &[Keypair],
|
||||||
|
dest: &[Keypair],
|
||||||
|
reclaim: bool,
|
||||||
|
blockhash: &Hash,
|
||||||
|
) -> Vec<(Transaction, u64)> {
|
||||||
|
let pairs: Vec<_> = if !reclaim {
|
||||||
|
source.iter().zip(dest.iter()).collect()
|
||||||
|
} else {
|
||||||
|
dest.iter().zip(source.iter()).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
pairs
|
||||||
|
.par_iter()
|
||||||
|
.map(|(from, to)| {
|
||||||
|
(
|
||||||
|
system_transaction::create_user_account(from, &to.pubkey(), 1, *blockhash),
|
||||||
|
timestamp(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_txs(
|
fn generate_txs(
|
||||||
shared_txs: &SharedTransactions,
|
shared_txs: &SharedTransactions,
|
||||||
blockhash: &Hash,
|
blockhash: &Hash,
|
||||||
@ -228,25 +309,31 @@ fn generate_txs(
|
|||||||
dest: &[Keypair],
|
dest: &[Keypair],
|
||||||
threads: usize,
|
threads: usize,
|
||||||
reclaim: bool,
|
reclaim: bool,
|
||||||
|
libra_args: &Option<LibraKeys>,
|
||||||
) {
|
) {
|
||||||
let tx_count = source.len();
|
let tx_count = source.len();
|
||||||
println!("Signing transactions... {} (reclaim={})", tx_count, reclaim);
|
println!("Signing transactions... {} (reclaim={})", tx_count, reclaim);
|
||||||
let signing_start = Instant::now();
|
let signing_start = Instant::now();
|
||||||
|
|
||||||
let pairs: Vec<_> = if !reclaim {
|
let transactions = if let Some((
|
||||||
source.iter().zip(dest.iter()).collect()
|
libra_genesis_keypair,
|
||||||
|
libra_pay_program_id,
|
||||||
|
_libra_mint_program_id,
|
||||||
|
libra_keys,
|
||||||
|
)) = libra_args
|
||||||
|
{
|
||||||
|
generate_move_txs(
|
||||||
|
source,
|
||||||
|
dest,
|
||||||
|
reclaim,
|
||||||
|
&libra_keys,
|
||||||
|
libra_pay_program_id,
|
||||||
|
&libra_genesis_keypair.pubkey(),
|
||||||
|
blockhash,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
dest.iter().zip(source.iter()).collect()
|
generate_system_txs(source, dest, reclaim, blockhash)
|
||||||
};
|
};
|
||||||
let transactions: Vec<_> = pairs
|
|
||||||
.par_iter()
|
|
||||||
.map(|(id, keypair)| {
|
|
||||||
(
|
|
||||||
system_transaction::create_user_account(id, &keypair.pubkey(), 1, *blockhash),
|
|
||||||
timestamp(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let duration = signing_start.elapsed();
|
let duration = signing_start.elapsed();
|
||||||
let ns = duration.as_secs() * 1_000_000_000 + u64::from(duration.subsec_nanos());
|
let ns = duration.as_secs() * 1_000_000_000 + u64::from(duration.subsec_nanos());
|
||||||
@ -392,13 +479,10 @@ pub fn fund_keys<T: Client>(
|
|||||||
let mut to_fund_txs: Vec<_> = chunk
|
let mut to_fund_txs: Vec<_> = chunk
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(k, m)| {
|
.map(|(k, m)| {
|
||||||
(
|
let tx = Transaction::new_unsigned_instructions(
|
||||||
k.clone(),
|
system_instruction::transfer_many(&k.pubkey(), &m),
|
||||||
Transaction::new_unsigned_instructions(system_instruction::transfer_many(
|
);
|
||||||
&k.pubkey(),
|
(k.clone(), tx)
|
||||||
&m,
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -602,15 +686,156 @@ pub fn generate_keypairs(seed_keypair: &Keypair, count: u64) -> (Vec<Keypair>, u
|
|||||||
(rnd.gen_n_keypairs(total_keys), extra)
|
(rnd.gen_n_keypairs(total_keys), extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fund_move_keys<T: Client>(
|
||||||
|
client: &T,
|
||||||
|
funding_key: &Keypair,
|
||||||
|
keypairs: &[Keypair],
|
||||||
|
total: u64,
|
||||||
|
libra_pay_program_id: &Pubkey,
|
||||||
|
libra_mint_program_id: &Pubkey,
|
||||||
|
libra_mint_key: &Keypair,
|
||||||
|
) {
|
||||||
|
let (mut blockhash, _fee_calculator) = client.get_recent_blockhash().unwrap();
|
||||||
|
|
||||||
|
info!("creating the libra funding account..");
|
||||||
|
let libra_funding_key = Keypair::new();
|
||||||
|
let tx = librapay_transaction::create_account(
|
||||||
|
funding_key,
|
||||||
|
&libra_funding_key.pubkey(),
|
||||||
|
1,
|
||||||
|
blockhash,
|
||||||
|
);
|
||||||
|
let sig = client
|
||||||
|
.async_send_transaction(tx)
|
||||||
|
.expect("create_account in generate_and_fund_keypairs");
|
||||||
|
client.poll_for_signature(&sig).unwrap();
|
||||||
|
|
||||||
|
info!("minting to funding keypair");
|
||||||
|
let tx = librapay_transaction::mint_tokens(
|
||||||
|
&libra_mint_program_id,
|
||||||
|
funding_key,
|
||||||
|
libra_mint_key,
|
||||||
|
&libra_funding_key.pubkey(),
|
||||||
|
total,
|
||||||
|
blockhash,
|
||||||
|
);
|
||||||
|
let sig = client
|
||||||
|
.async_send_transaction(tx)
|
||||||
|
.expect("create_account in generate_and_fund_keypairs");
|
||||||
|
client.poll_for_signature(&sig).unwrap();
|
||||||
|
|
||||||
|
info!("creating move accounts.. {}", keypairs.len());
|
||||||
|
let create_len = 8;
|
||||||
|
let mut funding_time = Measure::start("funding_time");
|
||||||
|
for (i, keys) in keypairs.chunks(create_len).enumerate() {
|
||||||
|
if client.get_balance(&keys[0].pubkey()).unwrap_or(0) > 0 {
|
||||||
|
// already created these accounts.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tx_send = Measure::start("poll");
|
||||||
|
|
||||||
|
let pubkeys: Vec<_> = keys.iter().map(|k| k.pubkey()).collect();
|
||||||
|
let tx = librapay_transaction::create_accounts(funding_key, &pubkeys, 1, blockhash);
|
||||||
|
let ser_size = bincode::serialized_size(&tx).unwrap();
|
||||||
|
let sig = client
|
||||||
|
.async_send_transaction(tx)
|
||||||
|
.expect("create_account in generate_and_fund_keypairs");
|
||||||
|
tx_send.stop();
|
||||||
|
let mut poll = Measure::start("poll");
|
||||||
|
client.poll_for_signature(&sig).unwrap();
|
||||||
|
poll.stop();
|
||||||
|
if i % 10 == 0 {
|
||||||
|
blockhash = client.get_recent_blockhash().unwrap().0;
|
||||||
|
info!(
|
||||||
|
"size: {} created {} accounts of {} sig: {}us send: {}us",
|
||||||
|
ser_size,
|
||||||
|
i,
|
||||||
|
(keypairs.len() / create_len),
|
||||||
|
poll.as_us(),
|
||||||
|
tx_send.as_us()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
funding_time.stop();
|
||||||
|
info!("funding accounts {}ms", funding_time.as_ms());
|
||||||
|
let mut sigs = vec![];
|
||||||
|
let tx_count = keypairs.len();
|
||||||
|
let amount = total / (tx_count as u64);
|
||||||
|
for (i, key) in keypairs[..tx_count].iter().enumerate() {
|
||||||
|
let tx = librapay_transaction::transfer(
|
||||||
|
libra_pay_program_id,
|
||||||
|
&libra_mint_key.pubkey(),
|
||||||
|
funding_key,
|
||||||
|
&libra_funding_key,
|
||||||
|
&key.pubkey(),
|
||||||
|
amount,
|
||||||
|
blockhash,
|
||||||
|
);
|
||||||
|
|
||||||
|
let sig = client
|
||||||
|
.async_send_transaction(tx.clone())
|
||||||
|
.expect("create_account in generate_and_fund_keypairs");
|
||||||
|
|
||||||
|
let mut poll_time = Measure::start("poll_start");
|
||||||
|
let poll_status = client.poll_for_signature(&sig);
|
||||||
|
poll_time.stop();
|
||||||
|
info!(
|
||||||
|
"i: {} poll: {:?} time: {}ms",
|
||||||
|
i,
|
||||||
|
poll_status,
|
||||||
|
poll_time.as_ms()
|
||||||
|
);
|
||||||
|
|
||||||
|
sigs.push((sig, key));
|
||||||
|
|
||||||
|
if i % 50 == 0 {
|
||||||
|
blockhash = client.get_recent_blockhash().unwrap().0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, (sig, key)) in sigs.iter().enumerate() {
|
||||||
|
let mut times = 0;
|
||||||
|
loop {
|
||||||
|
match client.poll_for_signature(&sig) {
|
||||||
|
Ok(_) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
info!("e :{:?} waiting times: {} sig: {}", e, times, sig);
|
||||||
|
times += 1;
|
||||||
|
sleep(Duration::from_secs(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
times = 0;
|
||||||
|
loop {
|
||||||
|
let balance = librapay_transaction::get_libra_balance(client, &key.pubkey()).unwrap();
|
||||||
|
if balance < amount {
|
||||||
|
info!("i: {} balance: {} times: {}", i, balance, times);
|
||||||
|
times += 1;
|
||||||
|
sleep(Duration::from_secs(1));
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i % 10 == 0 {
|
||||||
|
info!("funding {} of {}", i, tx_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info!("done..");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_and_fund_keypairs<T: Client>(
|
pub fn generate_and_fund_keypairs<T: Client>(
|
||||||
client: &T,
|
client: &T,
|
||||||
drone_addr: Option<SocketAddr>,
|
drone_addr: Option<SocketAddr>,
|
||||||
funding_pubkey: &Keypair,
|
funding_key: &Keypair,
|
||||||
tx_count: usize,
|
tx_count: usize,
|
||||||
lamports_per_account: u64,
|
lamports_per_account: u64,
|
||||||
) -> Result<(Vec<Keypair>, u64)> {
|
use_move: bool,
|
||||||
|
) -> Result<(Vec<Keypair>, Option<LibraKeys>, u64)> {
|
||||||
info!("Creating {} keypairs...", tx_count * 2);
|
info!("Creating {} keypairs...", tx_count * 2);
|
||||||
let (mut keypairs, extra) = generate_keypairs(funding_pubkey, tx_count as u64 * 2);
|
let (mut keypairs, extra) = generate_keypairs(funding_key, tx_count as u64 * 2);
|
||||||
info!("Get lamports...");
|
info!("Get lamports...");
|
||||||
|
|
||||||
// Sample the first keypair, see if it has lamports, if so then resume.
|
// Sample the first keypair, see if it has lamports, if so then resume.
|
||||||
@ -619,19 +844,60 @@ pub fn generate_and_fund_keypairs<T: Client>(
|
|||||||
.get_balance(&keypairs[tx_count * 2 - 1].pubkey())
|
.get_balance(&keypairs[tx_count * 2 - 1].pubkey())
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let mut move_keypairs_ret = None;
|
||||||
|
|
||||||
if lamports_per_account > last_keypair_balance {
|
if lamports_per_account > last_keypair_balance {
|
||||||
let (_, fee_calculator) = client.get_recent_blockhash().unwrap();
|
let (_blockhash, fee_calculator) = client.get_recent_blockhash().unwrap();
|
||||||
let account_desired_balance =
|
let account_desired_balance =
|
||||||
lamports_per_account - last_keypair_balance + fee_calculator.max_lamports_per_signature;
|
lamports_per_account - last_keypair_balance + fee_calculator.max_lamports_per_signature;
|
||||||
let extra_fees = extra * fee_calculator.max_lamports_per_signature;
|
let extra_fees = extra * fee_calculator.max_lamports_per_signature;
|
||||||
let total = account_desired_balance * (1 + keypairs.len() as u64) + extra_fees;
|
let mut total = account_desired_balance * (1 + keypairs.len() as u64) + extra_fees;
|
||||||
if client.get_balance(&funding_pubkey.pubkey()).unwrap_or(0) < total {
|
if use_move {
|
||||||
airdrop_lamports(client, &drone_addr.unwrap(), funding_pubkey, total)?;
|
total *= 2;
|
||||||
}
|
}
|
||||||
info!("adding more lamports {}", account_desired_balance);
|
|
||||||
|
println!("Previous key balance: {} max_fee: {} lamports_per_account: {} extra: {} desired_balance: {} total: {}",
|
||||||
|
last_keypair_balance, fee_calculator.max_lamports_per_signature, lamports_per_account, extra,
|
||||||
|
account_desired_balance, total
|
||||||
|
);
|
||||||
|
|
||||||
|
if client.get_balance(&funding_key.pubkey()).unwrap_or(0) < total {
|
||||||
|
airdrop_lamports(client, &drone_addr.unwrap(), funding_key, total)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if use_move {
|
||||||
|
let libra_genesis_keypair = create_genesis(&funding_key, client, 1_000_000);
|
||||||
|
let libra_mint_program_id = upload_mint_program(&funding_key, client);
|
||||||
|
let libra_pay_program_id = upload_payment_program(&funding_key, client);
|
||||||
|
|
||||||
|
// Generate another set of keypairs for move accounts.
|
||||||
|
// Still fund the solana ones which will be used for fees.
|
||||||
|
let seed = [0u8; 32];
|
||||||
|
let mut rnd = GenKeys::new(seed);
|
||||||
|
let move_keypairs = rnd.gen_n_keypairs(tx_count as u64 * 2);
|
||||||
|
fund_move_keys(
|
||||||
|
client,
|
||||||
|
funding_key,
|
||||||
|
&move_keypairs,
|
||||||
|
total / 2,
|
||||||
|
&libra_pay_program_id,
|
||||||
|
&libra_mint_program_id,
|
||||||
|
&libra_genesis_keypair,
|
||||||
|
);
|
||||||
|
move_keypairs_ret = Some((
|
||||||
|
libra_genesis_keypair,
|
||||||
|
libra_pay_program_id,
|
||||||
|
libra_mint_program_id,
|
||||||
|
move_keypairs,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Give solana keys half and move keys half the lamports.
|
||||||
|
total /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
fund_keys(
|
fund_keys(
|
||||||
client,
|
client,
|
||||||
funding_pubkey,
|
funding_key,
|
||||||
&keypairs,
|
&keypairs,
|
||||||
total,
|
total,
|
||||||
fee_calculator.max_lamports_per_signature,
|
fee_calculator.max_lamports_per_signature,
|
||||||
@ -642,11 +908,12 @@ pub fn generate_and_fund_keypairs<T: Client>(
|
|||||||
// 'generate_keypairs' generates extra keys to be able to have size-aligned funding batches for fund_keys.
|
// 'generate_keypairs' generates extra keys to be able to have size-aligned funding batches for fund_keys.
|
||||||
keypairs.truncate(2 * tx_count);
|
keypairs.truncate(2 * tx_count);
|
||||||
|
|
||||||
Ok((keypairs, last_keypair_balance))
|
Ok((keypairs, move_keypairs_ret, last_keypair_balance))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use solana::cluster_info::FULLNODE_PORT_RANGE;
|
use solana::cluster_info::FULLNODE_PORT_RANGE;
|
||||||
use solana::local_cluster::{ClusterConfig, LocalCluster};
|
use solana::local_cluster::{ClusterConfig, LocalCluster};
|
||||||
@ -675,47 +942,68 @@ mod tests {
|
|||||||
assert_eq!(should_switch_directions(20, 101), false);
|
assert_eq!(should_switch_directions(20, 101), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn test_bench_tps_local_cluster(config: Config) {
|
||||||
fn test_bench_tps_local_cluster() {
|
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
const NUM_NODES: usize = 1;
|
const NUM_NODES: usize = 1;
|
||||||
let cluster = LocalCluster::new(&ClusterConfig {
|
let cluster = LocalCluster::new(&ClusterConfig {
|
||||||
node_stakes: vec![999_990; NUM_NODES],
|
node_stakes: vec![999_990; NUM_NODES],
|
||||||
cluster_lamports: 2_000_000,
|
cluster_lamports: 200_000_000,
|
||||||
validator_configs: vec![ValidatorConfig::default(); NUM_NODES],
|
validator_configs: vec![ValidatorConfig::default(); NUM_NODES],
|
||||||
|
native_instruction_processors: vec![solana_move_loader_program!()],
|
||||||
..ClusterConfig::default()
|
..ClusterConfig::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
let drone_keypair = Keypair::new();
|
let drone_keypair = Keypair::new();
|
||||||
cluster.transfer(&cluster.funding_keypair, &drone_keypair.pubkey(), 1_000_000);
|
cluster.transfer(
|
||||||
|
&cluster.funding_keypair,
|
||||||
let (addr_sender, addr_receiver) = channel();
|
&drone_keypair.pubkey(),
|
||||||
run_local_drone(drone_keypair, addr_sender, None);
|
100_000_000,
|
||||||
let drone_addr = addr_receiver.recv_timeout(Duration::from_secs(2)).unwrap();
|
);
|
||||||
|
|
||||||
let mut config = Config::default();
|
|
||||||
config.tx_count = 100;
|
|
||||||
config.duration = Duration::from_secs(5);
|
|
||||||
|
|
||||||
let client = create_client(
|
let client = create_client(
|
||||||
(cluster.entry_point_info.rpc, cluster.entry_point_info.tpu),
|
(cluster.entry_point_info.rpc, cluster.entry_point_info.tpu),
|
||||||
FULLNODE_PORT_RANGE,
|
FULLNODE_PORT_RANGE,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let (addr_sender, addr_receiver) = channel();
|
||||||
|
run_local_drone(drone_keypair, addr_sender, None);
|
||||||
|
let drone_addr = addr_receiver.recv_timeout(Duration::from_secs(2)).unwrap();
|
||||||
|
|
||||||
let lamports_per_account = 100;
|
let lamports_per_account = 100;
|
||||||
let (keypairs, _keypair_balance) = generate_and_fund_keypairs(
|
|
||||||
|
let (keypairs, move_keypairs, _keypair_balance) = generate_and_fund_keypairs(
|
||||||
&client,
|
&client,
|
||||||
Some(drone_addr),
|
Some(drone_addr),
|
||||||
&config.id,
|
&config.id,
|
||||||
config.tx_count,
|
config.tx_count,
|
||||||
lamports_per_account,
|
lamports_per_account,
|
||||||
|
config.use_move,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let total = do_bench_tps(vec![client], config, keypairs, 0);
|
let total = do_bench_tps(vec![client], config, keypairs, 0, move_keypairs);
|
||||||
assert!(total > 100);
|
assert!(total > 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bench_tps_local_cluster_solana() {
|
||||||
|
let mut config = Config::default();
|
||||||
|
config.tx_count = 100;
|
||||||
|
config.duration = Duration::from_secs(10);
|
||||||
|
|
||||||
|
test_bench_tps_local_cluster(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bench_tps_local_cluster_move() {
|
||||||
|
let mut config = Config::default();
|
||||||
|
config.tx_count = 100;
|
||||||
|
config.duration = Duration::from_secs(20);
|
||||||
|
config.use_move = true;
|
||||||
|
|
||||||
|
test_bench_tps_local_cluster(config);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bench_tps_bank_client() {
|
fn test_bench_tps_bank_client() {
|
||||||
let (genesis_block, id) = create_genesis_block(10_000);
|
let (genesis_block, id) = create_genesis_block(10_000);
|
||||||
@ -727,10 +1015,11 @@ mod tests {
|
|||||||
config.tx_count = 10;
|
config.tx_count = 10;
|
||||||
config.duration = Duration::from_secs(5);
|
config.duration = Duration::from_secs(5);
|
||||||
|
|
||||||
let (keypairs, _keypair_balance) =
|
let (keypairs, _move_keypairs, _keypair_balance) =
|
||||||
generate_and_fund_keypairs(&clients[0], None, &config.id, config.tx_count, 20).unwrap();
|
generate_and_fund_keypairs(&clients[0], None, &config.id, config.tx_count, 20, false)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
do_bench_tps(clients, config, keypairs, 0);
|
do_bench_tps(clients, config, keypairs, 0, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -741,8 +1030,8 @@ mod tests {
|
|||||||
let tx_count = 10;
|
let tx_count = 10;
|
||||||
let lamports = 20;
|
let lamports = 20;
|
||||||
|
|
||||||
let (keypairs, _keypair_balance) =
|
let (keypairs, _move_keypairs, _keypair_balance) =
|
||||||
generate_and_fund_keypairs(&client, None, &id, tx_count, lamports).unwrap();
|
generate_and_fund_keypairs(&client, None, &id, tx_count, lamports, false).unwrap();
|
||||||
|
|
||||||
for kp in &keypairs {
|
for kp in &keypairs {
|
||||||
assert_eq!(client.get_balance(&kp.pubkey()).unwrap(), lamports);
|
assert_eq!(client.get_balance(&kp.pubkey()).unwrap(), lamports);
|
||||||
@ -759,8 +1048,8 @@ mod tests {
|
|||||||
let tx_count = 10;
|
let tx_count = 10;
|
||||||
let lamports = 20;
|
let lamports = 20;
|
||||||
|
|
||||||
let (keypairs, _keypair_balance) =
|
let (keypairs, _move_keypairs, _keypair_balance) =
|
||||||
generate_and_fund_keypairs(&client, None, &id, tx_count, lamports).unwrap();
|
generate_and_fund_keypairs(&client, None, &id, tx_count, lamports, false).unwrap();
|
||||||
|
|
||||||
let max_fee = client
|
let max_fee = client
|
||||||
.get_recent_blockhash()
|
.get_recent_blockhash()
|
||||||
|
@ -22,6 +22,7 @@ pub struct Config {
|
|||||||
pub write_to_client_file: bool,
|
pub write_to_client_file: bool,
|
||||||
pub read_from_client_file: bool,
|
pub read_from_client_file: bool,
|
||||||
pub target_lamports_per_signature: u64,
|
pub target_lamports_per_signature: u64,
|
||||||
|
pub use_move: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -40,6 +41,7 @@ impl Default for Config {
|
|||||||
write_to_client_file: false,
|
write_to_client_file: false,
|
||||||
read_from_client_file: false,
|
read_from_client_file: false,
|
||||||
target_lamports_per_signature: FeeCalculator::default().target_lamports_per_signature,
|
target_lamports_per_signature: FeeCalculator::default().target_lamports_per_signature,
|
||||||
|
use_move: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,6 +102,11 @@ pub fn build_args<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.long("sustained")
|
.long("sustained")
|
||||||
.help("Use sustained performance mode vs. peak mode. This overlaps the tx generation with transfers."),
|
.help("Use sustained performance mode vs. peak mode. This overlaps the tx generation with transfers."),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("use-move")
|
||||||
|
.long("use-move")
|
||||||
|
.help("Use Move language transactions to perform transfers."),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("tx_count")
|
Arg::with_name("tx_count")
|
||||||
.long("tx_count")
|
.long("tx_count")
|
||||||
@ -211,5 +218,7 @@ pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
|
|||||||
args.target_lamports_per_signature = v.to_string().parse().expect("can't parse lamports");
|
args.target_lamports_per_signature = v.to_string().parse().expect("can't parse lamports");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args.use_move = matches.is_present("use-move");
|
||||||
|
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_move_loader_program;
|
||||||
|
|
||||||
mod bench;
|
mod bench;
|
||||||
mod cli;
|
mod cli;
|
||||||
|
|
||||||
@ -37,6 +41,7 @@ fn main() {
|
|||||||
write_to_client_file,
|
write_to_client_file,
|
||||||
read_from_client_file,
|
read_from_client_file,
|
||||||
target_lamports_per_signature,
|
target_lamports_per_signature,
|
||||||
|
use_move,
|
||||||
} = cli_config;
|
} = cli_config;
|
||||||
|
|
||||||
if write_to_client_file {
|
if write_to_client_file {
|
||||||
@ -78,7 +83,7 @@ fn main() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (keypairs, keypair_balance) = if read_from_client_file {
|
let (keypairs, move_keypairs, keypair_balance) = if read_from_client_file && !use_move {
|
||||||
let path = Path::new(&client_ids_and_stake_file);
|
let path = Path::new(&client_ids_and_stake_file);
|
||||||
let file = File::open(path).unwrap();
|
let file = File::open(path).unwrap();
|
||||||
|
|
||||||
@ -95,7 +100,7 @@ fn main() {
|
|||||||
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
||||||
// across multiple runs.
|
// across multiple runs.
|
||||||
keypairs.sort_by(|x, y| x.pubkey().to_string().cmp(&y.pubkey().to_string()));
|
keypairs.sort_by(|x, y| x.pubkey().to_string().cmp(&y.pubkey().to_string()));
|
||||||
(keypairs, last_balance)
|
(keypairs, None, last_balance)
|
||||||
} else {
|
} else {
|
||||||
generate_and_fund_keypairs(
|
generate_and_fund_keypairs(
|
||||||
&client,
|
&client,
|
||||||
@ -103,6 +108,7 @@ fn main() {
|
|||||||
&id,
|
&id,
|
||||||
tx_count,
|
tx_count,
|
||||||
NUM_LAMPORTS_PER_ACCOUNT,
|
NUM_LAMPORTS_PER_ACCOUNT,
|
||||||
|
use_move,
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
eprintln!("Error could not fund keys: {:?}", e);
|
eprintln!("Error could not fund keys: {:?}", e);
|
||||||
@ -117,7 +123,14 @@ fn main() {
|
|||||||
duration,
|
duration,
|
||||||
tx_count,
|
tx_count,
|
||||||
sustained,
|
sustained,
|
||||||
|
use_move,
|
||||||
};
|
};
|
||||||
|
|
||||||
do_bench_tps(vec![client], config, keypairs, keypair_balance);
|
do_bench_tps(
|
||||||
|
vec![client],
|
||||||
|
config,
|
||||||
|
keypairs,
|
||||||
|
keypair_balance,
|
||||||
|
move_keypairs,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -59,10 +59,8 @@
|
|||||||
- [Economic Design MVP](ed_mvp.md)
|
- [Economic Design MVP](ed_mvp.md)
|
||||||
- [References](ed_references.md)
|
- [References](ed_references.md)
|
||||||
- [Cluster Test Framework](cluster-test-framework.md)
|
- [Cluster Test Framework](cluster-test-framework.md)
|
||||||
- [Credit-only Accounts](credit-only-credit-debit-accounts.md)
|
|
||||||
- [Validator](validator-proposal.md)
|
- [Validator](validator-proposal.md)
|
||||||
- [Simple Payment and State Verification](simple-payment-and-state-verification.md)
|
- [Simple Payment and State Verification](simple-payment-and-state-verification.md)
|
||||||
- [Embedding the Move Langauge](embedding-move.md)
|
|
||||||
- [Cross-Program Invocation](cross-program-invocation.md)
|
- [Cross-Program Invocation](cross-program-invocation.md)
|
||||||
|
|
||||||
- [Implemented Design Proposals](implemented-proposals.md)
|
- [Implemented Design Proposals](implemented-proposals.md)
|
||||||
@ -77,3 +75,5 @@
|
|||||||
- [Reliable Vote Transmission](reliable-vote-transmission.md)
|
- [Reliable Vote Transmission](reliable-vote-transmission.md)
|
||||||
- [Repair Service](repair-service.md)
|
- [Repair Service](repair-service.md)
|
||||||
- [Testing Programs](testing-programs.md)
|
- [Testing Programs](testing-programs.md)
|
||||||
|
- [Credit-only Accounts](credit-only-credit-debit-accounts.md)
|
||||||
|
- [Embedding the Move Langauge](embedding-move.md)
|
||||||
|
@ -130,7 +130,7 @@ FLAGS:
|
|||||||
-V, --version Prints version information
|
-V, --version Prints version information
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-c, --config <PATH> Configuration file to use [default: /Users/mvines/Library/Preferences/solana/install.yml]
|
-c, --config <PATH> Configuration file to use [default: .../Library/Preferences/solana/install.yml]
|
||||||
|
|
||||||
SUBCOMMANDS:
|
SUBCOMMANDS:
|
||||||
deploy deploys a new update
|
deploy deploys a new update
|
||||||
@ -152,7 +152,7 @@ FLAGS:
|
|||||||
-h, --help Prints help information
|
-h, --help Prints help information
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-d, --data_dir <PATH> Directory to store install data [default: /Users/mvines/Library/Application Support/solana]
|
-d, --data_dir <PATH> Directory to store install data [default: .../Library/Application Support/solana]
|
||||||
-u, --url <URL> JSON RPC URL for the solana cluster [default: http://testnet.solana.com:8899]
|
-u, --url <URL> JSON RPC URL for the solana cluster [default: http://testnet.solana.com:8899]
|
||||||
-p, --pubkey <PUBKEY> Public key of the update manifest [default: 9XX329sPuskWhH4DQh6k16c87dHKhXLBZTL3Gxmve8Gp]
|
-p, --pubkey <PUBKEY> Public key of the update manifest [default: 9XX329sPuskWhH4DQh6k16c87dHKhXLBZTL3Gxmve8Gp]
|
||||||
```
|
```
|
||||||
|
@ -74,7 +74,7 @@ The `solana-install` tool can be used to easily install and upgrade the cluster
|
|||||||
software on Linux x86_64 and mac OS systems.
|
software on Linux x86_64 and mac OS systems.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v0.16.5/install/solana-install-init.sh | sh -s
|
$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v0.17.0/install/solana-install-init.sh | sh -s
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively build the `solana-install` program from source and run the
|
Alternatively build the `solana-install` program from source and run the
|
||||||
@ -125,7 +125,7 @@ If building for CUDA (Linux only), fetch the perf-libs first then include the
|
|||||||
`cuda` feature flag when building:
|
`cuda` feature flag when building:
|
||||||
```bash
|
```bash
|
||||||
$ ./fetch-perf-libs.sh
|
$ ./fetch-perf-libs.sh
|
||||||
$ source /home/mvines/ws/solana/target/perf-libs/env.sh
|
$ source ./target/perf-libs/env.sh
|
||||||
$ ./scripts/cargo-install-all.sh . cuda
|
$ ./scripts/cargo-install-all.sh . cuda
|
||||||
$ export PATH=$PWD/bin:$PATH
|
$ export PATH=$PWD/bin:$PATH
|
||||||
```
|
```
|
||||||
|
@ -53,8 +53,7 @@ software.
|
|||||||
|
|
||||||
##### Linux and mac OS
|
##### Linux and mac OS
|
||||||
```bash
|
```bash
|
||||||
$ export SOLANA_RELEASE=v0.16.0 # skip this line to install the latest release
|
$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v0.17.0/install/solana-install-init.sh | sh -s
|
||||||
$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v0.16.0/install/solana-install-init.sh | sh -s
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively build the `solana-install` program from source and run the
|
Alternatively build the `solana-install` program from source and run the
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-chacha-sys"
|
name = "solana-chacha-sys"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana chacha-sys"
|
description = "Solana chacha-sys"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
15
ci/buildkite-release.yml
Normal file
15
ci/buildkite-release.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Build steps that run on a release tag
|
||||||
|
#
|
||||||
|
# All the steps in `buildkite.yml` are skipped and we jump directly to the
|
||||||
|
# secondary build steps since it's assumed the commit that was tagged is known
|
||||||
|
# to be good so there's no need to rebuild and retest it.
|
||||||
|
steps:
|
||||||
|
- trigger: "solana-secondary"
|
||||||
|
branches: "!pull/*"
|
||||||
|
async: true
|
||||||
|
build:
|
||||||
|
message: "${BUILDKITE_MESSAGE}"
|
||||||
|
commit: "${BUILDKITE_COMMIT}"
|
||||||
|
branch: "${BUILDKITE_BRANCH}"
|
||||||
|
env:
|
||||||
|
TRIGGERED_BUILDKITE_TAG: "${BUILDKITE_TAG}"
|
@ -1,16 +1,19 @@
|
|||||||
|
#
|
||||||
|
# Build steps that run after the primary pipeline on pushes and tags.
|
||||||
|
# Pull requests to not run these steps.
|
||||||
steps:
|
steps:
|
||||||
- command: "sdk/docker-solana/build.sh"
|
- command: "sdk/docker-solana/build.sh"
|
||||||
timeout_in_minutes: 40
|
timeout_in_minutes: 60
|
||||||
name: "publish docker"
|
name: "publish docker"
|
||||||
- command: "ci/publish-crate.sh"
|
- command: "ci/publish-crate.sh"
|
||||||
timeout_in_minutes: 90
|
timeout_in_minutes: 120
|
||||||
name: "publish crate"
|
name: "publish crate"
|
||||||
branches: "!master"
|
branches: "!master"
|
||||||
- command: "ci/publish-bpf-sdk.sh"
|
- command: "ci/publish-bpf-sdk.sh"
|
||||||
timeout_in_minutes: 5
|
timeout_in_minutes: 5
|
||||||
name: "publish bpf sdk"
|
name: "publish bpf sdk"
|
||||||
- command: "ci/publish-tarball.sh"
|
- command: "ci/publish-tarball.sh"
|
||||||
timeout_in_minutes: 45
|
timeout_in_minutes: 60
|
||||||
name: "publish tarball"
|
name: "publish tarball"
|
||||||
- command: "ci/publish-book.sh"
|
- command: "ci/publish-book.sh"
|
||||||
timeout_in_minutes: 15
|
timeout_in_minutes: 15
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# Build steps that run on pushes and pull requests.
|
||||||
|
#
|
||||||
|
# Release tags use buildkite-release.yml instead
|
||||||
steps:
|
steps:
|
||||||
- command: "ci/shellcheck.sh"
|
- command: "ci/shellcheck.sh"
|
||||||
name: "shellcheck"
|
name: "shellcheck"
|
||||||
|
@ -142,8 +142,6 @@ testnet-beta|testnet-beta-perf)
|
|||||||
testnet)
|
testnet)
|
||||||
CHANNEL_OR_TAG=$STABLE_CHANNEL_LATEST_TAG
|
CHANNEL_OR_TAG=$STABLE_CHANNEL_LATEST_TAG
|
||||||
CHANNEL_BRANCH=$STABLE_CHANNEL
|
CHANNEL_BRANCH=$STABLE_CHANNEL
|
||||||
: "${EC2_NODE_COUNT:=10}"
|
|
||||||
: "${GCE_NODE_COUNT:=}"
|
|
||||||
;;
|
;;
|
||||||
testnet-perf)
|
testnet-perf)
|
||||||
CHANNEL_OR_TAG=$STABLE_CHANNEL_LATEST_TAG
|
CHANNEL_OR_TAG=$STABLE_CHANNEL_LATEST_TAG
|
||||||
@ -203,7 +201,6 @@ steps:
|
|||||||
TESTNET: "$TESTNET"
|
TESTNET: "$TESTNET"
|
||||||
TESTNET_OP: "$TESTNET_OP"
|
TESTNET_OP: "$TESTNET_OP"
|
||||||
TESTNET_DB_HOST: "$TESTNET_DB_HOST"
|
TESTNET_DB_HOST: "$TESTNET_DB_HOST"
|
||||||
EC2_NODE_COUNT: "$EC2_NODE_COUNT"
|
|
||||||
GCE_NODE_COUNT: "$GCE_NODE_COUNT"
|
GCE_NODE_COUNT: "$GCE_NODE_COUNT"
|
||||||
GCE_LOW_QUOTA_NODE_COUNT: "$GCE_LOW_QUOTA_NODE_COUNT"
|
GCE_LOW_QUOTA_NODE_COUNT: "$GCE_LOW_QUOTA_NODE_COUNT"
|
||||||
EOF
|
EOF
|
||||||
@ -220,7 +217,7 @@ sanity() {
|
|||||||
set -x
|
set -x
|
||||||
NO_INSTALL_CHECK=1 \
|
NO_INSTALL_CHECK=1 \
|
||||||
NO_LEDGER_VERIFY=1 \
|
NO_LEDGER_VERIFY=1 \
|
||||||
ci/testnet-sanity.sh edge-testnet-solana-com ec2 us-west-1a
|
ci/testnet-sanity.sh edge-testnet-solana-com gce us-west1-b
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
testnet-edge-perf)
|
testnet-edge-perf)
|
||||||
@ -237,7 +234,7 @@ sanity() {
|
|||||||
set -x
|
set -x
|
||||||
NO_INSTALL_CHECK=1 \
|
NO_INSTALL_CHECK=1 \
|
||||||
NO_LEDGER_VERIFY=1 \
|
NO_LEDGER_VERIFY=1 \
|
||||||
ci/testnet-sanity.sh beta-testnet-solana-com ec2 us-west-1a
|
ci/testnet-sanity.sh beta-testnet-solana-com gce us-west1-b
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
testnet-beta-perf)
|
testnet-beta-perf)
|
||||||
@ -252,19 +249,9 @@ sanity() {
|
|||||||
testnet)
|
testnet)
|
||||||
(
|
(
|
||||||
set -x
|
set -x
|
||||||
|
NO_LEDGER_VERIFY=1 \
|
||||||
ok=true
|
NO_VALIDATOR_SANITY=1 \
|
||||||
if [[ -n $EC2_NODE_COUNT ]]; then
|
ci/testnet-sanity.sh testnet-solana-com gce us-west1-b
|
||||||
NO_LEDGER_VERIFY=1 \
|
|
||||||
ci/testnet-sanity.sh testnet-solana-com ec2 "${EC2_ZONES[0]}" || ok=false
|
|
||||||
elif [[ -n $GCE_NODE_COUNT ]]; then
|
|
||||||
NO_LEDGER_VERIFY=1 \
|
|
||||||
ci/testnet-sanity.sh testnet-solana-com gce "${GCE_ZONES[0]}" || ok=false
|
|
||||||
else
|
|
||||||
echo "Error: no EC2 or GCE nodes"
|
|
||||||
ok=false
|
|
||||||
fi
|
|
||||||
$ok
|
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
testnet-perf)
|
testnet-perf)
|
||||||
@ -334,9 +321,9 @@ deploy() {
|
|||||||
testnet-edge)
|
testnet-edge)
|
||||||
(
|
(
|
||||||
set -x
|
set -x
|
||||||
ci/testnet-deploy.sh -p edge-testnet-solana-com -C ec2 -z us-west-1a \
|
ci/testnet-deploy.sh -p edge-testnet-solana-com -C gce -z us-west1-b \
|
||||||
-t "$CHANNEL_OR_TAG" -n 3 -c 0 -u -P \
|
-t "$CHANNEL_OR_TAG" -n 2 -c 0 -u -P \
|
||||||
-a eipalloc-0ccd4f2239886fa94 --letsencrypt edge.testnet.solana.com \
|
-a edge-testnet-solana-com --letsencrypt edge.testnet.solana.com \
|
||||||
${skipCreate:+-e} \
|
${skipCreate:+-e} \
|
||||||
${skipStart:+-s} \
|
${skipStart:+-s} \
|
||||||
${maybeStop:+-S} \
|
${maybeStop:+-S} \
|
||||||
@ -361,9 +348,9 @@ deploy() {
|
|||||||
(
|
(
|
||||||
set -x
|
set -x
|
||||||
NO_VALIDATOR_SANITY=1 \
|
NO_VALIDATOR_SANITY=1 \
|
||||||
ci/testnet-deploy.sh -p beta-testnet-solana-com -C ec2 -z us-west-1a \
|
ci/testnet-deploy.sh -p beta-testnet-solana-com -C gce -z us-west1-b \
|
||||||
-t "$CHANNEL_OR_TAG" -n 3 -c 0 -u -P \
|
-t "$CHANNEL_OR_TAG" -n 2 -c 0 -u -P \
|
||||||
-a eipalloc-0f286cf8a0771ce35 --letsencrypt beta.testnet.solana.com \
|
-a beta-testnet-solana-com --letsencrypt beta.testnet.solana.com \
|
||||||
${skipCreate:+-e} \
|
${skipCreate:+-e} \
|
||||||
${skipStart:+-s} \
|
${skipStart:+-s} \
|
||||||
${maybeStop:+-S} \
|
${maybeStop:+-S} \
|
||||||
@ -387,30 +374,14 @@ deploy() {
|
|||||||
testnet)
|
testnet)
|
||||||
(
|
(
|
||||||
set -x
|
set -x
|
||||||
|
NO_VALIDATOR_SANITY=1 \
|
||||||
if [[ -n $GCE_NODE_COUNT ]] || [[ -n $skipStart ]]; then
|
ci/testnet-deploy.sh -p testnet-solana-com -C gce -z us-west1-b \
|
||||||
maybeSkipStart="skip"
|
-t "$CHANNEL_OR_TAG" -n 2 -c 0 -u -P \
|
||||||
fi
|
-a testnet-solana-com --letsencrypt testnet.solana.com \
|
||||||
|
|
||||||
# shellcheck disable=SC2068
|
|
||||||
ci/testnet-deploy.sh -p testnet-solana-com -C ec2 ${EC2_ZONE_ARGS[@]} \
|
|
||||||
-t "$CHANNEL_OR_TAG" -n "$EC2_NODE_COUNT" -c 0 -u -P -f \
|
|
||||||
-a eipalloc-0fa502bf95f6f18b2 --letsencrypt testnet.solana.com \
|
|
||||||
${skipCreate:+-e} \
|
|
||||||
${maybeSkipStart:+-s} \
|
|
||||||
${maybeStop:+-S} \
|
|
||||||
${maybeDelete:+-D}
|
|
||||||
|
|
||||||
if [[ -n $GCE_NODE_COUNT ]]; then
|
|
||||||
# shellcheck disable=SC2068
|
|
||||||
ci/testnet-deploy.sh -p testnet-solana-com -C gce ${GCE_ZONE_ARGS[@]} \
|
|
||||||
-t "$CHANNEL_OR_TAG" -n "$GCE_NODE_COUNT" -c 0 -P -f \
|
|
||||||
${skipCreate:+-e} \
|
${skipCreate:+-e} \
|
||||||
${skipStart:+-s} \
|
${skipStart:+-s} \
|
||||||
${maybeStop:+-S} \
|
${maybeStop:+-S} \
|
||||||
${maybeDelete:+-D} \
|
${maybeDelete:+-D}
|
||||||
-x
|
|
||||||
fi
|
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
testnet-perf)
|
testnet-perf)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-client"
|
name = "solana-client"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Client"
|
description = "Solana Client"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -19,10 +19,10 @@ reqwest = "0.9.19"
|
|||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
jsonrpc-core = "12.1.0"
|
jsonrpc-core = "12.1.0"
|
||||||
jsonrpc-http-server = "12.1.0"
|
jsonrpc-http-server = "12.1.0"
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana"
|
name = "solana"
|
||||||
description = "Blockchain, Rebuilt for Scale"
|
description = "Blockchain, Rebuilt for Scale"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
documentation = "https://docs.rs/solana"
|
documentation = "https://docs.rs/solana"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
@ -46,29 +46,25 @@ rocksdb = "0.11.0"
|
|||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
solana-budget-api = { path = "../programs/budget_api", version = "0.17.0" }
|
solana-budget-api = { path = "../programs/budget_api", version = "0.17.2" }
|
||||||
solana-budget-program = { path = "../programs/budget_program", version = "0.17.0" }
|
solana-budget-program = { path = "../programs/budget_program", version = "0.17.2" }
|
||||||
solana-chacha-sys = { path = "../chacha-sys", version = "0.17.0" }
|
solana-chacha-sys = { path = "../chacha-sys", version = "0.17.2" }
|
||||||
solana-client = { path = "../client", version = "0.17.0" }
|
solana-client = { path = "../client", version = "0.17.2" }
|
||||||
solana-config-program = { path = "../programs/config_program", version = "0.17.0" }
|
solana-drone = { path = "../drone", version = "0.17.2" }
|
||||||
solana-drone = { path = "../drone", version = "0.17.0" }
|
|
||||||
solana-ed25519-dalek = "0.2.0"
|
solana-ed25519-dalek = "0.2.0"
|
||||||
solana-exchange-program = { path = "../programs/exchange_program", version = "0.17.0" }
|
solana-kvstore = { path = "../kvstore", version = "0.17.2", optional = true }
|
||||||
solana-kvstore = { path = "../kvstore", version = "0.17.0", optional = true }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-merkle-tree = { path = "../merkle-tree", version = "0.17.2" }
|
||||||
solana-merkle-tree = { path = "../merkle-tree", version = "0.17.0" }
|
solana-metrics = { path = "../metrics", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../metrics", version = "0.17.0" }
|
solana-measure = { path = "../measure", version = "0.17.2" }
|
||||||
solana-measure = { path = "../measure", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-runtime = { path = "../runtime", version = "0.17.2" }
|
||||||
solana-runtime = { path = "../runtime", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-stake-api = { path = "../programs/stake_api", version = "0.17.2" }
|
||||||
solana-stake-api = { path = "../programs/stake_api", version = "0.17.0" }
|
solana-storage-api = { path = "../programs/storage_api", version = "0.17.2" }
|
||||||
solana-stake-program = { path = "../programs/stake_program", version = "0.17.0" }
|
solana-storage-program = { path = "../programs/storage_program", version = "0.17.2" }
|
||||||
solana-storage-api = { path = "../programs/storage_api", version = "0.17.0" }
|
solana-vote-api = { path = "../programs/vote_api", version = "0.17.2" }
|
||||||
solana-storage-program = { path = "../programs/storage_program", version = "0.17.0" }
|
solana-vote-signer = { path = "../vote-signer", version = "0.17.2" }
|
||||||
solana-vote-api = { path = "../programs/vote_api", version = "0.17.0" }
|
|
||||||
solana-vote-program = { path = "../programs/vote_program", version = "0.17.0" }
|
|
||||||
solana-vote-signer = { path = "../vote-signer", version = "0.17.0" }
|
|
||||||
sys-info = "0.5.7"
|
sys-info = "0.5.7"
|
||||||
tokio = "0.1"
|
tokio = "0.1"
|
||||||
tokio-codec = "0.1"
|
tokio-codec = "0.1"
|
||||||
|
@ -214,8 +214,7 @@ impl Tower {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_recent_epoch(&self, bank: &Bank) -> bool {
|
pub fn is_recent_epoch(&self, bank: &Bank) -> bool {
|
||||||
let bank_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
|
bank.epoch() >= self.epoch_stakes.epoch
|
||||||
bank_epoch >= self.epoch_stakes.epoch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_epoch(&mut self, bank: &Bank) {
|
pub fn update_epoch(&mut self, bank: &Bank) {
|
||||||
@ -224,8 +223,7 @@ impl Tower {
|
|||||||
bank.slot(),
|
bank.slot(),
|
||||||
self.epoch_stakes.epoch
|
self.epoch_stakes.epoch
|
||||||
);
|
);
|
||||||
let bank_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
|
if bank.epoch() != self.epoch_stakes.epoch {
|
||||||
if bank_epoch != self.epoch_stakes.epoch {
|
|
||||||
assert!(
|
assert!(
|
||||||
self.is_recent_epoch(bank),
|
self.is_recent_epoch(bank),
|
||||||
"epoch_stakes cannot move backwards"
|
"epoch_stakes cannot move backwards"
|
||||||
|
@ -155,15 +155,15 @@ impl LocalCluster {
|
|||||||
genesis_block
|
genesis_block
|
||||||
.native_instruction_processors
|
.native_instruction_processors
|
||||||
.extend_from_slice(&config.native_instruction_processors);
|
.extend_from_slice(&config.native_instruction_processors);
|
||||||
|
genesis_block
|
||||||
|
.native_instruction_processors
|
||||||
|
.push(solana_storage_program!());
|
||||||
|
|
||||||
let storage_keypair = Keypair::new();
|
let storage_keypair = Keypair::new();
|
||||||
genesis_block.accounts.push((
|
genesis_block.accounts.push((
|
||||||
storage_keypair.pubkey(),
|
storage_keypair.pubkey(),
|
||||||
storage_contract::create_validator_storage_account(leader_pubkey, 1),
|
storage_contract::create_validator_storage_account(leader_pubkey, 1),
|
||||||
));
|
));
|
||||||
genesis_block
|
|
||||||
.native_instruction_processors
|
|
||||||
.push(solana_storage_program!());
|
|
||||||
|
|
||||||
let (leader_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block);
|
let (leader_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block);
|
||||||
let leader_contact_info = leader_node.info.clone();
|
let leader_contact_info = leader_node.info.clone();
|
||||||
|
@ -150,6 +150,8 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
// First epoch has the bootstrap leader
|
// First epoch has the bootstrap leader
|
||||||
expected.insert(voting_keypair.pubkey(), leader_stake.stake(0));
|
expected.insert(voting_keypair.pubkey(), leader_stake.stake(0));
|
||||||
|
|
||||||
|
// henceforth, verify that we have snapshots of stake at epoch 0
|
||||||
let expected = Some(expected);
|
let expected = Some(expected);
|
||||||
assert_eq!(vote_account_stakes_at_epoch(&bank, 0), expected);
|
assert_eq!(vote_account_stakes_at_epoch(&bank, 0), expected);
|
||||||
|
|
||||||
@ -242,25 +244,27 @@ pub(crate) mod tests {
|
|||||||
stake,
|
stake,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// simulated stake
|
||||||
let other_stake = Stake {
|
let other_stake = Stake {
|
||||||
stake,
|
stake,
|
||||||
|
activated: bank.epoch(),
|
||||||
..Stake::default()
|
..Stake::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
// soonest slot that could be a new epoch is 1
|
let epoch = bank.get_stakers_epoch(bank.slot());
|
||||||
|
// find the first slot in the next staker's epoch
|
||||||
let mut slot = 1;
|
let mut slot = 1;
|
||||||
let mut epoch = bank.get_stakers_epoch(0);
|
while bank.get_stakers_epoch(slot) <= epoch {
|
||||||
// find the first slot in the next stakers_epoch
|
|
||||||
while bank.get_stakers_epoch(slot) == epoch {
|
|
||||||
slot += 1;
|
slot += 1;
|
||||||
}
|
}
|
||||||
epoch = bank.get_stakers_epoch(slot);
|
|
||||||
|
|
||||||
let bank = new_from_parent(&Arc::new(bank), slot);
|
let bank = new_from_parent(&Arc::new(bank), slot);
|
||||||
|
let epoch = bank.get_stakers_epoch(slot);
|
||||||
|
|
||||||
let result: Vec<_> = epoch_stakes_and_lockouts(&bank, 0);
|
let result: Vec<_> = epoch_stakes_and_lockouts(&bank, 0);
|
||||||
assert_eq!(result, vec![(leader_stake.stake(0), None)]);
|
assert_eq!(result, vec![(leader_stake.stake(0), None)]);
|
||||||
|
|
||||||
|
// epoch stakes and lockouts are saved off for the future epoch, should
|
||||||
|
// match current bank state
|
||||||
let mut result: Vec<_> = epoch_stakes_and_lockouts(&bank, epoch);
|
let mut result: Vec<_> = epoch_stakes_and_lockouts(&bank, epoch);
|
||||||
result.sort();
|
result.sort();
|
||||||
let mut expected = vec![
|
let mut expected = vec![
|
||||||
|
@ -21,6 +21,7 @@ use std::time::Duration;
|
|||||||
#[serial]
|
#[serial]
|
||||||
fn test_ledger_cleanup_service() {
|
fn test_ledger_cleanup_service() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_ledger_cleanup_service");
|
||||||
let num_nodes = 3;
|
let num_nodes = 3;
|
||||||
let mut validator_config = ValidatorConfig::default();
|
let mut validator_config = ValidatorConfig::default();
|
||||||
validator_config.max_ledger_slots = Some(100);
|
validator_config.max_ledger_slots = Some(100);
|
||||||
@ -59,6 +60,7 @@ fn test_ledger_cleanup_service() {
|
|||||||
#[serial]
|
#[serial]
|
||||||
fn test_spend_and_verify_all_nodes_1() {
|
fn test_spend_and_verify_all_nodes_1() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_spend_and_verify_all_nodes_1");
|
||||||
let num_nodes = 1;
|
let num_nodes = 1;
|
||||||
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
||||||
cluster_tests::spend_and_verify_all_nodes(
|
cluster_tests::spend_and_verify_all_nodes(
|
||||||
@ -73,6 +75,7 @@ fn test_spend_and_verify_all_nodes_1() {
|
|||||||
#[serial]
|
#[serial]
|
||||||
fn test_spend_and_verify_all_nodes_2() {
|
fn test_spend_and_verify_all_nodes_2() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_spend_and_verify_all_nodes_2");
|
||||||
let num_nodes = 2;
|
let num_nodes = 2;
|
||||||
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
||||||
cluster_tests::spend_and_verify_all_nodes(
|
cluster_tests::spend_and_verify_all_nodes(
|
||||||
@ -87,6 +90,7 @@ fn test_spend_and_verify_all_nodes_2() {
|
|||||||
#[serial]
|
#[serial]
|
||||||
fn test_spend_and_verify_all_nodes_3() {
|
fn test_spend_and_verify_all_nodes_3() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_spend_and_verify_all_nodes_3");
|
||||||
let num_nodes = 3;
|
let num_nodes = 3;
|
||||||
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
||||||
cluster_tests::spend_and_verify_all_nodes(
|
cluster_tests::spend_and_verify_all_nodes(
|
||||||
@ -122,6 +126,7 @@ fn test_spend_and_verify_all_nodes_env_num_nodes() {
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_fullnode_exit_default_config_should_panic() {
|
fn test_fullnode_exit_default_config_should_panic() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_fullnode_exit_default_config_should_panic");
|
||||||
let num_nodes = 2;
|
let num_nodes = 2;
|
||||||
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
let local = LocalCluster::new_with_equal_stakes(num_nodes, 10_000, 100);
|
||||||
cluster_tests::fullnode_exit(&local.entry_point_info, num_nodes);
|
cluster_tests::fullnode_exit(&local.entry_point_info, num_nodes);
|
||||||
@ -131,6 +136,7 @@ fn test_fullnode_exit_default_config_should_panic() {
|
|||||||
#[serial]
|
#[serial]
|
||||||
fn test_fullnode_exit_2() {
|
fn test_fullnode_exit_2() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_fullnode_exit_2");
|
||||||
let num_nodes = 2;
|
let num_nodes = 2;
|
||||||
let mut validator_config = ValidatorConfig::default();
|
let mut validator_config = ValidatorConfig::default();
|
||||||
validator_config.rpc_config.enable_fullnode_exit = true;
|
validator_config.rpc_config.enable_fullnode_exit = true;
|
||||||
@ -145,10 +151,13 @@ fn test_fullnode_exit_2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cluster needs a supermajority to remain, so the minimum size for this test is 4
|
// Cluster needs a supermajority to remain, so the minimum size for this test is 4
|
||||||
|
#[allow(unused_attributes)]
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
#[ignore]
|
||||||
fn test_leader_failure_4() {
|
fn test_leader_failure_4() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_leader_failure_4");
|
||||||
let num_nodes = 4;
|
let num_nodes = 4;
|
||||||
let mut validator_config = ValidatorConfig::default();
|
let mut validator_config = ValidatorConfig::default();
|
||||||
validator_config.rpc_config.enable_fullnode_exit = true;
|
validator_config.rpc_config.enable_fullnode_exit = true;
|
||||||
@ -170,6 +179,7 @@ fn test_leader_failure_4() {
|
|||||||
#[serial]
|
#[serial]
|
||||||
fn test_two_unbalanced_stakes() {
|
fn test_two_unbalanced_stakes() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_two_unbalanced_stakes");
|
||||||
let mut validator_config = ValidatorConfig::default();
|
let mut validator_config = ValidatorConfig::default();
|
||||||
let num_ticks_per_second = 100;
|
let num_ticks_per_second = 100;
|
||||||
let num_ticks_per_slot = 10;
|
let num_ticks_per_slot = 10;
|
||||||
@ -231,6 +241,8 @@ fn test_forwarding() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn test_restart_node() {
|
fn test_restart_node() {
|
||||||
|
solana_logger::setup();
|
||||||
|
error!("test_restart_node");
|
||||||
let slots_per_epoch = MINIMUM_SLOTS_PER_EPOCH as u64;
|
let slots_per_epoch = MINIMUM_SLOTS_PER_EPOCH as u64;
|
||||||
let ticks_per_slot = 16;
|
let ticks_per_slot = 16;
|
||||||
let mut cluster = LocalCluster::new(&ClusterConfig {
|
let mut cluster = LocalCluster::new(&ClusterConfig {
|
||||||
@ -273,14 +285,18 @@ fn test_listener_startup() {
|
|||||||
assert_eq!(cluster_nodes.len(), 4);
|
assert_eq!(cluster_nodes.len(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_attributes)]
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
#[ignore]
|
||||||
fn test_fail_entry_verification_leader() {
|
fn test_fail_entry_verification_leader() {
|
||||||
test_faulty_node(BroadcastStageType::FailEntryVerification);
|
test_faulty_node(BroadcastStageType::FailEntryVerification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_attributes)]
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
#[ignore]
|
||||||
fn test_bad_blob_size_leader() {
|
fn test_bad_blob_size_leader() {
|
||||||
test_faulty_node(BroadcastStageType::BroadcastBadBlobSizes);
|
test_faulty_node(BroadcastStageType::BroadcastBadBlobSizes);
|
||||||
}
|
}
|
||||||
@ -344,10 +360,13 @@ fn test_faulty_node(faulty_node_type: BroadcastStageType) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_attributes)]
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
#[ignore]
|
||||||
fn test_repairman_catchup() {
|
fn test_repairman_catchup() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
error!("test_repairman_catchup");
|
||||||
run_repairman_catchup(3);
|
run_repairman_catchup(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +79,10 @@ fn test_replicator_startup_1_node() {
|
|||||||
run_replicator_startup_basic(1, 1);
|
run_replicator_startup_basic(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_attributes)]
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
#[ignore]
|
||||||
fn test_replicator_startup_2_nodes() {
|
fn test_replicator_startup_2_nodes() {
|
||||||
run_replicator_startup_basic(2, 1);
|
run_replicator_startup_basic(2, 1);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-drone"
|
name = "solana-drone"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Drone"
|
description = "Solana Drone"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -20,9 +20,9 @@ clap = "2.33"
|
|||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../metrics", version = "0.17.0" }
|
solana-metrics = { path = "../metrics", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
tokio = "0.1"
|
tokio = "0.1"
|
||||||
tokio-codec = "0.1"
|
tokio-codec = "0.1"
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-genesis"
|
name = "solana-genesis"
|
||||||
description = "Blockchain, Rebuilt for Scale"
|
description = "Blockchain, Rebuilt for Scale"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
@ -15,24 +15,12 @@ serde = "1.0.97"
|
|||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
serde_yaml = "0.8.9"
|
serde_yaml = "0.8.9"
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-bpf-loader-api = { path = "../programs/bpf_loader_api", version = "0.17.0" }
|
solana-genesis-programs = { path = "../genesis_programs", version = "0.17.2" }
|
||||||
solana-bpf-loader-program = { path = "../programs/bpf_loader_program", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
solana-budget-api = { path = "../programs/budget_api", version = "0.17.0" }
|
solana-stake-api = { path = "../programs/stake_api", version = "0.17.2" }
|
||||||
solana-budget-program = { path = "../programs/budget_program", version = "0.17.0" }
|
solana-storage-api = { path = "../programs/storage_api", version = "0.17.2" }
|
||||||
solana-config-api = { path = "../programs/config_api", version = "0.17.0" }
|
solana-vote-api = { path = "../programs/vote_api", version = "0.17.2" }
|
||||||
solana-config-program = { path = "../programs/config_program", version = "0.17.0" }
|
|
||||||
solana-exchange-api = { path = "../programs/exchange_api", version = "0.17.0" }
|
|
||||||
solana-exchange-program = { path = "../programs/exchange_program", version = "0.17.0" }
|
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
|
||||||
solana-stake-api = { path = "../programs/stake_api", version = "0.17.0" }
|
|
||||||
solana-stake-program = { path = "../programs/stake_program", version = "0.17.0" }
|
|
||||||
solana-storage-api = { path = "../programs/storage_api", version = "0.17.0" }
|
|
||||||
solana-storage-program = { path = "../programs/storage_program", version = "0.17.0" }
|
|
||||||
solana-token-api = { path = "../programs/token_api", version = "0.17.0" }
|
|
||||||
solana-token-program = { path = "../programs/token_program", version = "0.17.0" }
|
|
||||||
solana-vote-api = { path = "../programs/vote_api", version = "0.17.0" }
|
|
||||||
solana-vote-program = { path = "../programs/vote_program", version = "0.17.0" }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hashbrown = "0.3.0"
|
hashbrown = "0.3.0"
|
||||||
|
@ -1,20 +1,4 @@
|
|||||||
//! A command-line executable for generating the chain's genesis block.
|
//! A command-line executable for generating the chain's genesis block.
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_bpf_loader_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_vote_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_stake_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_budget_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_token_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_config_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_exchange_program;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate solana_storage_program;
|
|
||||||
|
|
||||||
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;
|
||||||
@ -298,16 +282,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
.native_instruction_processors(&[
|
.native_instruction_processors(&solana_genesis_programs::get())
|
||||||
solana_bpf_loader_program!(),
|
|
||||||
solana_vote_program!(),
|
|
||||||
solana_stake_program!(),
|
|
||||||
solana_budget_program!(),
|
|
||||||
solana_token_program!(),
|
|
||||||
solana_config_program!(),
|
|
||||||
solana_exchange_program!(),
|
|
||||||
solana_storage_program!(),
|
|
||||||
])
|
|
||||||
.ticks_per_slot(value_t_or_exit!(matches, "ticks_per_slot", u64))
|
.ticks_per_slot(value_t_or_exit!(matches, "ticks_per_slot", u64))
|
||||||
.slots_per_epoch(value_t_or_exit!(matches, "slots_per_epoch", u64));
|
.slots_per_epoch(value_t_or_exit!(matches, "slots_per_epoch", u64));
|
||||||
|
|
||||||
@ -366,7 +341,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use hashbrown::HashSet;
|
|
||||||
use solana_sdk::genesis_block::Builder;
|
use solana_sdk::genesis_block::Builder;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -374,24 +348,6 @@ mod tests {
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_program_id_uniqueness() {
|
|
||||||
let mut unique = HashSet::new();
|
|
||||||
let ids = vec![
|
|
||||||
solana_sdk::system_program::id(),
|
|
||||||
solana_sdk::native_loader::id(),
|
|
||||||
solana_sdk::bpf_loader::id(),
|
|
||||||
solana_budget_api::id(),
|
|
||||||
solana_storage_api::id(),
|
|
||||||
solana_token_api::id(),
|
|
||||||
solana_vote_api::id(),
|
|
||||||
solana_stake_api::id(),
|
|
||||||
solana_config_api::id(),
|
|
||||||
solana_exchange_api::id(),
|
|
||||||
];
|
|
||||||
assert!(ids.into_iter().all(move |id| unique.insert(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_append_primordial_accounts_to_genesis() {
|
fn test_append_primordial_accounts_to_genesis() {
|
||||||
// Test invalid file returns error
|
// Test invalid file returns error
|
||||||
|
2
genesis_programs/.gitignore
vendored
Normal file
2
genesis_programs/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target/
|
||||||
|
/farf/
|
35
genesis_programs/Cargo.toml
Normal file
35
genesis_programs/Cargo.toml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[package]
|
||||||
|
name = "solana-genesis-programs"
|
||||||
|
version = "0.17.2"
|
||||||
|
description = "Solana genesis programs"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
homepage = "https://solana.com/"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hashbrown = "0.2.0"
|
||||||
|
solana-bpf-loader-api = { path = "../programs/bpf_loader_api", version = "0.17.2" }
|
||||||
|
solana-bpf-loader-program = { path = "../programs/bpf_loader_program", version = "0.17.2" }
|
||||||
|
solana-budget-api= { path = "../programs/budget_api", version = "0.17.0" }
|
||||||
|
solana-budget-program = { path = "../programs/budget_program", version = "0.17.2" }
|
||||||
|
solana-config-api = { path = "../programs/config_api", version = "0.17.2" }
|
||||||
|
solana-config-program = { path = "../programs/config_program", version = "0.17.2" }
|
||||||
|
solana-exchange-api = { path = "../programs/exchange_api", version = "0.17.2" }
|
||||||
|
solana-exchange-program = { path = "../programs/exchange_program", version = "0.17.2" }
|
||||||
|
solana-move-loader-program = { path = "../programs/move_loader_program", version = "0.17.2" }
|
||||||
|
solana-move-loader-api = { path = "../programs/move_loader_api", version = "0.17.2" }
|
||||||
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
solana-stake-api = { path = "../programs/stake_api", version = "0.17.2" }
|
||||||
|
solana-stake-program = { path = "../programs/stake_program", version = "0.17.2" }
|
||||||
|
solana-storage-api = { path = "../programs/storage_api", version = "0.17.2" }
|
||||||
|
solana-storage-program = { path = "../programs/storage_program", version = "0.17.2" }
|
||||||
|
solana-token-api = { path = "../programs/token_api", version = "0.17.2" }
|
||||||
|
solana-token-program = { path = "../programs/token_program", version = "0.17.2" }
|
||||||
|
solana-vote-api = { path = "../programs/vote_api", version = "0.17.2" }
|
||||||
|
solana-vote-program = { path = "../programs/vote_program", version = "0.17.2" }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["lib"]
|
||||||
|
name = "solana_genesis_programs"
|
58
genesis_programs/src/lib.rs
Normal file
58
genesis_programs/src/lib.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_bpf_loader_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_budget_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_config_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_exchange_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_move_loader_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_stake_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_storage_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_token_program;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate solana_vote_program;
|
||||||
|
|
||||||
|
pub fn get() -> Vec<(String, Pubkey)> {
|
||||||
|
vec![
|
||||||
|
solana_bpf_loader_program!(),
|
||||||
|
solana_budget_program!(),
|
||||||
|
solana_config_program!(),
|
||||||
|
solana_exchange_program!(),
|
||||||
|
solana_move_loader_program!(),
|
||||||
|
solana_stake_program!(),
|
||||||
|
solana_storage_program!(),
|
||||||
|
solana_token_program!(),
|
||||||
|
solana_vote_program!(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use hashbrown::HashSet;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_id_uniqueness() {
|
||||||
|
let mut unique = HashSet::new();
|
||||||
|
let ids = vec![
|
||||||
|
solana_budget_api::id(),
|
||||||
|
solana_config_api::id(),
|
||||||
|
solana_exchange_api::id(),
|
||||||
|
solana_move_loader_api::id(),
|
||||||
|
solana_sdk::bpf_loader::id(),
|
||||||
|
solana_sdk::native_loader::id(),
|
||||||
|
solana_sdk::system_program::id(),
|
||||||
|
solana_stake_api::id(),
|
||||||
|
solana_storage_api::id(),
|
||||||
|
solana_token_api::id(),
|
||||||
|
solana_vote_api::id(),
|
||||||
|
];
|
||||||
|
assert!(ids.into_iter().all(move |id| unique.insert(id)));
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-gossip"
|
name = "solana-gossip"
|
||||||
description = "Blockchain, Rebuilt for Scale"
|
description = "Blockchain, Rebuilt for Scale"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
@ -11,10 +11,10 @@ homepage = "https://solana.com/"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
env_logger = "0.6.2"
|
env_logger = "0.6.2"
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-client = { path = "../client", version = "0.17.0" }
|
solana-client = { path = "../client", version = "0.17.2" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
cuda = []
|
cuda = []
|
||||||
|
@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-install"
|
name = "solana-install"
|
||||||
description = "The solana cluster software installer"
|
description = "The solana cluster software installer"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
@ -32,10 +32,10 @@ serde = "1.0.97"
|
|||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_yaml = "0.8.9"
|
serde_yaml = "0.8.9"
|
||||||
sha2 = "0.8.0"
|
sha2 = "0.8.0"
|
||||||
solana-client = { path = "../client", version = "0.17.0" }
|
solana-client = { path = "../client", version = "0.17.2" }
|
||||||
solana-config-api = { path = "../programs/config_api", version = "0.17.0" }
|
solana-config-api = { path = "../programs/config_api", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
tar = "0.4.26"
|
tar = "0.4.26"
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
url = "2.0.0"
|
url = "2.0.0"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::config::Config;
|
use crate::config::{Config, ExplicitRelease};
|
||||||
use crate::stop_process::stop_process;
|
use crate::stop_process::stop_process;
|
||||||
use crate::update_manifest::{SignedUpdateManifest, UpdateManifest};
|
use crate::update_manifest::{SignedUpdateManifest, UpdateManifest};
|
||||||
use chrono::{Local, TimeZone};
|
use chrono::{Local, TimeZone};
|
||||||
@ -492,7 +492,7 @@ pub fn init(
|
|||||||
json_rpc_url: &str,
|
json_rpc_url: &str,
|
||||||
update_manifest_pubkey: &Pubkey,
|
update_manifest_pubkey: &Pubkey,
|
||||||
no_modify_path: bool,
|
no_modify_path: bool,
|
||||||
release_semver: Option<&str>,
|
explicit_release: Option<ExplicitRelease>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let config = {
|
let config = {
|
||||||
// Write new config file only if different, so that running |solana-install init|
|
// Write new config file only if different, so that running |solana-install init|
|
||||||
@ -503,7 +503,7 @@ pub fn init(
|
|||||||
data_dir,
|
data_dir,
|
||||||
json_rpc_url,
|
json_rpc_url,
|
||||||
update_manifest_pubkey,
|
update_manifest_pubkey,
|
||||||
release_semver,
|
explicit_release,
|
||||||
);
|
);
|
||||||
if current_config != config {
|
if current_config != config {
|
||||||
config.save(config_file)?;
|
config.save(config_file)?;
|
||||||
@ -525,7 +525,7 @@ pub fn init(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn github_download_url(release_semver: &str) -> String {
|
fn github_release_download_url(release_semver: &str) -> String {
|
||||||
format!(
|
format!(
|
||||||
"https://github.com/solana-labs/solana/releases/download/v{}/solana-release-{}.tar.bz2",
|
"https://github.com/solana-labs/solana/releases/download/v{}/solana-release-{}.tar.bz2",
|
||||||
release_semver,
|
release_semver,
|
||||||
@ -533,6 +533,14 @@ fn github_download_url(release_semver: &str) -> String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn release_channel_download_url(release_channel: &str) -> String {
|
||||||
|
format!(
|
||||||
|
"http://release.solana.com/{}/solana-release-{}.tar.bz2",
|
||||||
|
release_channel,
|
||||||
|
crate::build_env::TARGET
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn info(config_file: &str, local_info_only: bool) -> Result<Option<UpdateManifest>, String> {
|
pub fn info(config_file: &str, local_info_only: bool) -> Result<Option<UpdateManifest>, String> {
|
||||||
let config = Config::load(config_file)?;
|
let config = Config::load(config_file)?;
|
||||||
|
|
||||||
@ -541,12 +549,24 @@ pub fn info(config_file: &str, local_info_only: bool) -> Result<Option<UpdateMan
|
|||||||
"Active release directory:",
|
"Active release directory:",
|
||||||
&config.active_release_dir().to_str().unwrap_or("?"),
|
&config.active_release_dir().to_str().unwrap_or("?"),
|
||||||
);
|
);
|
||||||
if let Some(release_semver) = &config.release_semver {
|
|
||||||
println_name_value(&format!("{}Release version:", BULLET), &release_semver);
|
if let Some(explicit_release) = &config.explicit_release {
|
||||||
println_name_value(
|
match explicit_release {
|
||||||
&format!("{}Release URL:", BULLET),
|
ExplicitRelease::Semver(release_semver) => {
|
||||||
&github_download_url(release_semver),
|
println_name_value(&format!("{}Release version:", BULLET), &release_semver);
|
||||||
);
|
println_name_value(
|
||||||
|
&format!("{}Release URL:", BULLET),
|
||||||
|
&github_release_download_url(release_semver),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ExplicitRelease::Channel(release_channel) => {
|
||||||
|
println_name_value(&format!("{}Release channel:", BULLET), &release_channel);
|
||||||
|
println_name_value(
|
||||||
|
&format!("{}Release URL:", BULLET),
|
||||||
|
&release_channel_download_url(release_channel),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,13 +716,27 @@ pub fn update(config_file: &str) -> Result<bool, String> {
|
|||||||
let mut config = Config::load(config_file)?;
|
let mut config = Config::load(config_file)?;
|
||||||
let update_manifest = info(config_file, false)?;
|
let update_manifest = info(config_file, false)?;
|
||||||
|
|
||||||
let release_dir = if let Some(release_semver) = &config.release_semver {
|
let release_dir = if let Some(explicit_release) = &config.explicit_release {
|
||||||
let download_url = github_download_url(release_semver);
|
let (download_url, release_dir) = match explicit_release {
|
||||||
let release_dir = config.release_dir(&release_semver);
|
ExplicitRelease::Semver(release_semver) => {
|
||||||
let ok_dir = release_dir.join(".ok");
|
let download_url = github_release_download_url(release_semver);
|
||||||
if ok_dir.exists() {
|
let release_dir = config.release_dir(&release_semver);
|
||||||
return Ok(false);
|
if release_dir.join(".ok").exists() {
|
||||||
}
|
// If this release_semver has already been successfully downloaded, no update
|
||||||
|
// needed
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
(download_url, release_dir)
|
||||||
|
}
|
||||||
|
ExplicitRelease::Channel(release_channel) => {
|
||||||
|
let download_url = release_channel_download_url(release_channel);
|
||||||
|
let release_dir = config.release_dir(&release_channel);
|
||||||
|
// Note: There's currently no mechanism to check for an updated binary for a release
|
||||||
|
// channel so a download always occurs.
|
||||||
|
(download_url, release_dir)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let (_temp_dir, temp_archive, _temp_archive_sha256) =
|
let (_temp_dir, temp_archive, _temp_archive_sha256) =
|
||||||
download_to_temp_archive(&download_url, None)
|
download_to_temp_archive(&download_url, None)
|
||||||
.map_err(|err| format!("Unable to download {}: {}", download_url, err))?;
|
.map_err(|err| format!("Unable to download {}: {}", download_url, err))?;
|
||||||
@ -712,7 +746,7 @@ pub fn update(config_file: &str) -> Result<bool, String> {
|
|||||||
temp_archive, release_dir, err
|
temp_archive, release_dir, err
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let _ = fs::create_dir_all(ok_dir);
|
let _ = fs::create_dir_all(release_dir.join(".ok"));
|
||||||
|
|
||||||
release_dir
|
release_dir
|
||||||
} else {
|
} else {
|
||||||
@ -843,7 +877,7 @@ pub fn run(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if now.elapsed().as_secs() > config.update_poll_secs {
|
if config.explicit_release.is_none() && now.elapsed().as_secs() > config.update_poll_secs {
|
||||||
match update(config_file) {
|
match update(config_file) {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
// Update successful, kill current process so it will be restart
|
// Update successful, kill current process so it will be restart
|
||||||
|
@ -5,13 +5,19 @@ use std::fs::{create_dir_all, File};
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
|
pub enum ExplicitRelease {
|
||||||
|
Semver(String),
|
||||||
|
Channel(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Default, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Default, Debug, PartialEq)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub json_rpc_url: String,
|
pub json_rpc_url: String,
|
||||||
pub update_manifest_pubkey: Pubkey,
|
pub update_manifest_pubkey: Pubkey,
|
||||||
pub current_update_manifest: Option<UpdateManifest>,
|
pub current_update_manifest: Option<UpdateManifest>,
|
||||||
pub update_poll_secs: u64,
|
pub update_poll_secs: u64,
|
||||||
pub release_semver: Option<String>,
|
pub explicit_release: Option<ExplicitRelease>,
|
||||||
releases_dir: PathBuf,
|
releases_dir: PathBuf,
|
||||||
active_release_dir: PathBuf,
|
active_release_dir: PathBuf,
|
||||||
}
|
}
|
||||||
@ -21,14 +27,14 @@ impl Config {
|
|||||||
data_dir: &str,
|
data_dir: &str,
|
||||||
json_rpc_url: &str,
|
json_rpc_url: &str,
|
||||||
update_manifest_pubkey: &Pubkey,
|
update_manifest_pubkey: &Pubkey,
|
||||||
release_semver: Option<&str>,
|
explicit_release: Option<ExplicitRelease>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
json_rpc_url: json_rpc_url.to_string(),
|
json_rpc_url: json_rpc_url.to_string(),
|
||||||
update_manifest_pubkey: *update_manifest_pubkey,
|
update_manifest_pubkey: *update_manifest_pubkey,
|
||||||
current_update_manifest: None,
|
current_update_manifest: None,
|
||||||
update_poll_secs: 60, // check for updates once a minute
|
update_poll_secs: 60, // check for updates once a minute
|
||||||
release_semver: release_semver.map(|s| s.to_string()),
|
explicit_release,
|
||||||
releases_dir: PathBuf::from(data_dir).join("releases"),
|
releases_dir: PathBuf::from(data_dir).join("releases"),
|
||||||
active_release_dir: PathBuf::from(data_dir).join("active_release"),
|
active_release_dir: PathBuf::from(data_dir).join("active_release"),
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,20 @@ fn is_pubkey(string: String) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_semver(string: String) -> Result<(), String> {
|
fn is_semver(semver: &str) -> Result<(), String> {
|
||||||
match semver::Version::parse(&string) {
|
match semver::Version::parse(&semver) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(format!("{:?}", err)),
|
Err(err) => Err(format!("{:?}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_release_channel(channel: &str) -> Result<(), String> {
|
||||||
|
match channel {
|
||||||
|
"edge" | "beta" | "stable" => Ok(()),
|
||||||
|
_ => Err(format!("Invalid release channel {}", channel)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() -> Result<(), String> {
|
pub fn main() -> Result<(), String> {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
|
||||||
@ -107,12 +114,12 @@ pub fn main() -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("release_semver")
|
Arg::with_name("explicit_release")
|
||||||
.value_name("release-semver")
|
.value_name("release")
|
||||||
.index(1)
|
.index(1)
|
||||||
.conflicts_with_all(&["json_rpc_url", "update_manifest_pubkey"])
|
.conflicts_with_all(&["json_rpc_url", "update_manifest_pubkey"])
|
||||||
.validator(is_semver)
|
.validator(|string| is_semver(&string).or_else(|_| is_release_channel(&string)))
|
||||||
.help("The exact version to install. Updates will not be available if this argument is used"),
|
.help("The exact version to install. Either a semver or release channel name"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -206,7 +213,9 @@ pub fn main() -> Result<(), String> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let data_dir = matches.value_of("data_dir").unwrap();
|
let data_dir = matches.value_of("data_dir").unwrap();
|
||||||
let no_modify_path = matches.is_present("no_modify_path");
|
let no_modify_path = matches.is_present("no_modify_path");
|
||||||
let release_semver = matches.value_of("release_semver");
|
let explicit_release = matches
|
||||||
|
.value_of("explicit_release")
|
||||||
|
.map(ToString::to_string);
|
||||||
|
|
||||||
command::init(
|
command::init(
|
||||||
config_file,
|
config_file,
|
||||||
@ -214,7 +223,13 @@ pub fn main() -> Result<(), String> {
|
|||||||
json_rpc_url,
|
json_rpc_url,
|
||||||
&update_manifest_pubkey,
|
&update_manifest_pubkey,
|
||||||
no_modify_path,
|
no_modify_path,
|
||||||
release_semver,
|
explicit_release.map(|explicit_release| {
|
||||||
|
if is_semver(&explicit_release).is_ok() {
|
||||||
|
config::ExplicitRelease::Semver(explicit_release)
|
||||||
|
} else {
|
||||||
|
config::ExplicitRelease::Channel(explicit_release)
|
||||||
|
}
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
("info", Some(matches)) => {
|
("info", Some(matches)) => {
|
||||||
@ -310,11 +325,11 @@ pub fn main_init() -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("release_semver")
|
Arg::with_name("explicit_release")
|
||||||
.value_name("release-semver")
|
.value_name("release")
|
||||||
.index(1)
|
.index(1)
|
||||||
.conflicts_with_all(&["json_rpc_url", "update_manifest_pubkey"])
|
.conflicts_with_all(&["json_rpc_url", "update_manifest_pubkey"])
|
||||||
.validator(is_semver)
|
.validator(|string| is_semver(&string).or_else(|_| is_release_channel(&string)))
|
||||||
.help("The exact version to install. Updates will not be available if this argument is used"),
|
.help("The exact version to install. Updates will not be available if this argument is used"),
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
@ -329,7 +344,9 @@ pub fn main_init() -> Result<(), String> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let data_dir = matches.value_of("data_dir").unwrap();
|
let data_dir = matches.value_of("data_dir").unwrap();
|
||||||
let no_modify_path = matches.is_present("no_modify_path");
|
let no_modify_path = matches.is_present("no_modify_path");
|
||||||
let release_semver = matches.value_of("release_semver");
|
let explicit_release = matches
|
||||||
|
.value_of("explicit_release")
|
||||||
|
.map(ToString::to_string);
|
||||||
|
|
||||||
command::init(
|
command::init(
|
||||||
config_file,
|
config_file,
|
||||||
@ -337,6 +354,12 @@ pub fn main_init() -> Result<(), String> {
|
|||||||
json_rpc_url,
|
json_rpc_url,
|
||||||
&update_manifest_pubkey,
|
&update_manifest_pubkey,
|
||||||
no_modify_path,
|
no_modify_path,
|
||||||
release_semver,
|
explicit_release.map(|explicit_release| {
|
||||||
|
if is_semver(&explicit_release).is_ok() {
|
||||||
|
config::ExplicitRelease::Semver(explicit_release)
|
||||||
|
} else {
|
||||||
|
config::ExplicitRelease::Channel(explicit_release)
|
||||||
|
}
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-keygen"
|
name = "solana-keygen"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana key generation utility"
|
description = "Solana key generation utility"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -15,7 +15,7 @@ cuda = []
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
dirs = "2.0.1"
|
dirs = "2.0.1"
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "solana-keygen"
|
name = "solana-keygen"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-kvstore"
|
name = "solana-kvstore"
|
||||||
description = "Embedded Key-Value store for solana"
|
description = "Embedded Key-Value store for solana"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
|
@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-ledger-tool"
|
name = "solana-ledger-tool"
|
||||||
description = "Blockchain, Rebuilt for Scale"
|
description = "Blockchain, Rebuilt for Scale"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
@ -15,10 +15,10 @@ serde = "1.0.97"
|
|||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
serde_yaml = "0.8.9"
|
serde_yaml = "0.8.9"
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-runtime = { path = "../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../runtime", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = "0.11"
|
assert_cmd = "0.11"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-logger"
|
name = "solana-logger"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Logger"
|
description = "Solana Logger"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-measure"
|
name = "solana-measure"
|
||||||
description = "Blockchain, Rebuilt for Scale"
|
description = "Blockchain, Rebuilt for Scale"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
documentation = "https://docs.rs/solana"
|
documentation = "https://docs.rs/solana"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
@ -11,4 +11,4 @@ license = "Apache-2.0"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-merkle-tree"
|
name = "solana-merkle-tree"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Merkle Tree"
|
description = "Solana Merkle Tree"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -9,7 +9,7 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = "0.3.2"
|
hex = "0.3.2"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-metrics"
|
name = "solana-metrics"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Metrics"
|
description = "Solana Metrics"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -14,7 +14,7 @@ influx_db_client = "0.3.6"
|
|||||||
lazy_static = "1.3.0"
|
lazy_static = "1.3.0"
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
reqwest = "0.9.19"
|
reqwest = "0.9.19"
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
sys-info = "0.5.7"
|
sys-info = "0.5.7"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -145,7 +145,7 @@ ledger_not_setup() {
|
|||||||
|
|
||||||
args=()
|
args=()
|
||||||
node_type=validator
|
node_type=validator
|
||||||
node_lamports=424242 # number of lamports to assign the node for transaction fees
|
node_lamports=424242424242 # number of lamports to assign the node for transaction fees
|
||||||
stake_lamports=42 # number of lamports to assign as stake
|
stake_lamports=42 # number of lamports to assign as stake
|
||||||
poll_for_new_genesis_block=0
|
poll_for_new_genesis_block=0
|
||||||
label=
|
label=
|
||||||
@ -153,7 +153,6 @@ identity_keypair_path=
|
|||||||
no_restart=0
|
no_restart=0
|
||||||
airdrops_enabled=1
|
airdrops_enabled=1
|
||||||
generate_snapshots=0
|
generate_snapshots=0
|
||||||
boot_from_snapshot=1
|
|
||||||
reset_ledger=0
|
reset_ledger=0
|
||||||
config_dir=
|
config_dir=
|
||||||
|
|
||||||
@ -174,7 +173,7 @@ while [[ -n $1 ]]; do
|
|||||||
generate_snapshots=1
|
generate_snapshots=1
|
||||||
shift
|
shift
|
||||||
elif [[ $1 = --no-snapshot ]]; then
|
elif [[ $1 = --no-snapshot ]]; then
|
||||||
boot_from_snapshot=0
|
# Ignore
|
||||||
shift
|
shift
|
||||||
elif [[ $1 = --validator ]]; then
|
elif [[ $1 = --validator ]]; then
|
||||||
node_type=validator
|
node_type=validator
|
||||||
@ -418,25 +417,6 @@ while true; do
|
|||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
echo "Fetched genesis ledger in $SECONDS seconds"
|
echo "Fetched genesis ledger in $SECONDS seconds"
|
||||||
|
|
||||||
if ((boot_from_snapshot)); then
|
|
||||||
SECONDS=
|
|
||||||
echo "Rsyncing state snapshot ${rsync_entrypoint_url:?}..."
|
|
||||||
if ! $rsync -P "${rsync_entrypoint_url:?}"/config/state.tgz .; then
|
|
||||||
echo "State snapshot rsync failed"
|
|
||||||
rm -f "$SOLANA_RSYNC_CONFIG_DIR"/state.tgz
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
echo "Fetched snapshot in $SECONDS seconds"
|
|
||||||
|
|
||||||
SECONDS=
|
|
||||||
mkdir -p "$state_dir"
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
tar -C "$state_dir" -zxf "$SOLANA_RSYNC_CONFIG_DIR"/state.tgz
|
|
||||||
)
|
|
||||||
echo "Extracted snapshot in $SECONDS seconds"
|
|
||||||
fi
|
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ default_arg --bootstrap-storage-keypair "$SOLANA_CONFIG_DIR"/bootstrap-leader-st
|
|||||||
default_arg --ledger "$SOLANA_RSYNC_CONFIG_DIR"/ledger
|
default_arg --ledger "$SOLANA_RSYNC_CONFIG_DIR"/ledger
|
||||||
default_arg --mint "$SOLANA_CONFIG_DIR"/mint-keypair.json
|
default_arg --mint "$SOLANA_CONFIG_DIR"/mint-keypair.json
|
||||||
default_arg --lamports 100000000000000
|
default_arg --lamports 100000000000000
|
||||||
default_arg --bootstrap-leader-lamports 424242
|
default_arg --bootstrap-leader-lamports 424242424242
|
||||||
default_arg --target-lamports-per-signature 42
|
default_arg --target-lamports-per-signature 42
|
||||||
default_arg --target-signatures-per-slot 42
|
default_arg --target-signatures-per-slot 42
|
||||||
default_arg --hashes-per-tick auto
|
default_arg --hashes-per-tick auto
|
||||||
|
@ -12,7 +12,7 @@ gce)
|
|||||||
# shellcheck source=net/scripts/gce-provider.sh
|
# shellcheck source=net/scripts/gce-provider.sh
|
||||||
source "$here"/scripts/gce-provider.sh
|
source "$here"/scripts/gce-provider.sh
|
||||||
|
|
||||||
cpuBootstrapLeaderMachineType="--machine-type n1-standard-16 --min-cpu-platform Intel%20Skylake"
|
cpuBootstrapLeaderMachineType="--custom-cpu 12 --custom-memory 32GB --min-cpu-platform Intel%20Skylake"
|
||||||
gpuBootstrapLeaderMachineType="$cpuBootstrapLeaderMachineType --accelerator count=1,type=nvidia-tesla-p100"
|
gpuBootstrapLeaderMachineType="$cpuBootstrapLeaderMachineType --accelerator count=1,type=nvidia-tesla-p100"
|
||||||
bootstrapLeaderMachineType=$cpuBootstrapLeaderMachineType
|
bootstrapLeaderMachineType=$cpuBootstrapLeaderMachineType
|
||||||
fullNodeMachineType=$cpuBootstrapLeaderMachineType
|
fullNodeMachineType=$cpuBootstrapLeaderMachineType
|
||||||
@ -412,7 +412,6 @@ EOF
|
|||||||
declare failOnFailure="$6"
|
declare failOnFailure="$6"
|
||||||
declare arrayName="$7"
|
declare arrayName="$7"
|
||||||
|
|
||||||
# This check should eventually be moved to cloud provider specific script
|
|
||||||
if [ "$publicIp" = "TERMINATED" ] || [ "$privateIp" = "TERMINATED" ]; then
|
if [ "$publicIp" = "TERMINATED" ] || [ "$privateIp" = "TERMINATED" ]; then
|
||||||
if $failOnFailure; then
|
if $failOnFailure; then
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -491,6 +491,8 @@ startClient() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sanity() {
|
sanity() {
|
||||||
|
declare skipBlockstreamerSanity=$1
|
||||||
|
|
||||||
$metricsWriteDatapoint "testnet-deploy net-sanity-begin=1"
|
$metricsWriteDatapoint "testnet-deploy net-sanity-begin=1"
|
||||||
|
|
||||||
declare ok=true
|
declare ok=true
|
||||||
@ -508,7 +510,7 @@ sanity() {
|
|||||||
) || ok=false
|
) || ok=false
|
||||||
$ok || exit 1
|
$ok || exit 1
|
||||||
|
|
||||||
if [[ -n $blockstreamer ]]; then
|
if [[ -z $skipBlockstreamerSanity && -n $blockstreamer ]]; then
|
||||||
# If there's a blockstreamer node run a reduced sanity check on it as well
|
# If there's a blockstreamer node run a reduced sanity check on it as well
|
||||||
echo "--- Sanity: $blockstreamer"
|
echo "--- Sanity: $blockstreamer"
|
||||||
(
|
(
|
||||||
@ -675,7 +677,8 @@ deploy() {
|
|||||||
stopNode "$ipAddress" true
|
stopNode "$ipAddress" true
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
sanity
|
sanity skipBlockstreamerSanity # skip sanity on blockstreamer node, it may not
|
||||||
|
# have caught up to the bootstrap leader yet
|
||||||
|
|
||||||
SECONDS=0
|
SECONDS=0
|
||||||
for ((i=0; i < "$numClients" && i < "$numClientsRequested"; i++)) do
|
for ((i=0; i < "$numClients" && i < "$numClientsRequested"; i++)) do
|
||||||
|
@ -246,7 +246,7 @@ local|tar|skip)
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export BLOCKEXPLORER_GEOIP_WHITELIST=$PWD/net/config/geoip.yml
|
export BLOCKEXPLORER_GEOIP_WHITELIST=$PWD/net/config/geoip.yml
|
||||||
npm install @solana/blockexplorer@1
|
npm install @solana/blockexplorer@1.41.0
|
||||||
npx solana-blockexplorer > blockexplorer.log 2>&1 &
|
npx solana-blockexplorer > blockexplorer.log 2>&1 &
|
||||||
|
|
||||||
# Confirm the blockexplorer is accessible
|
# Confirm the blockexplorer is accessible
|
||||||
|
@ -36,6 +36,17 @@ __cloud_FindInstances() {
|
|||||||
--filter "$filter" \
|
--filter "$filter" \
|
||||||
--format 'value(name,networkInterfaces[0].accessConfigs[0].natIP,networkInterfaces[0].networkIP,status,zone)' \
|
--format 'value(name,networkInterfaces[0].accessConfigs[0].natIP,networkInterfaces[0].networkIP,status,zone)' \
|
||||||
| grep RUNNING)
|
| grep RUNNING)
|
||||||
|
|
||||||
|
while read -r name status zone; do
|
||||||
|
privateIp=TERMINATED
|
||||||
|
publicIp=TERMINATED
|
||||||
|
printf "%-30s | publicIp=%-16s privateIp=%s status=%s zone=%s\n" "$name" "$publicIp" "$privateIp" "$status" "$zone"
|
||||||
|
|
||||||
|
instances+=("$name:$publicIp:$privateIp:$zone")
|
||||||
|
done < <(gcloud compute instances list \
|
||||||
|
--filter "$filter" \
|
||||||
|
--format 'value(name,status,zone)' \
|
||||||
|
| grep TERMINATED)
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -251,6 +262,9 @@ cloud_WaitForInstanceReady() {
|
|||||||
# declare instanceZone="$3"
|
# declare instanceZone="$3"
|
||||||
declare timeout="$4"
|
declare timeout="$4"
|
||||||
|
|
||||||
|
if [[ $instanceIp = "TERMINATED" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
timeout "${timeout}"s bash -c "set -o pipefail; until ping -c 3 $instanceIp | tr - _; do echo .; done"
|
timeout "${timeout}"s bash -c "set -o pipefail; until ping -c 3 $instanceIp | tr - _; do echo .; done"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +282,10 @@ cloud_FetchFile() {
|
|||||||
declare localFile="$4"
|
declare localFile="$4"
|
||||||
declare zone="$5"
|
declare zone="$5"
|
||||||
|
|
||||||
|
if [[ $publicIp = "TERMINATED" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
(
|
(
|
||||||
set -x
|
set -x
|
||||||
gcloud compute scp --zone "$zone" "$instanceName:$remoteFile" "$localFile"
|
gcloud compute scp --zone "$zone" "$instanceName:$remoteFile" "$localFile"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-netutil"
|
name = "solana-netutil"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Network Utilities"
|
description = "Solana Network Utilities"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -15,7 +15,7 @@ log = "0.4.7"
|
|||||||
nix = "0.14.1"
|
nix = "0.14.1"
|
||||||
rand = "0.6.1"
|
rand = "0.6.1"
|
||||||
socket2 = "0.3.9"
|
socket2 = "0.3.9"
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
tokio = "0.1"
|
tokio = "0.1"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-programs"
|
name = "solana-bpf-programs"
|
||||||
description = "Blockchain, Rebuilt for Scale"
|
description = "Blockchain, Rebuilt for Scale"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
documentation = "https://docs.rs/solana"
|
documentation = "https://docs.rs/solana"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@ -22,10 +22,10 @@ walkdir = "2"
|
|||||||
bincode = "1.1.4"
|
bincode = "1.1.4"
|
||||||
byteorder = "1.3.2"
|
byteorder = "1.3.2"
|
||||||
elf = "0.0.10"
|
elf = "0.0.10"
|
||||||
solana-bpf-loader-api = { path = "../bpf_loader_api", version = "0.17.0" }
|
solana-bpf-loader-api = { path = "../bpf_loader_api", version = "0.17.2" }
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana_rbpf = "=0.1.13"
|
solana_rbpf = "=0.1.13"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-128bit"
|
name = "solana-bpf-rust-128bit"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF iter program written in Rust"
|
description = "Solana BPF iter program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,12 +12,12 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "0.17.0" }
|
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "0.17.2" }
|
||||||
|
|
||||||
[dev_dependencies]
|
[dev_dependencies]
|
||||||
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/rust-test", version = "0.17.0" }
|
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/rust-test", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-128bit-dep"
|
name = "solana-bpf-rust-128bit-dep"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF many-args-dep program written in Rust"
|
description = "Solana BPF many-args-dep program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,10 +12,10 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
|
|
||||||
[dev_dependencies]
|
[dev_dependencies]
|
||||||
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/rust-test", version = "0.17.0" }
|
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/rust-test", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-alloc"
|
name = "solana-bpf-rust-alloc"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF alloc program written in Rust"
|
description = "Solana BPF alloc program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-dep-crate"
|
name = "solana-bpf-rust-dep-crate"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF dep-crate program written in Rust"
|
description = "Solana BPF dep-crate program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -13,8 +13,8 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = { version = "1", default-features = false }
|
byteorder = { version = "1", default-features = false }
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-external-spend"
|
name = "solana-bpf-rust-external-spend"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF external spend program written in Rust"
|
description = "Solana BPF external spend program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-iter"
|
name = "solana-bpf-rust-iter"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF iter program written in Rust"
|
description = "Solana BPF iter program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-many-args"
|
name = "solana-bpf-rust-many-args"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF many-args program written in Rust"
|
description = "Solana BPF many-args program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,9 +12,9 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "0.17.0" }
|
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-many-args-dep"
|
name = "solana-bpf-rust-many-args-dep"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF many-args-dep program written in Rust"
|
description = "Solana BPF many-args-dep program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,10 +12,10 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
|
|
||||||
[dev_dependencies]
|
[dev_dependencies]
|
||||||
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/rust-test", version = "0.17.0" }
|
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/rust-test", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-noop"
|
name = "solana-bpf-rust-noop"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF noop program written in Rust"
|
description = "Solana BPF noop program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-panic"
|
name = "solana-bpf-rust-panic"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF iter program written in Rust"
|
description = "Solana BPF iter program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-rust-tick-height"
|
name = "solana-bpf-rust-tick-height"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF noop program written in Rust"
|
description = "Solana BPF noop program written in Rust"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -13,8 +13,8 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = { version = "1", default-features = false }
|
byteorder = { version = "1", default-features = false }
|
||||||
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.0" }
|
solana-sdk-bpf-utils = { path = "../../../../sdk/bpf/rust/rust-utils", version = "0.17.2" }
|
||||||
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.0" }
|
solana-sdk-bpf-no-std = { path = "../../../../sdk/bpf/rust/rust-no-std", version = "0.17.2" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = []
|
members = []
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-loader-api"
|
name = "solana-bpf-loader-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF Loader"
|
description = "Solana BPF Loader"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -14,8 +14,8 @@ byteorder = "1.3.2"
|
|||||||
libc = "0.2.58"
|
libc = "0.2.58"
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana_rbpf = "=0.1.13"
|
solana_rbpf = "=0.1.13"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-bpf-loader-program"
|
name = "solana-bpf-loader-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana BPF Loader"
|
description = "Solana BPF Loader"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-bpf-loader-api = { path = "../bpf_loader_api", version = "0.17.0" }
|
solana-bpf-loader-api = { path = "../bpf_loader_api", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-budget-api"
|
name = "solana-budget-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Budget program API"
|
description = "Solana Budget program API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -16,10 +16,10 @@ num-derive = "0.2"
|
|||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-budget-program"
|
name = "solana-budget-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana budget program"
|
description = "Solana budget program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-budget-api = { path = "../budget_api", version = "0.17.0" }
|
solana-budget-api = { path = "../budget_api", version = "0.17.2" }
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-config-api"
|
name = "solana-config-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "config program API"
|
description = "config program API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -13,11 +13,11 @@ bincode = "1.1.4"
|
|||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-config-program"
|
name = "solana-config-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "config program"
|
description = "config program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-config-api = { path = "../config_api", version = "0.17.0" }
|
solana-config-api = { path = "../config_api", version = "0.17.2" }
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-exchange-api"
|
name = "solana-exchange-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Exchange program API"
|
description = "Solana Exchange program API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -13,12 +13,12 @@ bincode = "1.1.4"
|
|||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../../metrics", version = "0.17.0" }
|
solana-metrics = { path = "../../metrics", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-exchange-program"
|
name = "solana-exchange-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana exchange program"
|
description = "Solana exchange program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-exchange-api = { path = "../exchange_api", version = "0.17.0" }
|
solana-exchange-api = { path = "../exchange_api", version = "0.17.2" }
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-failure-program"
|
name = "solana-failure-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana failure program"
|
description = "Solana failure program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,10 +10,10 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
3
programs/librapay_api/.gitignore
vendored
Normal file
3
programs/librapay_api/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/farf/
|
||||||
|
/target/
|
||||||
|
Cargo.lock
|
23
programs/librapay_api/Cargo.toml
Normal file
23
programs/librapay_api/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[package]
|
||||||
|
name = "solana-librapay-api"
|
||||||
|
version = "0.17.2"
|
||||||
|
description = "Solana Libra Payment"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
homepage = "https://solana.com/"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bincode = "1.1.4"
|
||||||
|
log = "0.4.2"
|
||||||
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
|
types = { version = "0.0.0-sol15", package = "solana_libra_types" }
|
||||||
|
language_e2e_tests = { version = "0.0.0-sol15", package = "solana_libra_language_e2e_tests" }
|
||||||
|
solana-move-loader-api = { path = "../move_loader_api", version = "0.17.2" }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["lib"]
|
||||||
|
name = "solana_librapay_api"
|
89
programs/librapay_api/src/lib.rs
Normal file
89
programs/librapay_api/src/lib.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
const LIBRAPAY_PROGRAM_ID: [u8; 32] = [
|
||||||
|
5, 13, 18, 222, 165, 11, 80, 225, 56, 103, 125, 38, 15, 252, 181, 16, 125, 99, 110, 106, 186,
|
||||||
|
28, 136, 119, 235, 245, 20, 80, 0, 0, 0, 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
solana_sdk::solana_name_id!(
|
||||||
|
LIBRAPAY_PROGRAM_ID,
|
||||||
|
"LibraPay11111111111111111111111111111111111"
|
||||||
|
);
|
||||||
|
|
||||||
|
pub mod librapay_instruction;
|
||||||
|
pub mod librapay_transaction;
|
||||||
|
|
||||||
|
extern crate solana_move_loader_api;
|
||||||
|
|
||||||
|
use solana_move_loader_api::account_state::LibraAccountState;
|
||||||
|
use solana_runtime::loader_utils::load_program;
|
||||||
|
use solana_sdk::account::KeyedAccount;
|
||||||
|
use solana_sdk::client::Client;
|
||||||
|
use solana_sdk::instruction::InstructionError;
|
||||||
|
use solana_sdk::message::Message;
|
||||||
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
|
use solana_sdk::system_instruction;
|
||||||
|
|
||||||
|
use types::account_address::AccountAddress;
|
||||||
|
|
||||||
|
pub fn create_genesis<T: Client>(from_key: &Keypair, client: &T, amount: u64) -> Keypair {
|
||||||
|
let libra_genesis_key = Keypair::new();
|
||||||
|
|
||||||
|
let instruction = system_instruction::create_account(
|
||||||
|
&from_key.pubkey(),
|
||||||
|
&libra_genesis_key.pubkey(),
|
||||||
|
1,
|
||||||
|
bincode::serialize(&LibraAccountState::create_genesis(1))
|
||||||
|
.unwrap()
|
||||||
|
.len() as u64,
|
||||||
|
&solana_move_loader_api::id(),
|
||||||
|
);
|
||||||
|
client.send_instruction(&from_key, instruction).unwrap();
|
||||||
|
|
||||||
|
let instruction = librapay_instruction::genesis(&libra_genesis_key.pubkey(), amount);
|
||||||
|
let message = Message::new_with_payer(vec![instruction], Some(&from_key.pubkey()));
|
||||||
|
client
|
||||||
|
.send_message(&[from_key, &libra_genesis_key], message)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
libra_genesis_key
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upload_move_program<T: Client>(from: &Keypair, client: &T, code: &str) -> Pubkey {
|
||||||
|
let address = AccountAddress::default();
|
||||||
|
let account_state = LibraAccountState::create_program(&address, code, vec![]);
|
||||||
|
let program_bytes = bincode::serialize(&account_state).unwrap();
|
||||||
|
|
||||||
|
load_program(client, &from, &solana_move_loader_api::id(), program_bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upload_mint_program<T: Client>(from: &Keypair, client: &T) -> Pubkey {
|
||||||
|
let code = "
|
||||||
|
import 0x0.LibraAccount;
|
||||||
|
import 0x0.LibraCoin;
|
||||||
|
main(payee: address, amount: u64) {
|
||||||
|
LibraAccount.mint_to_address(move(payee), move(amount));
|
||||||
|
return;
|
||||||
|
}";
|
||||||
|
upload_move_program(from, client, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn upload_payment_program<T: Client>(from: &Keypair, client: &T) -> Pubkey {
|
||||||
|
let code = "
|
||||||
|
import 0x0.LibraAccount;
|
||||||
|
import 0x0.LibraCoin;
|
||||||
|
main(payee: address, amount: u64) {
|
||||||
|
LibraAccount.pay_from_sender(move(payee), move(amount));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
upload_move_program(from, client, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_instruction(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
keyed_accounts: &mut [KeyedAccount],
|
||||||
|
data: &[u8],
|
||||||
|
) -> Result<(), InstructionError> {
|
||||||
|
solana_move_loader_api::processor::process_instruction(program_id, keyed_accounts, data)
|
||||||
|
}
|
98
programs/librapay_api/src/librapay_instruction.rs
Normal file
98
programs/librapay_api/src/librapay_instruction.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
use bincode;
|
||||||
|
use solana_move_loader_api::account_state::pubkey_to_address;
|
||||||
|
use solana_move_loader_api::processor::InvokeCommand;
|
||||||
|
use solana_sdk::instruction::{AccountMeta, Instruction};
|
||||||
|
use solana_sdk::loader_instruction::LoaderInstruction;
|
||||||
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
use types::account_address::AccountAddress;
|
||||||
|
use types::transaction::TransactionArgument;
|
||||||
|
|
||||||
|
pub fn genesis(genesis_pubkey: &Pubkey, microlibras: u64) -> Instruction {
|
||||||
|
let data = bincode::serialize(&InvokeCommand::CreateGenesis(microlibras)).unwrap();
|
||||||
|
let ix_data = LoaderInstruction::InvokeMain { data };
|
||||||
|
|
||||||
|
let accounts = vec![AccountMeta::new(*genesis_pubkey, true)];
|
||||||
|
|
||||||
|
Instruction::new(solana_move_loader_api::id(), &ix_data, accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mint(
|
||||||
|
program_pubkey: &Pubkey,
|
||||||
|
from_pubkey: &Pubkey,
|
||||||
|
to_pubkey: &Pubkey,
|
||||||
|
microlibras: u64,
|
||||||
|
) -> Instruction {
|
||||||
|
let args = vec![
|
||||||
|
TransactionArgument::Address(pubkey_to_address(to_pubkey)),
|
||||||
|
TransactionArgument::U64(microlibras),
|
||||||
|
];
|
||||||
|
|
||||||
|
let data = bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: AccountAddress::default(),
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let ix_data = LoaderInstruction::InvokeMain { data };
|
||||||
|
|
||||||
|
let accounts = vec![
|
||||||
|
AccountMeta::new_credit_only(*program_pubkey, false),
|
||||||
|
AccountMeta::new(*from_pubkey, true),
|
||||||
|
AccountMeta::new(*to_pubkey, false),
|
||||||
|
];
|
||||||
|
|
||||||
|
Instruction::new(solana_move_loader_api::id(), &ix_data, accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transfer(
|
||||||
|
program_pubkey: &Pubkey,
|
||||||
|
mint_pubkey: &Pubkey,
|
||||||
|
from_pubkey: &Pubkey,
|
||||||
|
to_pubkey: &Pubkey,
|
||||||
|
microlibras: u64,
|
||||||
|
) -> Instruction {
|
||||||
|
let args = vec![
|
||||||
|
TransactionArgument::Address(pubkey_to_address(to_pubkey)),
|
||||||
|
TransactionArgument::U64(microlibras),
|
||||||
|
];
|
||||||
|
|
||||||
|
let data = bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: pubkey_to_address(from_pubkey),
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let ix_data = LoaderInstruction::InvokeMain { data };
|
||||||
|
|
||||||
|
let accounts = vec![
|
||||||
|
AccountMeta::new_credit_only(*program_pubkey, false),
|
||||||
|
AccountMeta::new_credit_only(*mint_pubkey, false),
|
||||||
|
AccountMeta::new(*from_pubkey, true),
|
||||||
|
AccountMeta::new(*to_pubkey, false),
|
||||||
|
];
|
||||||
|
|
||||||
|
Instruction::new(solana_move_loader_api::id(), &ix_data, accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pay() {
|
||||||
|
let from = Pubkey::new_rand();
|
||||||
|
let to = Pubkey::new_rand();
|
||||||
|
let program_id = Pubkey::new_rand();
|
||||||
|
let mint_id = Pubkey::new_rand();
|
||||||
|
transfer(&program_id, &mint_id, &from, &to, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mint() {
|
||||||
|
let program_id = Pubkey::new_rand();
|
||||||
|
let from = Pubkey::new_rand();
|
||||||
|
let to = Pubkey::new_rand();
|
||||||
|
|
||||||
|
mint(&program_id, &from, &to, 1);
|
||||||
|
}
|
||||||
|
}
|
217
programs/librapay_api/src/librapay_transaction.rs
Normal file
217
programs/librapay_api/src/librapay_transaction.rs
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
use crate::librapay_instruction;
|
||||||
|
use language_e2e_tests::account::AccountResource;
|
||||||
|
use log::*;
|
||||||
|
use solana_move_loader_api::account_state::{pubkey_to_address, LibraAccountState};
|
||||||
|
use solana_move_loader_api::data_store::DataStore;
|
||||||
|
use solana_sdk::client::Client;
|
||||||
|
use solana_sdk::hash::Hash;
|
||||||
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
|
use solana_sdk::system_instruction;
|
||||||
|
use solana_sdk::transaction::Transaction;
|
||||||
|
use std::boxed::Box;
|
||||||
|
use std::error;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub fn create_genesis(
|
||||||
|
genesis_keypair: &Keypair,
|
||||||
|
microlibras: u64,
|
||||||
|
recent_blockhash: Hash,
|
||||||
|
) -> Transaction {
|
||||||
|
let ix = librapay_instruction::genesis(&genesis_keypair.pubkey(), microlibras);
|
||||||
|
Transaction::new_signed_with_payer(
|
||||||
|
vec![ix],
|
||||||
|
Some(&genesis_keypair.pubkey()),
|
||||||
|
&[genesis_keypair],
|
||||||
|
recent_blockhash,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mint_tokens(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
payer: &Keypair,
|
||||||
|
mint: &Keypair,
|
||||||
|
to: &Pubkey,
|
||||||
|
microlibras: u64,
|
||||||
|
recent_blockhash: Hash,
|
||||||
|
) -> Transaction {
|
||||||
|
let ix = librapay_instruction::mint(program_id, &mint.pubkey(), to, microlibras);
|
||||||
|
Transaction::new_signed_with_payer(
|
||||||
|
vec![ix],
|
||||||
|
Some(&payer.pubkey()),
|
||||||
|
&[payer, mint],
|
||||||
|
recent_blockhash,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transfer(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
mint: &Pubkey,
|
||||||
|
payer: &Keypair,
|
||||||
|
from: &Keypair,
|
||||||
|
to: &Pubkey,
|
||||||
|
microlibras: u64,
|
||||||
|
recent_blockhash: Hash,
|
||||||
|
) -> Transaction {
|
||||||
|
let ix = librapay_instruction::transfer(program_id, mint, &from.pubkey(), to, microlibras);
|
||||||
|
Transaction::new_signed_with_payer(
|
||||||
|
vec![ix],
|
||||||
|
Some(&payer.pubkey()),
|
||||||
|
&[payer, from],
|
||||||
|
recent_blockhash,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_accounts(
|
||||||
|
from: &Keypair,
|
||||||
|
tos: &[Pubkey],
|
||||||
|
lamports: u64,
|
||||||
|
recent_blockhash: Hash,
|
||||||
|
) -> Transaction {
|
||||||
|
let instructions = tos
|
||||||
|
.iter()
|
||||||
|
.map(|to| {
|
||||||
|
system_instruction::create_account(
|
||||||
|
&from.pubkey(),
|
||||||
|
to,
|
||||||
|
lamports,
|
||||||
|
128,
|
||||||
|
&solana_move_loader_api::id(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Transaction::new_signed_instructions(&[from], instructions, recent_blockhash)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_account(
|
||||||
|
from: &Keypair,
|
||||||
|
to: &Pubkey,
|
||||||
|
lamports: u64,
|
||||||
|
recent_blockhash: Hash,
|
||||||
|
) -> Transaction {
|
||||||
|
create_accounts(from, &[*to], lamports, recent_blockhash)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum LibrapayError {
|
||||||
|
UnknownAccountState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LibrapayError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for LibrapayError {}
|
||||||
|
|
||||||
|
pub fn get_libra_balance<T: Client>(
|
||||||
|
client: &T,
|
||||||
|
account_address: &Pubkey,
|
||||||
|
) -> Result<u64, Box<dyn error::Error>> {
|
||||||
|
let account = client.get_account_data(&account_address)?;
|
||||||
|
if let Some(account) = account {
|
||||||
|
let mut data_store = DataStore::default();
|
||||||
|
match bincode::deserialize(&account)? {
|
||||||
|
LibraAccountState::User(_, write_set) => {
|
||||||
|
data_store.apply_write_set(&write_set);
|
||||||
|
}
|
||||||
|
LibraAccountState::Unallocated => {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
state => {
|
||||||
|
info!("Unknown account state: {:?}", state);
|
||||||
|
return Err(LibrapayError::UnknownAccountState)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let resource = data_store
|
||||||
|
.read_account_resource(&pubkey_to_address(account_address))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let res = AccountResource::read_balance(&resource);
|
||||||
|
Ok(res)
|
||||||
|
} else {
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::{create_genesis, upload_mint_program, upload_payment_program};
|
||||||
|
use solana_runtime::bank::Bank;
|
||||||
|
use solana_runtime::bank_client::BankClient;
|
||||||
|
use solana_sdk::genesis_block::create_genesis_block;
|
||||||
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
fn create_bank(lamports: u64) -> (Arc<Bank>, Keypair, Keypair, Pubkey, Pubkey) {
|
||||||
|
let (genesis_block, mint_keypair) = create_genesis_block(lamports);
|
||||||
|
let mut bank = Bank::new(&genesis_block);
|
||||||
|
bank.add_instruction_processor(
|
||||||
|
solana_move_loader_api::id(),
|
||||||
|
solana_move_loader_api::processor::process_instruction,
|
||||||
|
);
|
||||||
|
let shared_bank = Arc::new(bank);
|
||||||
|
let bank_client = BankClient::new_shared(&shared_bank);
|
||||||
|
let genesis_keypair = create_genesis(&mint_keypair, &bank_client, 1_000_000);
|
||||||
|
let mint_program_pubkey = upload_mint_program(&mint_keypair, &bank_client);
|
||||||
|
let program_pubkey = upload_payment_program(&mint_keypair, &bank_client);
|
||||||
|
(
|
||||||
|
shared_bank,
|
||||||
|
mint_keypair,
|
||||||
|
genesis_keypair,
|
||||||
|
mint_program_pubkey,
|
||||||
|
program_pubkey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_transfer() {
|
||||||
|
let (bank, mint_keypair, libra_genesis_keypair, mint_program_id, program_id) =
|
||||||
|
create_bank(10_000);
|
||||||
|
let from = Keypair::new();
|
||||||
|
let to = Keypair::new();
|
||||||
|
|
||||||
|
let tx = create_accounts(
|
||||||
|
&mint_keypair,
|
||||||
|
&[from.pubkey(), to.pubkey()],
|
||||||
|
1,
|
||||||
|
bank.last_blockhash(),
|
||||||
|
);
|
||||||
|
bank.process_transaction(&tx).unwrap();
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"created accounts: mint: {} libra_mint: {}",
|
||||||
|
mint_keypair.pubkey(),
|
||||||
|
libra_genesis_keypair.pubkey()
|
||||||
|
);
|
||||||
|
info!(" from: {} to: {}", from.pubkey(), to.pubkey());
|
||||||
|
|
||||||
|
let tx = mint_tokens(
|
||||||
|
&mint_program_id,
|
||||||
|
&mint_keypair,
|
||||||
|
&libra_genesis_keypair,
|
||||||
|
&from.pubkey(),
|
||||||
|
1,
|
||||||
|
bank.last_blockhash(),
|
||||||
|
);
|
||||||
|
bank.process_transaction(&tx).unwrap();
|
||||||
|
let client = BankClient::new_shared(&bank);
|
||||||
|
assert_eq!(1, get_libra_balance(&client, &from.pubkey()).unwrap());
|
||||||
|
|
||||||
|
info!("passed mint... doing another transfer..");
|
||||||
|
|
||||||
|
let tx = transfer(
|
||||||
|
&program_id,
|
||||||
|
&libra_genesis_keypair.pubkey(),
|
||||||
|
&mint_keypair,
|
||||||
|
&from,
|
||||||
|
&to.pubkey(),
|
||||||
|
1,
|
||||||
|
bank.last_blockhash(),
|
||||||
|
);
|
||||||
|
bank.process_transaction(&tx).unwrap();
|
||||||
|
assert_eq!(1, get_libra_balance(&client, &to.pubkey()).unwrap());
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-move-loader-api"
|
name = "solana-move-loader-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Move Loader"
|
description = "Solana Move Loader"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -17,19 +17,19 @@ log = "0.4.2"
|
|||||||
serde = "1.0.94"
|
serde = "1.0.94"
|
||||||
serde_derive = "1.0.94"
|
serde_derive = "1.0.94"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
bytecode_verifier = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_bytecode_verifier" }
|
bytecode_verifier = { version = "0.0.0-sol15", package = "solana_libra_bytecode_verifier" }
|
||||||
compiler = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_compiler" }
|
compiler = { version = "0.0.0-sol15", package = "solana_libra_compiler" }
|
||||||
failure = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_failure_ext" }
|
failure = { version = "0.0.0-sol15", package = "solana_libra_failure_ext" }
|
||||||
language_e2e_tests = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_language_e2e_tests" }
|
language_e2e_tests = { version = "0.0.0-sol15", package = "solana_libra_language_e2e_tests" }
|
||||||
state_view = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_state_view" }
|
state_view = { version = "0.0.0-sol15", package = "solana_libra_state_view" }
|
||||||
stdlib = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_stdlib" }
|
stdlib = { version = "0.0.0-sol15", package = "solana_libra_stdlib" }
|
||||||
types = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_types" }
|
types = { version = "0.0.0-sol15", package = "solana_libra_types" }
|
||||||
vm = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_vm" }
|
vm = { version = "0.0.0-sol15", package = "solana_libra_vm" }
|
||||||
vm_cache_map = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_vm_cache_map" }
|
vm_cache_map = { version = "0.0.0-sol15", package = "solana_libra_vm_cache_map" }
|
||||||
vm_runtime = { git = "https://github.com/solana-labs/libra", tag = "v0.0.0-sol13.2", package = "solana_libra_vm_runtime" }
|
vm_runtime = { version = "0.0.0-sol15", package = "solana_libra_vm_runtime" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::data_store::DataStore;
|
use crate::data_store::DataStore;
|
||||||
|
use crate::error_mappers::*;
|
||||||
use bytecode_verifier::VerifiedModule;
|
use bytecode_verifier::VerifiedModule;
|
||||||
use compiler::Compiler;
|
use compiler::Compiler;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::{instruction::InstructionError, pubkey::Pubkey};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use stdlib::stdlib_modules;
|
use stdlib::stdlib_modules;
|
||||||
use types::{
|
use types::{
|
||||||
@ -47,8 +48,8 @@ pub enum LibraAccountState {
|
|||||||
script_bytes: Vec<u8>,
|
script_bytes: Vec<u8>,
|
||||||
modules_bytes: Vec<Vec<u8>>,
|
modules_bytes: Vec<Vec<u8>>,
|
||||||
},
|
},
|
||||||
/// Write set containing a Libra account's data
|
/// Associated genesis account and the write set containing the Libra account data
|
||||||
User(WriteSet),
|
User(Pubkey, WriteSet),
|
||||||
/// Write sets containing the mint and stdlib modules
|
/// Write sets containing the mint and stdlib modules
|
||||||
Genesis(WriteSet),
|
Genesis(WriteSet),
|
||||||
}
|
}
|
||||||
@ -62,12 +63,12 @@ impl LibraAccountState {
|
|||||||
code: &str,
|
code: &str,
|
||||||
deps: Vec<&Vec<u8>>,
|
deps: Vec<&Vec<u8>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Compiler needs all the dependencies all the dependency module's account's
|
// Compiler needs all the dependencies and the dependency module's account's
|
||||||
// data into `VerifiedModules`
|
// data into `VerifiedModules`
|
||||||
let mut extra_deps: Vec<VerifiedModule> = vec![];
|
let mut extra_deps: Vec<VerifiedModule> = vec![];
|
||||||
for dep in deps {
|
for dep in deps {
|
||||||
let state: LibraAccountState = bincode::deserialize(&dep).unwrap();
|
let state: Self = bincode::deserialize(&dep).unwrap();
|
||||||
if let LibraAccountState::User(write_set) = state {
|
if let LibraAccountState::User(_, write_set) = state {
|
||||||
for (_, write_op) in write_set.iter() {
|
for (_, write_op) in write_set.iter() {
|
||||||
if let WriteOp::Value(raw_bytes) = write_op {
|
if let WriteOp::Value(raw_bytes) = write_op {
|
||||||
extra_deps.push(
|
extra_deps.push(
|
||||||
@ -93,7 +94,7 @@ impl LibraAccountState {
|
|||||||
.serialize(&mut script_bytes)
|
.serialize(&mut script_bytes)
|
||||||
.expect("Unable to serialize script");
|
.expect("Unable to serialize script");
|
||||||
let mut modules_bytes = vec![];
|
let mut modules_bytes = vec![];
|
||||||
for module in compiled_program.modules.iter() {
|
for module in &compiled_program.modules {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
module
|
module
|
||||||
.serialize(&mut buf)
|
.serialize(&mut buf)
|
||||||
@ -106,11 +107,11 @@ impl LibraAccountState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_user(write_set: WriteSet) -> Self {
|
pub fn create_user(owner: &Pubkey, write_set: WriteSet) -> Self {
|
||||||
LibraAccountState::User(write_set)
|
LibraAccountState::User(*owner, write_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_genesis(mint_balance: u64) -> Self {
|
pub fn create_genesis(mint_balance: u64) -> Result<(Self), InstructionError> {
|
||||||
let modules = stdlib_modules();
|
let modules = stdlib_modules();
|
||||||
let arena = Arena::new();
|
let arena = Arena::new();
|
||||||
let state_view = DataStore::default();
|
let state_view = DataStore::default();
|
||||||
@ -130,11 +131,14 @@ impl LibraAccountState {
|
|||||||
txn_data.sender = mint_address;
|
txn_data.sender = mint_address;
|
||||||
|
|
||||||
let mut txn_executor = TransactionExecutor::new(&block_cache, &data_cache, txn_data);
|
let mut txn_executor = TransactionExecutor::new(&block_cache, &data_cache, txn_data);
|
||||||
txn_executor.create_account(mint_address).unwrap().unwrap();
|
txn_executor
|
||||||
|
.create_account(mint_address)
|
||||||
|
.map_err(map_vm_invariant_violation_error)?
|
||||||
|
.map_err(map_vm_runtime_error)?;
|
||||||
txn_executor
|
txn_executor
|
||||||
.execute_function(&COIN_MODULE, "initialize", vec![])
|
.execute_function(&COIN_MODULE, "initialize", vec![])
|
||||||
.unwrap()
|
.map_err(map_vm_invariant_violation_error)?
|
||||||
.unwrap();
|
.map_err(map_vm_runtime_error)?;
|
||||||
|
|
||||||
txn_executor
|
txn_executor
|
||||||
.execute_function(
|
.execute_function(
|
||||||
@ -142,8 +146,8 @@ impl LibraAccountState {
|
|||||||
"mint_to_address",
|
"mint_to_address",
|
||||||
vec![Local::address(mint_address), Local::u64(mint_balance)],
|
vec![Local::address(mint_address), Local::u64(mint_balance)],
|
||||||
)
|
)
|
||||||
.unwrap()
|
.map_err(map_vm_invariant_violation_error)?
|
||||||
.unwrap();
|
.map_err(map_vm_runtime_error)?;
|
||||||
|
|
||||||
txn_executor
|
txn_executor
|
||||||
.execute_function(
|
.execute_function(
|
||||||
@ -151,28 +155,26 @@ impl LibraAccountState {
|
|||||||
"rotate_authentication_key",
|
"rotate_authentication_key",
|
||||||
vec![Local::bytearray(genesis_auth_key)],
|
vec![Local::bytearray(genesis_auth_key)],
|
||||||
)
|
)
|
||||||
.unwrap()
|
.map_err(map_vm_invariant_violation_error)?
|
||||||
.unwrap();
|
.map_err(map_vm_runtime_error)?;
|
||||||
|
|
||||||
let stdlib_modules = modules
|
let mut stdlib_modules = vec![];
|
||||||
.iter()
|
for module in modules.iter() {
|
||||||
.map(|m| {
|
let mut buf = vec![];
|
||||||
let mut module_vec = vec![];
|
module.serialize(&mut buf).map_err(map_failure_error)?;
|
||||||
m.serialize(&mut module_vec).unwrap();
|
stdlib_modules.push((module.self_id(), buf));
|
||||||
(m.self_id(), module_vec)
|
}
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
txn_executor
|
txn_executor
|
||||||
.make_write_set(stdlib_modules, Ok(Ok(())))
|
.make_write_set(stdlib_modules, Ok(Ok(())))
|
||||||
.unwrap()
|
.map_err(map_vm_runtime_error)?
|
||||||
.write_set()
|
.write_set()
|
||||||
.clone()
|
.clone()
|
||||||
.into_mut()
|
.into_mut()
|
||||||
}
|
}
|
||||||
.freeze()
|
.freeze()
|
||||||
.unwrap();
|
.map_err(map_failure_error)?;
|
||||||
|
|
||||||
LibraAccountState::Genesis(write_set)
|
Ok(LibraAccountState::Genesis(write_set))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ pub struct DataStore {
|
|||||||
impl DataStore {
|
impl DataStore {
|
||||||
/// Creates a new `DataStore` with the provided initial data.
|
/// Creates a new `DataStore` with the provided initial data.
|
||||||
pub fn new(data: IndexMap<AccessPath, Vec<u8>>) -> Self {
|
pub fn new(data: IndexMap<AccessPath, Vec<u8>>) -> Self {
|
||||||
DataStore { data }
|
Self { data }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies a [`WriteSet`] to this data store.
|
/// Applies a [`WriteSet`] to this data store.
|
||||||
|
42
programs/move_loader_api/src/error_mappers.rs
Normal file
42
programs/move_loader_api/src/error_mappers.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//! Mapping functions to Instruction errors
|
||||||
|
|
||||||
|
use log::*;
|
||||||
|
use solana_sdk::instruction::InstructionError;
|
||||||
|
use vm::file_format::CompiledModule;
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
pub fn map_vm_runtime_error(err: vm::errors::VMRuntimeError) -> InstructionError {
|
||||||
|
debug!("Execution failed: {:?}", err);
|
||||||
|
match err.err {
|
||||||
|
vm::errors::VMErrorKind::OutOfGasError => InstructionError::InsufficientFunds,
|
||||||
|
_ => InstructionError::GenericError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn map_vm_invariant_violation_error(err: vm::errors::VMInvariantViolation) -> InstructionError {
|
||||||
|
debug!("Error: Execution failed: {:?}", err);
|
||||||
|
InstructionError::GenericError
|
||||||
|
}
|
||||||
|
pub fn map_vm_binary_error(err: vm::errors::BinaryError) -> InstructionError {
|
||||||
|
debug!("Error: Script deserialize failed: {:?}", err);
|
||||||
|
InstructionError::InvalidInstructionData
|
||||||
|
}
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
pub fn map_data_error(err: std::boxed::Box<bincode::ErrorKind>) -> InstructionError {
|
||||||
|
debug!("Error: Account data: {:?}", err);
|
||||||
|
InstructionError::InvalidAccountData
|
||||||
|
}
|
||||||
|
pub fn map_vm_verification_error(
|
||||||
|
err: (CompiledModule, Vec<vm::errors::VerificationError>),
|
||||||
|
) -> InstructionError {
|
||||||
|
debug!("Error: Script verification failed: {:?}", err.1);
|
||||||
|
InstructionError::InvalidInstructionData
|
||||||
|
}
|
||||||
|
pub fn map_failure_error(err: failure::Error) -> InstructionError {
|
||||||
|
debug!("Error: Script verification failed: {:?}", err);
|
||||||
|
InstructionError::InvalidInstructionData
|
||||||
|
}
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
pub fn missing_account() -> InstructionError {
|
||||||
|
debug!("Error: Missing account");
|
||||||
|
InstructionError::InvalidAccountData
|
||||||
|
}
|
@ -1,13 +1,14 @@
|
|||||||
pub mod account_state;
|
pub mod account_state;
|
||||||
pub mod data_store;
|
pub mod data_store;
|
||||||
|
pub mod error_mappers;
|
||||||
pub mod processor;
|
pub mod processor;
|
||||||
|
|
||||||
const MOVE_LOADER_PROGRAM_ID: [u8; 32] = [
|
const MOVE_LOADER_PROGRAM_ID: [u8; 32] = [
|
||||||
5, 91, 237, 31, 90, 253, 197, 145, 157, 236, 147, 43, 6, 5, 157, 238, 63, 151, 181, 165, 118,
|
5, 84, 172, 160, 172, 5, 64, 41, 134, 4, 81, 31, 45, 11, 30, 64, 219, 238, 140, 38, 194, 100,
|
||||||
224, 198, 97, 103, 136, 113, 64, 0, 0, 0, 0,
|
192, 219, 156, 94, 62, 208, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
solana_sdk::solana_name_id!(
|
solana_sdk::solana_name_id!(
|
||||||
MOVE_LOADER_PROGRAM_ID,
|
MOVE_LOADER_PROGRAM_ID,
|
||||||
"MvLdr11111111111111111111111111111111111111"
|
"MoveLdr111111111111111111111111111111111111"
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::account_state::{pubkey_to_address, LibraAccountState};
|
use crate::account_state::{pubkey_to_address, LibraAccountState};
|
||||||
use crate::data_store::DataStore;
|
use crate::data_store::DataStore;
|
||||||
|
use crate::error_mappers::*;
|
||||||
use crate::id;
|
use crate::id;
|
||||||
use bytecode_verifier::{VerifiedModule, VerifiedScript};
|
use bytecode_verifier::{VerifiedModule, VerifiedScript};
|
||||||
use log::*;
|
use log::*;
|
||||||
@ -44,11 +45,11 @@ pub fn process_instruction(
|
|||||||
|
|
||||||
match command {
|
match command {
|
||||||
LoaderInstruction::Write { offset, bytes } => {
|
LoaderInstruction::Write { offset, bytes } => {
|
||||||
MoveProcessor::do_write(keyed_accounts, offset, bytes)
|
MoveProcessor::do_write(keyed_accounts, offset, &bytes)
|
||||||
}
|
}
|
||||||
LoaderInstruction::Finalize => MoveProcessor::do_finalize(keyed_accounts),
|
LoaderInstruction::Finalize => MoveProcessor::do_finalize(keyed_accounts),
|
||||||
LoaderInstruction::InvokeMain { data } => {
|
LoaderInstruction::InvokeMain { data } => {
|
||||||
MoveProcessor::do_invoke_main(keyed_accounts, data)
|
MoveProcessor::do_invoke_main(keyed_accounts, &data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,52 +57,25 @@ pub fn process_instruction(
|
|||||||
pub const PROGRAM_INDEX: usize = 0;
|
pub const PROGRAM_INDEX: usize = 0;
|
||||||
pub const GENESIS_INDEX: usize = 1;
|
pub const GENESIS_INDEX: usize = 1;
|
||||||
|
|
||||||
// TODO: Not quite right yet
|
/// Command to invoke
|
||||||
/// Invoke information passed via the Invoke Instruction
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[derive(Default, Debug, Serialize, Deserialize)]
|
pub enum InvokeCommand {
|
||||||
pub struct InvokeInfo {
|
/// Create a new genesis account
|
||||||
/// Sender of the "transaction", the "sender" who is calling this program
|
CreateGenesis(u64),
|
||||||
sender_address: AccountAddress,
|
/// Run a Move program
|
||||||
/// Name of the function to call
|
RunProgram {
|
||||||
function_name: String,
|
/// Sender of the "transaction", the "sender" who is running this program
|
||||||
/// Arguments to pass to the program being invoked
|
sender_address: AccountAddress,
|
||||||
args: Vec<TransactionArgument>,
|
/// Name of the program's function to call
|
||||||
|
function_name: String,
|
||||||
|
/// Arguments to pass to the program being called
|
||||||
|
args: Vec<TransactionArgument>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MoveProcessor {}
|
pub struct MoveProcessor {}
|
||||||
|
|
||||||
impl MoveProcessor {
|
impl MoveProcessor {
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
|
||||||
fn map_vm_runtime_error(err: vm::errors::VMRuntimeError) -> InstructionError {
|
|
||||||
debug!("Execution failed: {:?}", err);
|
|
||||||
match err.err {
|
|
||||||
vm::errors::VMErrorKind::OutOfGasError => InstructionError::InsufficientFunds,
|
|
||||||
_ => InstructionError::GenericError,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn map_vm_invariant_violation_error(err: vm::errors::VMInvariantViolation) -> InstructionError {
|
|
||||||
debug!("Error: Execution failed: {:?}", err);
|
|
||||||
InstructionError::GenericError
|
|
||||||
}
|
|
||||||
fn map_vm_binary_error(err: vm::errors::BinaryError) -> InstructionError {
|
|
||||||
debug!("Error: Script deserialize failed: {:?}", err);
|
|
||||||
InstructionError::InvalidInstructionData
|
|
||||||
}
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
|
||||||
fn map_data_error(err: std::boxed::Box<bincode::ErrorKind>) -> InstructionError {
|
|
||||||
debug!("Error: Account data: {:?}", err);
|
|
||||||
InstructionError::InvalidAccountData
|
|
||||||
}
|
|
||||||
fn map_vm_verification_error(
|
|
||||||
err: (CompiledModule, Vec<vm::errors::VerificationError>),
|
|
||||||
) -> InstructionError {
|
|
||||||
debug!("Error: Script verification failed: {:?}", err.1);
|
|
||||||
InstructionError::InvalidInstructionData
|
|
||||||
}
|
|
||||||
fn map_failure_error(err: failure::Error) -> InstructionError {
|
|
||||||
debug!("Error: Script verification failed: {:?}", err);
|
|
||||||
InstructionError::InvalidInstructionData
|
|
||||||
}
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
fn missing_account() -> InstructionError {
|
fn missing_account() -> InstructionError {
|
||||||
debug!("Error: Missing account");
|
debug!("Error: Missing account");
|
||||||
@ -110,7 +84,7 @@ impl MoveProcessor {
|
|||||||
|
|
||||||
fn arguments_to_locals(args: Vec<TransactionArgument>) -> Vec<Local> {
|
fn arguments_to_locals(args: Vec<TransactionArgument>) -> Vec<Local> {
|
||||||
let mut locals = vec![];
|
let mut locals = vec![];
|
||||||
for arg in args.into_iter() {
|
for arg in args {
|
||||||
locals.push(match arg {
|
locals.push(match arg {
|
||||||
TransactionArgument::U64(i) => Local::u64(i),
|
TransactionArgument::U64(i) => Local::u64(i),
|
||||||
TransactionArgument::Address(a) => Local::address(a),
|
TransactionArgument::Address(a) => Local::address(a),
|
||||||
@ -129,28 +103,28 @@ impl MoveProcessor {
|
|||||||
script
|
script
|
||||||
.as_inner()
|
.as_inner()
|
||||||
.serialize(&mut script_bytes)
|
.serialize(&mut script_bytes)
|
||||||
.map_err(Self::map_failure_error)?;
|
.map_err(map_failure_error)?;
|
||||||
let mut modules_bytes = vec![];
|
let mut modules_bytes = vec![];
|
||||||
for module in modules.iter() {
|
for module in modules.iter() {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
module
|
module
|
||||||
.as_inner()
|
.as_inner()
|
||||||
.serialize(&mut buf)
|
.serialize(&mut buf)
|
||||||
.map_err(Self::map_failure_error)?;
|
.map_err(map_failure_error)?;
|
||||||
modules_bytes.push(buf);
|
modules_bytes.push(buf);
|
||||||
}
|
}
|
||||||
bincode::serialize(&LibraAccountState::VerifiedProgram {
|
bincode::serialize(&LibraAccountState::VerifiedProgram {
|
||||||
script_bytes,
|
script_bytes,
|
||||||
modules_bytes,
|
modules_bytes,
|
||||||
})
|
})
|
||||||
.map_err(Self::map_data_error)
|
.map_err(map_data_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_compiled_program(
|
fn deserialize_compiled_program(
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(CompiledScript, Vec<CompiledModule>), InstructionError> {
|
) -> Result<(CompiledScript, Vec<CompiledModule>), InstructionError> {
|
||||||
let (script_bytes, modules_bytes) =
|
let (script_bytes, modules_bytes) =
|
||||||
match bincode::deserialize(data).map_err(Self::map_data_error)? {
|
match bincode::deserialize(data).map_err(map_data_error)? {
|
||||||
LibraAccountState::CompiledProgram {
|
LibraAccountState::CompiledProgram {
|
||||||
script_bytes,
|
script_bytes,
|
||||||
modules_bytes,
|
modules_bytes,
|
||||||
@ -161,13 +135,12 @@ impl MoveProcessor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let script =
|
let script = CompiledScript::deserialize(&script_bytes).map_err(map_vm_binary_error)?;
|
||||||
CompiledScript::deserialize(&script_bytes).map_err(Self::map_vm_binary_error)?;
|
|
||||||
let modules = modules_bytes
|
let modules = modules_bytes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|bytes| CompiledModule::deserialize(&bytes))
|
.map(|bytes| CompiledModule::deserialize(&bytes))
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(Self::map_vm_binary_error)?;
|
.map_err(map_vm_binary_error)?;
|
||||||
|
|
||||||
Ok((script, modules))
|
Ok((script, modules))
|
||||||
}
|
}
|
||||||
@ -176,7 +149,7 @@ impl MoveProcessor {
|
|||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(VerifiedScript, Vec<VerifiedModule>), InstructionError> {
|
) -> Result<(VerifiedScript, Vec<VerifiedModule>), InstructionError> {
|
||||||
let (script_bytes, modules_bytes) =
|
let (script_bytes, modules_bytes) =
|
||||||
match bincode::deserialize(data).map_err(Self::map_data_error)? {
|
match bincode::deserialize(data).map_err(map_data_error)? {
|
||||||
LibraAccountState::VerifiedProgram {
|
LibraAccountState::VerifiedProgram {
|
||||||
script_bytes,
|
script_bytes,
|
||||||
modules_bytes,
|
modules_bytes,
|
||||||
@ -187,19 +160,20 @@ impl MoveProcessor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let script =
|
let script = VerifiedScript::deserialize(&script_bytes).map_err(map_vm_binary_error)?;
|
||||||
VerifiedScript::deserialize(&script_bytes).map_err(Self::map_vm_binary_error)?;
|
|
||||||
let modules = modules_bytes
|
let modules = modules_bytes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|bytes| VerifiedModule::deserialize(&bytes))
|
.map(|bytes| VerifiedModule::deserialize(&bytes))
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(Self::map_vm_binary_error)?;
|
.map_err(map_vm_binary_error)?;
|
||||||
|
|
||||||
Ok((script, modules))
|
Ok((script, modules))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(
|
fn execute(
|
||||||
invoke_info: InvokeInfo,
|
sender_address: AccountAddress,
|
||||||
|
function_name: String,
|
||||||
|
args: Vec<TransactionArgument>,
|
||||||
script: VerifiedScript,
|
script: VerifiedScript,
|
||||||
modules: Vec<VerifiedModule>,
|
modules: Vec<VerifiedModule>,
|
||||||
data_store: &DataStore,
|
data_store: &DataStore,
|
||||||
@ -217,38 +191,41 @@ impl MoveProcessor {
|
|||||||
verified_module
|
verified_module
|
||||||
.as_inner()
|
.as_inner()
|
||||||
.serialize(&mut raw_bytes)
|
.serialize(&mut raw_bytes)
|
||||||
.expect("Unable to serialize module"); // TODO remove expect
|
.map_err(map_failure_error)?;
|
||||||
modules_to_publish.push((verified_module.self_id(), raw_bytes));
|
modules_to_publish.push((verified_module.self_id(), raw_bytes));
|
||||||
module_cache.cache_module(verified_module);
|
module_cache.cache_module(verified_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut txn_metadata = TransactionMetadata::default();
|
let mut txn_metadata = TransactionMetadata::default();
|
||||||
txn_metadata.sender = invoke_info.sender_address;
|
txn_metadata.sender = sender_address;
|
||||||
|
|
||||||
// Caps execution to the Libra prescribed 10 milliseconds
|
// Caps execution to the Libra prescribed 10 milliseconds
|
||||||
txn_metadata.max_gas_amount = *MAXIMUM_NUMBER_OF_GAS_UNITS;
|
txn_metadata.max_gas_amount = *MAXIMUM_NUMBER_OF_GAS_UNITS;
|
||||||
txn_metadata.gas_unit_price = *MAX_PRICE_PER_GAS_UNIT;
|
txn_metadata.gas_unit_price = *MAX_PRICE_PER_GAS_UNIT;
|
||||||
|
|
||||||
let mut vm = TransactionExecutor::new(&module_cache, data_store, txn_metadata);
|
let mut vm = TransactionExecutor::new(&module_cache, data_store, txn_metadata);
|
||||||
vm.execute_function(
|
vm.execute_function(&module_id, &function_name, Self::arguments_to_locals(args))
|
||||||
&module_id,
|
.map_err(map_vm_invariant_violation_error)?
|
||||||
&invoke_info.function_name,
|
.map_err(map_vm_runtime_error)?;
|
||||||
Self::arguments_to_locals(invoke_info.args),
|
|
||||||
)
|
|
||||||
.map_err(Self::map_vm_invariant_violation_error)?
|
|
||||||
.map_err(Self::map_vm_runtime_error)?;
|
|
||||||
|
|
||||||
Ok(vm
|
Ok(vm
|
||||||
.make_write_set(modules_to_publish, Ok(Ok(())))
|
.make_write_set(modules_to_publish, Ok(Ok(())))
|
||||||
.map_err(Self::map_vm_runtime_error)?)
|
.map_err(map_vm_runtime_error)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keyed_accounts_to_data_store(
|
fn keyed_accounts_to_data_store(
|
||||||
|
genesis_key: &Pubkey,
|
||||||
keyed_accounts: &[KeyedAccount],
|
keyed_accounts: &[KeyedAccount],
|
||||||
) -> Result<DataStore, InstructionError> {
|
) -> Result<DataStore, InstructionError> {
|
||||||
let mut data_store = DataStore::default();
|
let mut data_store = DataStore::default();
|
||||||
for keyed_account in keyed_accounts {
|
for keyed_account in keyed_accounts {
|
||||||
match bincode::deserialize(&keyed_account.account.data).map_err(Self::map_data_error)? {
|
match bincode::deserialize(&keyed_account.account.data).map_err(map_data_error)? {
|
||||||
LibraAccountState::Genesis(write_set) | LibraAccountState::User(write_set) => {
|
LibraAccountState::Genesis(write_set) => data_store.apply_write_set(&write_set),
|
||||||
|
LibraAccountState::User(owner, write_set) => {
|
||||||
|
if owner != *genesis_key {
|
||||||
|
debug!("All user accounts must be owned by the genesis");
|
||||||
|
return Err(InstructionError::InvalidArgument);
|
||||||
|
}
|
||||||
data_store.apply_write_set(&write_set)
|
data_store.apply_write_set(&write_set)
|
||||||
}
|
}
|
||||||
_ => (), // ignore unallocated accounts
|
_ => (), // ignore unallocated accounts
|
||||||
@ -257,10 +234,45 @@ impl MoveProcessor {
|
|||||||
Ok(data_store)
|
Ok(data_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn data_store_to_keyed_accounts(
|
||||||
|
data_store: DataStore,
|
||||||
|
keyed_accounts: &mut [KeyedAccount],
|
||||||
|
) -> Result<(), InstructionError> {
|
||||||
|
let mut write_sets = data_store
|
||||||
|
.into_write_sets()
|
||||||
|
.map_err(|_| InstructionError::GenericError)?;
|
||||||
|
|
||||||
|
// Genesis account holds both mint and stdlib under address 0x0
|
||||||
|
let genesis_key = *keyed_accounts[GENESIS_INDEX].unsigned_key();
|
||||||
|
let write_set = write_sets
|
||||||
|
.remove(&AccountAddress::default())
|
||||||
|
.ok_or_else(Self::missing_account)?;
|
||||||
|
keyed_accounts[GENESIS_INDEX].account.data.clear();
|
||||||
|
let writer = std::io::BufWriter::new(&mut keyed_accounts[GENESIS_INDEX].account.data);
|
||||||
|
bincode::serialize_into(writer, &LibraAccountState::Genesis(write_set))
|
||||||
|
.map_err(map_data_error)?;
|
||||||
|
|
||||||
|
// Now do the rest of the accounts
|
||||||
|
for keyed_account in keyed_accounts[GENESIS_INDEX + 1..].iter_mut() {
|
||||||
|
let write_set = write_sets
|
||||||
|
.remove(&pubkey_to_address(keyed_account.unsigned_key()))
|
||||||
|
.ok_or_else(Self::missing_account)?;
|
||||||
|
keyed_account.account.data.clear();
|
||||||
|
let writer = std::io::BufWriter::new(&mut keyed_account.account.data);
|
||||||
|
bincode::serialize_into(writer, &LibraAccountState::User(genesis_key, write_set))
|
||||||
|
.map_err(map_data_error)?;
|
||||||
|
}
|
||||||
|
if !write_sets.is_empty() {
|
||||||
|
debug!("Error: Missing keyed accounts");
|
||||||
|
return Err(InstructionError::GenericError);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn do_write(
|
pub fn do_write(
|
||||||
keyed_accounts: &mut [KeyedAccount],
|
keyed_accounts: &mut [KeyedAccount],
|
||||||
offset: u32,
|
offset: u32,
|
||||||
bytes: Vec<u8>,
|
bytes: &[u8],
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
if keyed_accounts[PROGRAM_INDEX].signer_key().is_none() {
|
if keyed_accounts[PROGRAM_INDEX].signer_key().is_none() {
|
||||||
debug!("Error: key[0] did not sign the transaction");
|
debug!("Error: key[0] did not sign the transaction");
|
||||||
@ -295,7 +307,7 @@ impl MoveProcessor {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(VerifiedModule::new)
|
.map(VerifiedModule::new)
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(Self::map_vm_verification_error)?;
|
.map_err(map_vm_verification_error)?;
|
||||||
|
|
||||||
keyed_accounts[PROGRAM_INDEX].account.data =
|
keyed_accounts[PROGRAM_INDEX].account.data =
|
||||||
Self::serialize_verified_program(&verified_script, &verified_modules)?;
|
Self::serialize_verified_program(&verified_script, &verified_modules)?;
|
||||||
@ -312,62 +324,76 @@ impl MoveProcessor {
|
|||||||
|
|
||||||
pub fn do_invoke_main(
|
pub fn do_invoke_main(
|
||||||
keyed_accounts: &mut [KeyedAccount],
|
keyed_accounts: &mut [KeyedAccount],
|
||||||
data: Vec<u8>,
|
data: &[u8],
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
if keyed_accounts.len() < 2 {
|
match bincode::deserialize(&data).map_err(map_data_error)? {
|
||||||
debug!("Error: Requires at least a program and a genesis accounts");
|
InvokeCommand::CreateGenesis(amount) => {
|
||||||
return Err(InstructionError::InvalidArgument);
|
if keyed_accounts.is_empty() {
|
||||||
}
|
debug!("Error: Requires an unallocated account");
|
||||||
if keyed_accounts[PROGRAM_INDEX].account.owner != id() {
|
return Err(InstructionError::InvalidArgument);
|
||||||
debug!("Error: Move program account not owned by Move loader");
|
}
|
||||||
return Err(InstructionError::InvalidArgument);
|
if keyed_accounts[0].account.owner != id() {
|
||||||
}
|
debug!("Error: Move program account not owned by Move loader");
|
||||||
if !keyed_accounts[PROGRAM_INDEX].account.executable {
|
return Err(InstructionError::InvalidArgument);
|
||||||
debug!("Error: Move program account not executable");
|
}
|
||||||
return Err(InstructionError::InvalidArgument);
|
|
||||||
}
|
|
||||||
|
|
||||||
let invoke_info: InvokeInfo = bincode::deserialize(&data).map_err(Self::map_data_error)?;
|
match bincode::deserialize(&keyed_accounts[0].account.data)
|
||||||
let mut data_store = Self::keyed_accounts_to_data_store(&keyed_accounts[GENESIS_INDEX..])?;
|
.map_err(map_data_error)?
|
||||||
let (verified_script, verified_modules) =
|
{
|
||||||
Self::deserialize_verified_program(&keyed_accounts[PROGRAM_INDEX].account.data)?;
|
LibraAccountState::Unallocated => {
|
||||||
|
keyed_accounts[0].account.data.clear();
|
||||||
|
let writer = std::io::BufWriter::new(&mut keyed_accounts[0].account.data);
|
||||||
|
bincode::serialize_into(writer, &LibraAccountState::create_genesis(amount)?)
|
||||||
|
.map_err(map_data_error)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
debug!("Error: Must provide an unallocated account");
|
||||||
|
Err(InstructionError::InvalidArgument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InvokeCommand::RunProgram {
|
||||||
|
sender_address,
|
||||||
|
function_name,
|
||||||
|
args,
|
||||||
|
} => {
|
||||||
|
if keyed_accounts.len() < 2 {
|
||||||
|
debug!("Error: Requires at least a program and a genesis accounts");
|
||||||
|
return Err(InstructionError::InvalidArgument);
|
||||||
|
}
|
||||||
|
if keyed_accounts[PROGRAM_INDEX].account.owner != id() {
|
||||||
|
debug!("Error: Move program account not owned by Move loader");
|
||||||
|
return Err(InstructionError::InvalidArgument);
|
||||||
|
}
|
||||||
|
if !keyed_accounts[PROGRAM_INDEX].account.executable {
|
||||||
|
debug!("Error: Move program account not executable");
|
||||||
|
return Err(InstructionError::InvalidArgument);
|
||||||
|
}
|
||||||
|
|
||||||
let output = Self::execute(invoke_info, verified_script, verified_modules, &data_store)?;
|
let mut data_store = Self::keyed_accounts_to_data_store(
|
||||||
for event in output.events() {
|
keyed_accounts[GENESIS_INDEX].unsigned_key(),
|
||||||
trace!("Event: {:?}", event);
|
&keyed_accounts[GENESIS_INDEX..],
|
||||||
|
)?;
|
||||||
|
let (verified_script, verified_modules) = Self::deserialize_verified_program(
|
||||||
|
&keyed_accounts[PROGRAM_INDEX].account.data,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let output = Self::execute(
|
||||||
|
sender_address,
|
||||||
|
function_name,
|
||||||
|
args,
|
||||||
|
verified_script,
|
||||||
|
verified_modules,
|
||||||
|
&data_store,
|
||||||
|
)?;
|
||||||
|
for event in output.events() {
|
||||||
|
trace!("Event: {:?}", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
data_store.apply_write_set(&output.write_set());
|
||||||
|
Self::data_store_to_keyed_accounts(data_store, keyed_accounts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data_store.apply_write_set(&output.write_set());
|
|
||||||
|
|
||||||
// Break data store into a list of address keyed WriteSets
|
|
||||||
let mut write_sets = data_store
|
|
||||||
.into_write_sets()
|
|
||||||
.map_err(|_| InstructionError::GenericError)?;
|
|
||||||
|
|
||||||
// Genesis account holds both mint and stdlib under address 0x0
|
|
||||||
let write_set = write_sets
|
|
||||||
.remove(&AccountAddress::default())
|
|
||||||
.ok_or_else(Self::missing_account)?;
|
|
||||||
keyed_accounts[GENESIS_INDEX].account.data.clear();
|
|
||||||
let writer = std::io::BufWriter::new(&mut keyed_accounts[GENESIS_INDEX].account.data);
|
|
||||||
bincode::serialize_into(writer, &LibraAccountState::Genesis(write_set))
|
|
||||||
.map_err(Self::map_data_error)?;
|
|
||||||
|
|
||||||
// Now do the rest of the accounts
|
|
||||||
for keyed_account in keyed_accounts[GENESIS_INDEX + 1..].iter_mut() {
|
|
||||||
let write_set = write_sets
|
|
||||||
.remove(&pubkey_to_address(keyed_account.unsigned_key()))
|
|
||||||
.ok_or_else(Self::missing_account)?;
|
|
||||||
keyed_account.account.data.clear();
|
|
||||||
let writer = std::io::BufWriter::new(&mut keyed_account.account.data);
|
|
||||||
bincode::serialize_into(writer, &LibraAccountState::User(write_set))
|
|
||||||
.map_err(Self::map_data_error)?;
|
|
||||||
}
|
|
||||||
if !write_sets.is_empty() {
|
|
||||||
debug!("Error: Missing keyed accounts");
|
|
||||||
return Err(InstructionError::GenericError);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,6 +415,33 @@ mod tests {
|
|||||||
let (_, _) = MoveProcessor::deserialize_verified_program(&program.account.data).unwrap();
|
let (_, _) = MoveProcessor::deserialize_verified_program(&program.account.data).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_genesis_account() {
|
||||||
|
solana_logger::setup();
|
||||||
|
|
||||||
|
let amount = 10_000_000;
|
||||||
|
let mut unallocated = LibraAccount::create_unallocated();
|
||||||
|
|
||||||
|
let mut keyed_accounts = vec![KeyedAccount::new(
|
||||||
|
&unallocated.key,
|
||||||
|
false,
|
||||||
|
&mut unallocated.account,
|
||||||
|
)];
|
||||||
|
MoveProcessor::do_invoke_main(
|
||||||
|
&mut keyed_accounts,
|
||||||
|
&bincode::serialize(&InvokeCommand::CreateGenesis(amount)).unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
bincode::deserialize::<LibraAccountState>(
|
||||||
|
&LibraAccount::create_genesis(amount).account.data
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
bincode::deserialize::<LibraAccountState>(&keyed_accounts[0].account.data).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_invoke_main() {
|
fn test_invoke_main() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
@ -396,21 +449,21 @@ mod tests {
|
|||||||
let code = "main() { return; }";
|
let code = "main() { return; }";
|
||||||
let sender_address = AccountAddress::default();
|
let sender_address = AccountAddress::default();
|
||||||
let mut program = LibraAccount::create_program(&sender_address, code, vec![]);
|
let mut program = LibraAccount::create_program(&sender_address, code, vec![]);
|
||||||
let mut genesis = LibraAccount::create_genesis();
|
let mut genesis = LibraAccount::create_genesis(1_000_000_000);
|
||||||
|
|
||||||
let mut keyed_accounts = vec![
|
let mut keyed_accounts = vec![
|
||||||
KeyedAccount::new(&program.key, true, &mut program.account),
|
KeyedAccount::new(&program.key, true, &mut program.account),
|
||||||
KeyedAccount::new(&genesis.key, false, &mut genesis.account),
|
KeyedAccount::new(&genesis.key, false, &mut genesis.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address,
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
};
|
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address,
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -427,23 +480,22 @@ mod tests {
|
|||||||
";
|
";
|
||||||
let sender_address = AccountAddress::default();
|
let sender_address = AccountAddress::default();
|
||||||
let mut program = LibraAccount::create_program(&sender_address, code, vec![]);
|
let mut program = LibraAccount::create_program(&sender_address, code, vec![]);
|
||||||
let mut genesis = LibraAccount::create_genesis();
|
let mut genesis = LibraAccount::create_genesis(1_000_000_000);
|
||||||
|
|
||||||
let mut keyed_accounts = vec![
|
let mut keyed_accounts = vec![
|
||||||
KeyedAccount::new(&program.key, true, &mut program.account),
|
KeyedAccount::new(&program.key, true, &mut program.account),
|
||||||
KeyedAccount::new(&genesis.key, false, &mut genesis.account),
|
KeyedAccount::new(&genesis.key, false, &mut genesis.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
|
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address,
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
};
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address,
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
),
|
),
|
||||||
Err(InstructionError::InsufficientFunds)
|
Err(InstructionError::InsufficientFunds)
|
||||||
);
|
);
|
||||||
@ -458,7 +510,12 @@ mod tests {
|
|||||||
|
|
||||||
let mut data_store = DataStore::default();
|
let mut data_store = DataStore::default();
|
||||||
match bincode::deserialize(&accounts[GENESIS_INDEX + 1].account.data).unwrap() {
|
match bincode::deserialize(&accounts[GENESIS_INDEX + 1].account.data).unwrap() {
|
||||||
LibraAccountState::User(write_set) => data_store.apply_write_set(&write_set),
|
LibraAccountState::User(owner, write_set) => {
|
||||||
|
if owner != accounts[GENESIS_INDEX].key {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
data_store.apply_write_set(&write_set)
|
||||||
|
}
|
||||||
_ => panic!("Invalid account state"),
|
_ => panic!("Invalid account state"),
|
||||||
}
|
}
|
||||||
let payee_resource = data_store
|
let payee_resource = data_store
|
||||||
@ -497,24 +554,24 @@ mod tests {
|
|||||||
KeyedAccount::new(&payee.key, false, &mut payee.account),
|
KeyedAccount::new(&payee.key, false, &mut payee.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
|
|
||||||
let amount = 2;
|
let amount = 2;
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address: sender.address.clone(),
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![
|
|
||||||
TransactionArgument::Address(payee.address.clone()),
|
|
||||||
TransactionArgument::U64(amount),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: sender.address.clone(),
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![
|
||||||
|
TransactionArgument::Address(payee.address.clone()),
|
||||||
|
TransactionArgument::U64(amount),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let data_store = MoveProcessor::keyed_accounts_to_data_store(&keyed_accounts[1..]).unwrap();
|
let data_store =
|
||||||
|
MoveProcessor::keyed_accounts_to_data_store(&genesis.key, &keyed_accounts[1..])
|
||||||
|
.unwrap();
|
||||||
let sender_resource = data_store.read_account_resource(&sender.address).unwrap();
|
let sender_resource = data_store.read_account_resource(&sender.address).unwrap();
|
||||||
let payee_resource = data_store.read_account_resource(&payee.address).unwrap();
|
let payee_resource = data_store.read_account_resource(&payee.address).unwrap();
|
||||||
|
|
||||||
@ -549,7 +606,7 @@ mod tests {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
let mut genesis = LibraAccount::create_genesis();
|
let mut genesis = LibraAccount::create_genesis(1_000_000_000);
|
||||||
let mut payee = LibraAccount::create_unallocated();
|
let mut payee = LibraAccount::create_unallocated();
|
||||||
let mut program = LibraAccount::create_program(&payee.address, code, vec![]);
|
let mut program = LibraAccount::create_program(&payee.address, code, vec![]);
|
||||||
|
|
||||||
@ -559,14 +616,14 @@ mod tests {
|
|||||||
KeyedAccount::new(&payee.key, false, &mut payee.account),
|
KeyedAccount::new(&payee.key, false, &mut payee.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address: payee.address,
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
};
|
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: payee.address,
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -586,7 +643,7 @@ mod tests {
|
|||||||
";
|
";
|
||||||
let mut module = LibraAccount::create_unallocated();
|
let mut module = LibraAccount::create_unallocated();
|
||||||
let mut program = LibraAccount::create_program(&module.address, code, vec![]);
|
let mut program = LibraAccount::create_program(&module.address, code, vec![]);
|
||||||
let mut genesis = LibraAccount::create_genesis();
|
let mut genesis = LibraAccount::create_genesis(1_000_000_000);
|
||||||
|
|
||||||
let mut keyed_accounts = vec![
|
let mut keyed_accounts = vec![
|
||||||
KeyedAccount::new(&program.key, true, &mut program.account),
|
KeyedAccount::new(&program.key, true, &mut program.account),
|
||||||
@ -594,14 +651,14 @@ mod tests {
|
|||||||
KeyedAccount::new(&module.key, false, &mut module.account),
|
KeyedAccount::new(&module.key, false, &mut module.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address: module.address,
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
};
|
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: module.address,
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -627,14 +684,14 @@ mod tests {
|
|||||||
KeyedAccount::new(&module.key, false, &mut module.account),
|
KeyedAccount::new(&module.key, false, &mut module.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address: program.address,
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![],
|
|
||||||
};
|
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: program.address,
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -650,7 +707,7 @@ mod tests {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
let mut genesis = LibraAccount::create_genesis();
|
let mut genesis = LibraAccount::create_genesis(1_000_000_000);
|
||||||
let mut program = LibraAccount::create_program(&genesis.address, code, vec![]);
|
let mut program = LibraAccount::create_program(&genesis.address, code, vec![]);
|
||||||
let mut payee = LibraAccount::create_unallocated();
|
let mut payee = LibraAccount::create_unallocated();
|
||||||
|
|
||||||
@ -660,18 +717,17 @@ mod tests {
|
|||||||
KeyedAccount::new(&payee.key, false, &mut payee.account),
|
KeyedAccount::new(&payee.key, false, &mut payee.account),
|
||||||
];
|
];
|
||||||
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
MoveProcessor::do_finalize(&mut keyed_accounts).unwrap();
|
||||||
let invoke_info = InvokeInfo {
|
|
||||||
sender_address: genesis.address.clone(),
|
|
||||||
function_name: "main".to_string(),
|
|
||||||
args: vec![
|
|
||||||
TransactionArgument::Address(pubkey_to_address(&payee.key)),
|
|
||||||
TransactionArgument::U64(amount),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
MoveProcessor::do_invoke_main(
|
MoveProcessor::do_invoke_main(
|
||||||
&mut keyed_accounts,
|
&mut keyed_accounts,
|
||||||
bincode::serialize(&invoke_info).unwrap(),
|
&bincode::serialize(&InvokeCommand::RunProgram {
|
||||||
|
sender_address: genesis.address.clone(),
|
||||||
|
function_name: "main".to_string(),
|
||||||
|
args: vec![
|
||||||
|
TransactionArgument::Address(pubkey_to_address(&payee.key)),
|
||||||
|
TransactionArgument::U64(amount),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -682,6 +738,7 @@ mod tests {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Debug, Default)]
|
||||||
struct LibraAccount {
|
struct LibraAccount {
|
||||||
pub key: Pubkey,
|
pub key: Pubkey,
|
||||||
pub address: AccountAddress,
|
pub address: AccountAddress,
|
||||||
@ -708,7 +765,7 @@ mod tests {
|
|||||||
Self::new(key, account)
|
Self::new(key, account)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_genesis() -> Self {
|
pub fn create_genesis(amount: u64) -> Self {
|
||||||
let account = Account {
|
let account = Account {
|
||||||
lamports: 1,
|
lamports: 1,
|
||||||
data: vec![],
|
data: vec![],
|
||||||
@ -717,7 +774,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut genesis = Self::new(Pubkey::default(), account);
|
let mut genesis = Self::new(Pubkey::default(), account);
|
||||||
genesis.account.data =
|
genesis.account.data =
|
||||||
bincode::serialize(&LibraAccountState::create_genesis(1_000_000_000)).unwrap();
|
bincode::serialize(&LibraAccountState::create_genesis(amount).unwrap()).unwrap();
|
||||||
genesis
|
genesis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-move-loader-program"
|
name = "solana-move-loader-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Move Loader"
|
description = "Solana Move Loader"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.2"
|
log = "0.4.2"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-move-loader-api = { path = "../move_loader_api", version = "0.17.0" }
|
solana-move-loader-api = { path = "../move_loader_api", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-noop-program"
|
name = "solana-noop-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana noop program"
|
description = "Solana noop program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,8 +10,8 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-stake-api"
|
name = "solana-stake-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Stake program API"
|
description = "Solana Stake program API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -14,10 +14,10 @@ log = "0.4.7"
|
|||||||
rand = "0.6.5"
|
rand = "0.6.5"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../../metrics", version = "0.17.0" }
|
solana-metrics = { path = "../../metrics", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-vote-api = { path = "../vote_api", version = "0.17.0" }
|
solana-vote-api = { path = "../vote_api", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -53,7 +53,7 @@ pub struct Stake {
|
|||||||
pub activated: Epoch, // epoch the stake was activated
|
pub activated: Epoch, // epoch the stake was activated
|
||||||
pub deactivated: Epoch, // epoch the stake was deactivated, std::Epoch::MAX if not deactivated
|
pub deactivated: Epoch, // epoch the stake was deactivated, std::Epoch::MAX if not deactivated
|
||||||
}
|
}
|
||||||
pub const STAKE_WARMUP_EPOCHS: u64 = 3;
|
pub const STAKE_WARMUP_EPOCHS: Epoch = 3;
|
||||||
|
|
||||||
impl Default for Stake {
|
impl Default for Stake {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@ -68,7 +68,7 @@ impl Default for Stake {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stake {
|
impl Stake {
|
||||||
pub fn stake(&self, epoch: u64) -> u64 {
|
pub fn stake(&self, epoch: Epoch) -> u64 {
|
||||||
// before "activated" or after deactivated?
|
// before "activated" or after deactivated?
|
||||||
if epoch < self.activated || epoch >= self.deactivated {
|
if epoch < self.activated || epoch >= self.deactivated {
|
||||||
return 0;
|
return 0;
|
||||||
@ -287,6 +287,10 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||||||
|
|
||||||
match self.state()? {
|
match self.state()? {
|
||||||
StakeState::Stake(mut stake) => {
|
StakeState::Stake(mut stake) => {
|
||||||
|
// still activated, no can do
|
||||||
|
if stake.deactivated == std::u64::MAX {
|
||||||
|
return Err(InstructionError::InsufficientFunds);
|
||||||
|
}
|
||||||
let staked = if stake.stake(clock.epoch) == 0 {
|
let staked = if stake.stake(clock.epoch) == 0 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
@ -353,7 +357,10 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_stake_delegate_stake() {
|
fn test_stake_delegate_stake() {
|
||||||
let clock = sysvar::clock::Clock::default();
|
let clock = sysvar::clock::Clock {
|
||||||
|
epoch: 1,
|
||||||
|
..sysvar::clock::Clock::default()
|
||||||
|
};
|
||||||
|
|
||||||
let vote_keypair = Keypair::new();
|
let vote_keypair = Keypair::new();
|
||||||
let mut vote_state = VoteState::default();
|
let mut vote_state = VoteState::default();
|
||||||
@ -399,7 +406,7 @@ mod tests {
|
|||||||
voter_pubkey: vote_keypair.pubkey(),
|
voter_pubkey: vote_keypair.pubkey(),
|
||||||
credits_observed: vote_state.credits(),
|
credits_observed: vote_state.credits(),
|
||||||
stake: stake_lamports,
|
stake: stake_lamports,
|
||||||
activated: 0,
|
activated: clock.epoch,
|
||||||
deactivated: std::u64::MAX,
|
deactivated: std::u64::MAX,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -456,7 +463,10 @@ mod tests {
|
|||||||
let mut stake_account =
|
let mut stake_account =
|
||||||
Account::new(stake_lamports, std::mem::size_of::<StakeState>(), &id());
|
Account::new(stake_lamports, std::mem::size_of::<StakeState>(), &id());
|
||||||
|
|
||||||
let clock = sysvar::clock::Clock::default();
|
let clock = sysvar::clock::Clock {
|
||||||
|
epoch: 1,
|
||||||
|
..sysvar::clock::Clock::default()
|
||||||
|
};
|
||||||
|
|
||||||
// unsigned keyed account
|
// unsigned keyed account
|
||||||
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, false, &mut stake_account);
|
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, false, &mut stake_account);
|
||||||
@ -495,7 +505,7 @@ mod tests {
|
|||||||
let mut stake_account =
|
let mut stake_account =
|
||||||
Account::new(total_lamports, std::mem::size_of::<StakeState>(), &id());
|
Account::new(total_lamports, std::mem::size_of::<StakeState>(), &id());
|
||||||
|
|
||||||
let clock = sysvar::clock::Clock::default();
|
let mut clock = sysvar::clock::Clock::default();
|
||||||
|
|
||||||
let to = Pubkey::new_rand();
|
let to = Pubkey::new_rand();
|
||||||
let mut to_account = Account::new(1, 0, &system_program::id());
|
let mut to_account = Account::new(1, 0, &system_program::id());
|
||||||
@ -535,6 +545,11 @@ mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// deactivate the stake before withdrawal
|
||||||
|
assert_eq!(stake_keyed_account.deactivate_stake(&clock), Ok(()));
|
||||||
|
// simulate time passing
|
||||||
|
clock.epoch += STAKE_WARMUP_EPOCHS;
|
||||||
|
|
||||||
// Try to withdraw more than what's available
|
// Try to withdraw more than what's available
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
stake_keyed_account.withdraw(
|
stake_keyed_account.withdraw(
|
||||||
@ -585,14 +600,14 @@ mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
);
|
);
|
||||||
|
|
||||||
// Try to withdraw including staked
|
// Try to withdraw stake
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
stake_keyed_account.withdraw(
|
stake_keyed_account.withdraw(
|
||||||
total_lamports - stake_lamports + 1,
|
total_lamports - stake_lamports + 1,
|
||||||
&mut to_keyed_account,
|
&mut to_keyed_account,
|
||||||
&clock
|
&clock
|
||||||
),
|
),
|
||||||
Ok(())
|
Err(InstructionError::InsufficientFunds)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-stake-program"
|
name = "solana-stake-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana stake program"
|
description = "Solana stake program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-stake-api = { path = "../stake_api", version = "0.17.0" }
|
solana-stake-api = { path = "../stake_api", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-stake-tests"
|
name = "solana-stake-tests"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana stake api tests"
|
description = "Solana stake api tests"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,12 +10,12 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-stake-api = { path = "../stake_api", version = "0.17.0" }
|
solana-stake-api = { path = "../stake_api", version = "0.17.2" }
|
||||||
solana-stake-program = { path = "../stake_program", version = "0.17.0" }
|
solana-stake-program = { path = "../stake_program", version = "0.17.2" }
|
||||||
solana-vote-api = { path = "../vote_api", version = "0.17.0" }
|
solana-vote-api = { path = "../vote_api", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
assert_matches = "1.3.0"
|
assert_matches = "1.3.0"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-storage-api"
|
name = "solana-storage-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Storage program API"
|
description = "Solana Storage program API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -17,8 +17,8 @@ num-derive = "0.2"
|
|||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-storage-program"
|
name = "solana-storage-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana storage program"
|
description = "Solana storage program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,12 +10,12 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-storage-api = { path = "../storage_api", version = "0.17.0" }
|
solana-storage-api = { path = "../storage_api", version = "0.17.2" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.17.0" }
|
solana-runtime = { path = "../../runtime", version = "0.17.2" }
|
||||||
assert_matches = "1.3.0"
|
assert_matches = "1.3.0"
|
||||||
bincode = "1.1.4"
|
bincode = "1.1.4"
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-token-api"
|
name = "solana-token-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Token API"
|
description = "Solana Token API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -15,8 +15,8 @@ num-derive = "0.2"
|
|||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-token-program"
|
name = "solana-token-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana token program"
|
description = "Solana token program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-token-api = { path = "../token_api", version = "0.17.0" }
|
solana-token-api = { path = "../token_api", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-vote-api"
|
name = "solana-vote-api"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Vote program API"
|
description = "Solana Vote program API"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -13,9 +13,9 @@ bincode = "1.1.4"
|
|||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../../metrics", version = "0.17.0" }
|
solana-metrics = { path = "../../metrics", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib"]
|
crate-type = ["lib"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-vote-program"
|
name = "solana-vote-program"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana Vote program"
|
description = "Solana Vote program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.7"
|
log = "0.4.7"
|
||||||
solana-logger = { path = "../../logger", version = "0.17.0" }
|
solana-logger = { path = "../../logger", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../../sdk", version = "0.17.2" }
|
||||||
solana-vote-api = { path = "../vote_api", version = "0.17.0" }
|
solana-vote-api = { path = "../vote_api", version = "0.17.2" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-replicator"
|
name = "solana-replicator"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
solana = { path = "../core", version = "0.17.0" }
|
solana = { path = "../core", version = "0.17.2" }
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.17.0" }
|
solana-netutil = { path = "../netutil", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
cuda = ["solana/cuda"]
|
cuda = ["solana/cuda"]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "solana-runtime"
|
name = "solana-runtime"
|
||||||
version = "0.17.0"
|
version = "0.17.2"
|
||||||
description = "Solana runtime"
|
description = "Solana runtime"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
@ -25,18 +25,17 @@ rayon = "1.1.0"
|
|||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "1.0.97"
|
serde_derive = "1.0.97"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
solana-logger = { path = "../logger", version = "0.17.0" }
|
solana-logger = { path = "../logger", version = "0.17.2" }
|
||||||
solana-measure = { path = "../measure", version = "0.17.0" }
|
solana-measure = { path = "../measure", version = "0.17.2" }
|
||||||
solana-metrics = { path = "../metrics", version = "0.17.0" }
|
solana-metrics = { path = "../metrics", version = "0.17.2" }
|
||||||
solana-bpf-loader-api = { path = "../programs/bpf_loader_api", version = "0.17.0" }
|
solana-bpf-loader-api = { path = "../programs/bpf_loader_api", version = "0.17.2" }
|
||||||
solana-bpf-loader-program = { path = "../programs/bpf_loader_program", version = "0.17.0" }
|
solana-bpf-loader-program = { path = "../programs/bpf_loader_program", version = "0.17.2" }
|
||||||
solana-noop-program = { path = "../programs/noop_program", version = "0.17.0" }
|
solana-sdk = { path = "../sdk", version = "0.17.2" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.17.0" }
|
solana-stake-api = { path = "../programs/stake_api", version = "0.17.2" }
|
||||||
solana-stake-api = { path = "../programs/stake_api", version = "0.17.0" }
|
solana-stake-program = { path = "../programs/stake_program", version = "0.17.2" }
|
||||||
solana-stake-program = { path = "../programs/stake_program", version = "0.17.0" }
|
solana-storage-api = { path = "../programs/storage_api", version = "0.17.2" }
|
||||||
solana-storage-api = { path = "../programs/storage_api", version = "0.17.0" }
|
solana-vote-api = { path = "../programs/vote_api", version = "0.17.2" }
|
||||||
solana-vote-api = { path = "../programs/vote_api", version = "0.17.0" }
|
solana-vote-program = { path = "../programs/vote_program", version = "0.17.2" }
|
||||||
solana-vote-program = { path = "../programs/vote_program", version = "0.17.0" }
|
|
||||||
sys-info = "0.5.7"
|
sys-info = "0.5.7"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -151,21 +151,25 @@ fn do_bench_transactions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
fn bench_bank_sync_process_builtin_transactions(bencher: &mut Bencher) {
|
fn bench_bank_sync_process_builtin_transactions(bencher: &mut Bencher) {
|
||||||
do_bench_transactions(bencher, &sync_bencher, &create_builtin_transactions);
|
do_bench_transactions(bencher, &sync_bencher, &create_builtin_transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
fn bench_bank_sync_process_native_loader_transactions(bencher: &mut Bencher) {
|
fn bench_bank_sync_process_native_loader_transactions(bencher: &mut Bencher) {
|
||||||
do_bench_transactions(bencher, &sync_bencher, &create_native_loader_transactions);
|
do_bench_transactions(bencher, &sync_bencher, &create_native_loader_transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
fn bench_bank_async_process_builtin_transactions(bencher: &mut Bencher) {
|
fn bench_bank_async_process_builtin_transactions(bencher: &mut Bencher) {
|
||||||
do_bench_transactions(bencher, &async_bencher, &create_builtin_transactions);
|
do_bench_transactions(bencher, &async_bencher, &create_builtin_transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
fn bench_bank_async_process_native_loader_transactions(bencher: &mut Bencher) {
|
fn bench_bank_async_process_native_loader_transactions(bencher: &mut Bencher) {
|
||||||
do_bench_transactions(bencher, &async_bencher, &create_native_loader_transactions);
|
do_bench_transactions(bencher, &async_bencher, &create_native_loader_transactions);
|
||||||
}
|
}
|
||||||
|
@ -286,8 +286,8 @@ impl Bank {
|
|||||||
// slot = 0 and genesis configuration
|
// slot = 0 and genesis configuration
|
||||||
{
|
{
|
||||||
let stakes = bank.stakes.read().unwrap();
|
let stakes = bank.stakes.read().unwrap();
|
||||||
for i in 0..=bank.get_stakers_epoch(bank.slot) {
|
for epoch in 0..=bank.get_stakers_epoch(bank.slot) {
|
||||||
bank.epoch_stakes.insert(i, stakes.clone());
|
bank.epoch_stakes.insert(epoch, stakes.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bank.update_clock();
|
bank.update_clock();
|
||||||
@ -296,80 +296,81 @@ impl Bank {
|
|||||||
|
|
||||||
/// Create a new bank that points to an immutable checkpoint of another bank.
|
/// Create a new bank that points to an immutable checkpoint of another bank.
|
||||||
pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: u64) -> Self {
|
pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: u64) -> Self {
|
||||||
Self::default().init_from_parent(parent, collector_id, slot)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new bank that points to an immutable checkpoint of another bank.
|
|
||||||
pub fn init_from_parent(
|
|
||||||
mut self,
|
|
||||||
parent: &Arc<Bank>,
|
|
||||||
collector_id: &Pubkey,
|
|
||||||
slot: u64,
|
|
||||||
) -> Self {
|
|
||||||
parent.freeze();
|
parent.freeze();
|
||||||
assert_ne!(slot, parent.slot());
|
assert_ne!(slot, parent.slot());
|
||||||
|
|
||||||
// TODO: clean this up, soo much special-case copying...
|
let rc = BankRc {
|
||||||
self.ticks_per_slot = parent.ticks_per_slot;
|
accounts: Arc::new(Accounts::new_from_parent(&parent.rc.accounts)),
|
||||||
self.slots_per_segment = parent.slots_per_segment;
|
parent: RwLock::new(Some(parent.clone())),
|
||||||
self.slots_per_year = parent.slots_per_year;
|
};
|
||||||
self.epoch_schedule = parent.epoch_schedule;
|
let src = StatusCacheRc {
|
||||||
|
status_cache: parent.src.status_cache.clone(),
|
||||||
|
};
|
||||||
|
let mut new = Bank {
|
||||||
|
rc,
|
||||||
|
src,
|
||||||
|
blockhash_queue: RwLock::new(parent.blockhash_queue.read().unwrap().clone()),
|
||||||
|
|
||||||
self.slot = slot;
|
// TODO: clean this up, soo much special-case copying...
|
||||||
self.max_tick_height = (self.slot + 1) * self.ticks_per_slot - 1;
|
ticks_per_slot: parent.ticks_per_slot,
|
||||||
|
slots_per_segment: parent.slots_per_segment,
|
||||||
|
slots_per_year: parent.slots_per_year,
|
||||||
|
epoch_schedule: parent.epoch_schedule,
|
||||||
|
slot,
|
||||||
|
max_tick_height: (slot + 1) * parent.ticks_per_slot - 1,
|
||||||
|
bank_height: parent.bank_height + 1,
|
||||||
|
fee_calculator: FeeCalculator::new_derived(
|
||||||
|
&parent.fee_calculator,
|
||||||
|
parent.signature_count(),
|
||||||
|
),
|
||||||
|
capitalization: AtomicUsize::new(parent.capitalization() as usize),
|
||||||
|
inflation: parent.inflation.clone(),
|
||||||
|
transaction_count: AtomicUsize::new(parent.transaction_count() as usize),
|
||||||
|
stakes: RwLock::new(parent.stakes.read().unwrap().clone_with_epoch(0)),
|
||||||
|
storage_accounts: RwLock::new(parent.storage_accounts.read().unwrap().clone()),
|
||||||
|
parent_hash: parent.hash(),
|
||||||
|
collector_id: *collector_id,
|
||||||
|
collector_fees: AtomicUsize::new(0),
|
||||||
|
ancestors: HashMap::new(),
|
||||||
|
epoch_stakes: HashMap::new(),
|
||||||
|
hash: RwLock::new(Hash::default()),
|
||||||
|
is_delta: AtomicBool::new(false),
|
||||||
|
tick_height: AtomicUsize::new(parent.tick_height.load(Ordering::Relaxed)),
|
||||||
|
signature_count: AtomicUsize::new(0),
|
||||||
|
message_processor: MessageProcessor::default(),
|
||||||
|
};
|
||||||
|
|
||||||
self.blockhash_queue = RwLock::new(parent.blockhash_queue.read().unwrap().clone());
|
{
|
||||||
self.src.status_cache = parent.src.status_cache.clone();
|
*new.stakes.write().unwrap() =
|
||||||
self.bank_height = parent.bank_height + 1;
|
parent.stakes.read().unwrap().clone_with_epoch(new.epoch());
|
||||||
self.fee_calculator =
|
}
|
||||||
FeeCalculator::new_derived(&parent.fee_calculator, parent.signature_count());
|
|
||||||
|
|
||||||
self.capitalization
|
|
||||||
.store(parent.capitalization() as usize, Ordering::Relaxed);
|
|
||||||
self.inflation = parent.inflation.clone();
|
|
||||||
|
|
||||||
self.transaction_count
|
|
||||||
.store(parent.transaction_count() as usize, Ordering::Relaxed);
|
|
||||||
self.stakes = RwLock::new(parent.stakes.read().unwrap().clone_with_epoch(self.epoch()));
|
|
||||||
self.storage_accounts = RwLock::new(parent.storage_accounts.read().unwrap().clone());
|
|
||||||
|
|
||||||
self.tick_height.store(
|
|
||||||
parent.tick_height.load(Ordering::Relaxed),
|
|
||||||
Ordering::Relaxed,
|
|
||||||
);
|
|
||||||
|
|
||||||
datapoint_info!(
|
datapoint_info!(
|
||||||
"bank-new_from_parent-heights",
|
"bank-new_from_parent-heights",
|
||||||
("slot_height", slot, i64),
|
("slot_height", slot, i64),
|
||||||
("bank_height", self.bank_height, i64)
|
("bank_height", new.bank_height, i64)
|
||||||
);
|
);
|
||||||
|
|
||||||
self.rc.parent = RwLock::new(Some(parent.clone()));
|
new.epoch_stakes = {
|
||||||
self.parent_hash = parent.hash();
|
|
||||||
self.collector_id = *collector_id;
|
|
||||||
|
|
||||||
self.rc.accounts = Arc::new(Accounts::new_from_parent(&parent.rc.accounts));
|
|
||||||
|
|
||||||
self.epoch_stakes = {
|
|
||||||
let mut epoch_stakes = parent.epoch_stakes.clone();
|
let mut epoch_stakes = parent.epoch_stakes.clone();
|
||||||
let epoch = self.get_stakers_epoch(self.slot);
|
let epoch = new.get_stakers_epoch(new.slot);
|
||||||
// update epoch_vote_states cache
|
// update epoch_vote_states cache
|
||||||
// if my parent didn't populate for this epoch, we've
|
// if my parent didn't populate for this epoch, we've
|
||||||
// crossed a boundary
|
// crossed a boundary
|
||||||
if epoch_stakes.get(&epoch).is_none() {
|
if epoch_stakes.get(&epoch).is_none() {
|
||||||
epoch_stakes.insert(epoch, self.stakes.read().unwrap().clone());
|
epoch_stakes.insert(epoch, new.stakes.read().unwrap().clone());
|
||||||
}
|
}
|
||||||
epoch_stakes
|
epoch_stakes
|
||||||
};
|
};
|
||||||
self.ancestors.insert(self.slot(), 0);
|
new.ancestors.insert(new.slot(), 0);
|
||||||
self.parents().iter().enumerate().for_each(|(i, p)| {
|
new.parents().iter().enumerate().for_each(|(i, p)| {
|
||||||
self.ancestors.insert(p.slot(), i + 1);
|
new.ancestors.insert(p.slot(), i + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.update_rewards(parent.epoch());
|
new.update_rewards(parent.epoch());
|
||||||
self.update_clock();
|
new.update_clock();
|
||||||
self.update_fees();
|
new.update_fees();
|
||||||
self
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collector_id(&self) -> &Pubkey {
|
pub fn collector_id(&self) -> &Pubkey {
|
||||||
@ -1496,6 +1497,7 @@ mod tests {
|
|||||||
use solana_sdk::system_transaction;
|
use solana_sdk::system_transaction;
|
||||||
use solana_sdk::sysvar::{fees::Fees, rewards::Rewards};
|
use solana_sdk::sysvar::{fees::Fees, rewards::Rewards};
|
||||||
use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT;
|
use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT;
|
||||||
|
use solana_stake_api::stake_state::Stake;
|
||||||
use solana_vote_api::vote_instruction;
|
use solana_vote_api::vote_instruction;
|
||||||
use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
@ -2319,9 +2321,9 @@ mod tests {
|
|||||||
Some(Ok(()))
|
Some(Ok(()))
|
||||||
);
|
);
|
||||||
|
|
||||||
trace!("new form parent");
|
trace!("new from parent");
|
||||||
let bank = new_from_parent(&parent);
|
let bank = new_from_parent(&parent);
|
||||||
trace!("done new form parent");
|
trace!("done new from parent");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.get_signature_status(&tx_transfer_mint_to_1.signatures[0]),
|
bank.get_signature_status(&tx_transfer_mint_to_1.signatures[0]),
|
||||||
Some(Ok(()))
|
Some(Ok(()))
|
||||||
@ -2435,33 +2437,50 @@ mod tests {
|
|||||||
genesis_block.epoch_warmup = false; // allows me to do the normal division stuff below
|
genesis_block.epoch_warmup = false; // allows me to do the normal division stuff below
|
||||||
|
|
||||||
let parent = Arc::new(Bank::new(&genesis_block));
|
let parent = Arc::new(Bank::new(&genesis_block));
|
||||||
|
let mut leader_vote_stake: Vec<_> = parent
|
||||||
let vote_accounts0: Option<HashMap<_, _>> = parent.epoch_vote_accounts(0).map(|accounts| {
|
.epoch_vote_accounts(0)
|
||||||
accounts
|
.map(|accounts| {
|
||||||
.iter()
|
accounts
|
||||||
.filter_map(|(pubkey, (_, account))| {
|
.iter()
|
||||||
if let Ok(vote_state) = VoteState::deserialize(&account.data) {
|
.filter_map(|(pubkey, (stake, account))| {
|
||||||
if vote_state.node_pubkey == leader_pubkey {
|
if let Ok(vote_state) = VoteState::deserialize(&account.data) {
|
||||||
Some((*pubkey, true))
|
if vote_state.node_pubkey == leader_pubkey {
|
||||||
|
Some((*pubkey, *stake))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
None
|
.collect()
|
||||||
}
|
})
|
||||||
})
|
.unwrap();
|
||||||
.collect()
|
assert_eq!(leader_vote_stake.len(), 1);
|
||||||
});
|
let (leader_vote_account, leader_stake) = leader_vote_stake.pop().unwrap();
|
||||||
assert!(vote_accounts0.is_some());
|
assert!(leader_stake > 0);
|
||||||
assert!(vote_accounts0.iter().len() != 0);
|
|
||||||
|
|
||||||
let mut i = 1;
|
let leader_stake = Stake {
|
||||||
|
stake: leader_lamports,
|
||||||
|
..Stake::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut epoch = 1;
|
||||||
loop {
|
loop {
|
||||||
if i > STAKERS_SLOT_OFFSET / SLOTS_PER_EPOCH {
|
if epoch > STAKERS_SLOT_OFFSET / SLOTS_PER_EPOCH {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert!(parent.epoch_vote_accounts(i).is_some());
|
let vote_accounts = parent.epoch_vote_accounts(epoch);
|
||||||
i += 1;
|
assert!(vote_accounts.is_some());
|
||||||
|
|
||||||
|
// epoch_stakes are a snapshot at the stakers_slot_offset boundary
|
||||||
|
// in the prior epoch (0 in this case)
|
||||||
|
assert_eq!(
|
||||||
|
leader_stake.stake(0),
|
||||||
|
vote_accounts.unwrap().get(&leader_vote_account).unwrap().0
|
||||||
|
);
|
||||||
|
|
||||||
|
epoch += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// child crosses epoch boundary and is the first slot in the epoch
|
// child crosses epoch boundary and is the first slot in the epoch
|
||||||
@ -2471,15 +2490,34 @@ mod tests {
|
|||||||
SLOTS_PER_EPOCH - (STAKERS_SLOT_OFFSET % SLOTS_PER_EPOCH),
|
SLOTS_PER_EPOCH - (STAKERS_SLOT_OFFSET % SLOTS_PER_EPOCH),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(child.epoch_vote_accounts(i).is_some());
|
assert!(child.epoch_vote_accounts(epoch).is_some());
|
||||||
|
assert_eq!(
|
||||||
|
leader_stake.stake(child.epoch()),
|
||||||
|
child
|
||||||
|
.epoch_vote_accounts(epoch)
|
||||||
|
.unwrap()
|
||||||
|
.get(&leader_vote_account)
|
||||||
|
.unwrap()
|
||||||
|
.0
|
||||||
|
);
|
||||||
|
|
||||||
// child crosses epoch boundary but isn't the first slot in the epoch
|
// child crosses epoch boundary but isn't the first slot in the epoch, still
|
||||||
|
// makes an epoch stakes snapshot at 1
|
||||||
let child = Bank::new_from_parent(
|
let child = Bank::new_from_parent(
|
||||||
&parent,
|
&parent,
|
||||||
&leader_pubkey,
|
&leader_pubkey,
|
||||||
SLOTS_PER_EPOCH - (STAKERS_SLOT_OFFSET % SLOTS_PER_EPOCH) + 1,
|
SLOTS_PER_EPOCH - (STAKERS_SLOT_OFFSET % SLOTS_PER_EPOCH) + 1,
|
||||||
);
|
);
|
||||||
assert!(child.epoch_vote_accounts(i).is_some());
|
assert!(child.epoch_vote_accounts(epoch).is_some());
|
||||||
|
assert_eq!(
|
||||||
|
leader_stake.stake(child.epoch()),
|
||||||
|
child
|
||||||
|
.epoch_vote_accounts(epoch)
|
||||||
|
.unwrap()
|
||||||
|
.get(&leader_vote_account)
|
||||||
|
.unwrap()
|
||||||
|
.0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -66,6 +66,7 @@ pub fn create_genesis_block_with_leader(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
|
// Bare minimum program set
|
||||||
.native_instruction_processors(&[
|
.native_instruction_processors(&[
|
||||||
solana_bpf_loader_program!(),
|
solana_bpf_loader_program!(),
|
||||||
solana_vote_program!(),
|
solana_vote_program!(),
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user