Compare commits

..

21 Commits

Author SHA1 Message Date
mergify[bot]
f13498b428 Fix fannout gossip bench (bp #10509) (#10556)
automerge
2020-06-14 08:52:00 -07:00
Ryo Onodera
b567138170 Use git diff instead of git show for --check (#10566) (#10568)
automerge
2020-06-14 07:41:48 -07:00
mergify[bot]
653982cae5 Check the whole range of commits in the topic branch (bp #10560) (#10564)
automerge
2020-06-14 04:53:08 -07:00
mergify[bot]
605f4906ba Revert "Gossip PullRequests tend to return a lot of duplicates. (#10326)" (#10455) (#10557)
automerge
2020-06-13 23:41:06 -07:00
Michael Vines
d27f24e312 Add merge-stake subcommmand
(cherry picked from commit 0510b6e336)
2020-06-13 09:50:34 -07:00
Dan Albert
c9c1cb5c9c Add Trust Wallet security info (#10516)
automerge

(cherry picked from commit 914f285914)
2020-06-12 22:14:30 -07:00
mergify[bot]
1cc6493ccf Split commitment module (#10541) (#10547)
automerge
2020-06-12 20:59:25 -07:00
Michael Vines
ae47862be2 Add FdGYQ... to non-circulation withdrawer authority list (#10542)
automerge

(cherry picked from commit f54c049b43)
2020-06-12 18:35:07 -07:00
Michael Vines
8590184df7 Refine build condition 2020-06-12 17:02:50 -07:00
Michael Vines
d840bbab08 Disable PR builds 2020-06-12 16:51:37 -07:00
mergify[bot]
63314de516 Remove redundant BankForks parameter (#10537) (#10538)
automerge
2020-06-12 16:41:21 -07:00
mergify[bot]
c47a6e12c7 Improve BPF SDK dependency caching (#10434) (#10513)
(cherry picked from commit 97f9b63507)

Co-authored-by: Jack May <jack@solana.com>
2020-06-12 15:36:35 -07:00
mergify[bot]
7937c45ba4 Adopt heaviest subtree fork choice rule (#10441) (#10515)
automerge
2020-06-12 01:25:47 -07:00
mergify[bot]
813b11ac56 Optimize stale slot shrinking for previously cleaned roots (#10099) (#10534)
automerge
2020-06-12 00:18:40 -07:00
Michael Vines
ad6883b66a ./scripts/cargo-for-all-lock-files.sh update 2020-06-11 20:48:23 -07:00
Michael Vines
a8f4c4e297 Bump version to 1.2.2 2020-06-11 20:45:13 -07:00
mergify[bot]
6d68e94e4e Add operating mode gating (#10332) (#10531)
automerge
2020-06-11 20:05:58 -07:00
mergify[bot]
5dd40d7d88 Enable jsonrpc client (#10522) (#10525)
automerge
2020-06-11 17:19:26 -07:00
mergify[bot]
3f58177670 Update non-circulating pubkeys (#10524) (#10527)
automerge

(cherry picked from commit fb8612be49)

Co-authored-by: Greg Fitzgerald <greg@solana.com>
2020-06-11 16:58:49 -07:00
mergify[bot]
edfd65b115 Distinguish switch/non-switching votes in ReplayStage (#10218) (#10523)
automerge
2020-06-11 16:43:40 -07:00
Michael Vines
51da66ec84 Force CI_REPO_SLUG 2020-06-11 13:14:07 -07:00
137 changed files with 4626 additions and 2735 deletions

View File

@@ -13,11 +13,14 @@ script:
- source ci/env.sh
- ci/publish-tarball.sh
branches:
only:
- master
- /^v\d+\.\d+/
if: type IN (api, cron) OR tag IS present
notifications:
slack:
on_success: change

434
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-accounts-bench"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -10,10 +10,10 @@ homepage = "https://solana.com/"
[dependencies]
log = "0.4.6"
rayon = "1.3.0"
solana-logger = { path = "../logger", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-measure = { path = "../measure", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-measure = { path = "../measure", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
rand = "0.7.0"
clap = "2.33.1"
crossbeam-channel = "0.4"

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-banking-bench"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -13,16 +13,16 @@ crossbeam-channel = "0.4"
log = "0.4.6"
rand = "0.7.0"
rayon = "1.3.0"
solana-core = { path = "../core", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-streamer = { path = "../streamer", version = "1.2.1" }
solana-perf = { path = "../perf", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-measure = { path = "../measure", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-streamer = { path = "../streamer", version = "1.2.2" }
solana-perf = { path = "../perf", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-measure = { path = "../measure", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -169,7 +169,7 @@ fn main() {
let (verified_sender, verified_receiver) = unbounded();
let (vote_sender, vote_receiver) = unbounded();
let bank0 = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank0);
let mut bank_forks = BankForks::new(bank0);
let mut bank = bank_forks.working_bank();
info!("threads: {} txs: {}", num_threads, total_num_transactions);

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-exchange"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -18,21 +18,21 @@ rand = "0.7.0"
rayon = "1.3.0"
serde_json = "1.0.53"
serde_yaml = "0.8.12"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.1" }
solana-genesis = { path = "../genesis", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-faucet = { path = "../faucet", version = "1.2.1" }
solana-exchange-program = { path = "../programs/exchange", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-core = { path = "../core", version = "1.2.2" }
solana-genesis = { path = "../genesis", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-faucet = { path = "../faucet", version = "1.2.2" }
solana-exchange-program = { path = "../programs/exchange", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
[dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "1.2.1" }
solana-local-cluster = { path = "../local-cluster", version = "1.2.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,18 +2,18 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-streamer"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.1"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-streamer = { path = "../streamer", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-streamer = { path = "../streamer", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-tps"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,25 +14,25 @@ log = "0.4.8"
rayon = "1.3.0"
serde_json = "1.0.53"
serde_yaml = "0.8.12"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.1" }
solana-genesis = { path = "../genesis", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-faucet = { path = "../faucet", version = "1.2.1" }
solana-librapay = { path = "../programs/librapay", version = "1.2.1", optional = true }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-measure = { path = "../measure", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-move-loader-program = { path = "../programs/move_loader", version = "1.2.1", optional = true }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-core = { path = "../core", version = "1.2.2" }
solana-genesis = { path = "../genesis", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-faucet = { path = "../faucet", version = "1.2.2" }
solana-librapay = { path = "../programs/librapay", version = "1.2.2", optional = true }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
solana-measure = { path = "../measure", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-move-loader-program = { path = "../programs/move_loader", version = "1.2.2", optional = true }
solana-version = { path = "../version", version = "1.2.2" }
[dev-dependencies]
serial_test = "0.4.0"
serial_test_derive = "0.4.0"
solana-local-cluster = { path = "../local-cluster", version = "1.2.1" }
solana-local-cluster = { path = "../local-cluster", version = "1.2.2" }
[features]
move = ["solana-librapay", "solana-move-loader-program"]

View File

@@ -5,6 +5,9 @@
# Release tags use buildkite-release.yml instead
steps:
- command: "ci/test-sanity.sh"
name: "sanity"
timeout_in_minutes: 5
- command: "ci/dependabot-pr.sh"
name: "dependabot"
timeout_in_minutes: 5

View File

@@ -10,9 +10,6 @@ source ci/rust-version.sh nightly
export RUST_BACKTRACE=1
export RUSTFLAGS="-D warnings"
# Look for failed mergify.io backports
_ git show HEAD --check --oneline
if _ scripts/cargo-for-all-lock-files.sh +"$rust_nightly" check --locked --all-targets; then
true
else
@@ -29,10 +26,8 @@ _ cargo +"$rust_stable" clippy --workspace -- --deny=warnings
_ cargo +"$rust_stable" audit --version
_ scripts/cargo-for-all-lock-files.sh +"$rust_stable" audit --ignore RUSTSEC-2020-0002 --ignore RUSTSEC-2020-0008
_ ci/nits.sh
_ ci/order-crates-for-publishing.py
_ docs/build.sh
_ ci/check-ssh-keys.sh
{
cd programs/bpf

27
ci/test-sanity.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")/.."
source ci/_
(
echo --- git diff --check
set -x
# Look for failed mergify.io backports by searching leftover conflict markers
# Also check for any trailing whitespaces!
if [[ -n $BUILDKITE_PULL_REQUEST_BASE_BRANCH ]]; then
base_branch=$BUILDKITE_PULL_REQUEST_BASE_BRANCH
else
base_branch=$BUILDKITE_BRANCH
fi
git fetch origin "$base_branch"
git diff "$(git merge-base HEAD "origin/$base_branch")..HEAD" --check --oneline
)
echo
_ ci/nits.sh
_ ci/check-ssh-keys.sh
echo --- ok

View File

@@ -23,10 +23,14 @@ if [[ -z $CI_TAG ]]; then
exit 1
fi
if [[ -z $CI_REPO_SLUG ]]; then
echo Error: CI_REPO_SLUG not defined
exit 1
fi
# Force CI_REPO_SLUG since sometimes
# BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG is not set correctly, causing the
# artifact upload to fail
CI_REPO_SLUG=solana-labs/solana
#if [[ -z $CI_REPO_SLUG ]]; then
# echo Error: CI_REPO_SLUG not defined
# exit 1
#fi
releaseId=$( \
curl -s "https://api.github.com/repos/$CI_REPO_SLUG/releases/tags/$CI_TAG" \

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-clap-utils"
version = "1.2.1"
version = "1.2.2"
description = "Solana utilities for the clap"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,8 +11,8 @@ edition = "2018"
[dependencies]
clap = "2.33.0"
rpassword = "4.0"
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
thiserror = "1.0.11"
tiny-bip39 = "0.7.0"
url = "2.1.0"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-cli-config"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-cli"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -27,28 +27,28 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
serde = "1.0.110"
serde_derive = "1.0.103"
serde_json = "1.0.53"
solana-budget-program = { path = "../programs/budget", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-cli-config = { path = "../cli-config", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-config-program = { path = "../programs/config", version = "1.2.1" }
solana-faucet = { path = "../faucet", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-stake-program = { path = "../programs/stake", version = "1.2.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-vote-signer = { path = "../vote-signer", version = "1.2.1" }
solana-budget-program = { path = "../programs/budget", version = "1.2.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-cli-config = { path = "../cli-config", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-config-program = { path = "../programs/config", version = "1.2.2" }
solana-faucet = { path = "../faucet", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-stake-program = { path = "../programs/stake", version = "1.2.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
solana-vote-signer = { path = "../vote-signer", version = "1.2.2" }
thiserror = "1.0.19"
url = "2.1.1"
[dev-dependencies]
solana-core = { path = "../core", version = "1.2.1" }
solana-budget-program = { path = "../programs/budget", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.2" }
solana-budget-program = { path = "../programs/budget", version = "1.2.2" }
tempfile = "3.1.0"
[[bin]]

View File

@@ -324,6 +324,16 @@ pub enum CliCommand {
lamports: u64,
fee_payer: SignerIndex,
},
MergeStake {
stake_account_pubkey: Pubkey,
source_stake_account_pubkey: Pubkey,
stake_authority: SignerIndex,
sign_only: bool,
blockhash_query: BlockhashQuery,
nonce_account: Option<Pubkey>,
nonce_authority: SignerIndex,
fee_payer: SignerIndex,
},
ShowStakeHistory {
use_lamports_unit: bool,
},
@@ -691,6 +701,9 @@ pub fn parse_command(
("split-stake", Some(matches)) => {
parse_split_stake(matches, default_signer_path, wallet_manager)
}
("merge-stake", Some(matches)) => {
parse_merge_stake(matches, default_signer_path, wallet_manager)
}
("stake-authorize", Some(matches)) => {
parse_stake_authorize(matches, default_signer_path, wallet_manager)
}
@@ -1992,6 +2005,27 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
*lamports,
*fee_payer,
),
CliCommand::MergeStake {
stake_account_pubkey,
source_stake_account_pubkey,
stake_authority,
sign_only,
blockhash_query,
nonce_account,
nonce_authority,
fee_payer,
} => process_merge_stake(
&rpc_client,
config,
&stake_account_pubkey,
&source_stake_account_pubkey,
*stake_authority,
*sign_only,
blockhash_query,
*nonce_account,
*nonce_authority,
*fee_payer,
),
CliCommand::ShowStakeAccount {
pubkey: stake_account_pubkey,
use_lamports_unit,
@@ -3436,10 +3470,10 @@ mod tests {
let result = process_command(&config);
assert!(result.is_ok());
let stake_pubkey = Pubkey::new_rand();
let stake_account_pubkey = Pubkey::new_rand();
let to_pubkey = Pubkey::new_rand();
config.command = CliCommand::WithdrawStake {
stake_account_pubkey: stake_pubkey,
stake_account_pubkey,
destination_account_pubkey: to_pubkey,
lamports: 100,
withdraw_authority: 0,
@@ -3454,9 +3488,9 @@ mod tests {
let result = process_command(&config);
assert!(result.is_ok());
let stake_pubkey = Pubkey::new_rand();
let stake_account_pubkey = Pubkey::new_rand();
config.command = CliCommand::DeactivateStake {
stake_account_pubkey: stake_pubkey,
stake_account_pubkey,
stake_authority: 0,
sign_only: false,
blockhash_query: BlockhashQuery::default(),
@@ -3467,10 +3501,10 @@ mod tests {
let result = process_command(&config);
assert!(result.is_ok());
let stake_pubkey = Pubkey::new_rand();
let stake_account_pubkey = Pubkey::new_rand();
let split_stake_account = Keypair::new();
config.command = CliCommand::SplitStake {
stake_account_pubkey: stake_pubkey,
stake_account_pubkey,
stake_authority: 0,
sign_only: false,
blockhash_query: BlockhashQuery::default(),
@@ -3485,6 +3519,23 @@ mod tests {
let result = process_command(&config);
assert!(result.is_ok());
let stake_account_pubkey = Pubkey::new_rand();
let source_stake_account_pubkey = Pubkey::new_rand();
let merge_stake_account = Keypair::new();
config.command = CliCommand::MergeStake {
stake_account_pubkey,
source_stake_account_pubkey,
stake_authority: 1,
sign_only: false,
blockhash_query: BlockhashQuery::default(),
nonce_account: None,
nonce_authority: 0,
fee_payer: 0,
};
config.signers = vec![&keypair, &merge_stake_account];
let result = process_command(&config);
assert!(dbg!(result).is_ok());
config.command = CliCommand::GetSlot {
commitment_config: CommitmentConfig::default(),
};

View File

@@ -264,6 +264,29 @@ impl StakeSubCommands for App<'_, '_> {
.arg(nonce_authority_arg())
.arg(fee_payer_arg())
)
.subcommand(
SubCommand::with_name("merge-stake")
.about("Merges one stake account into another")
.arg(
pubkey!(Arg::with_name("stake_account_pubkey")
.index(1)
.value_name("STAKE_ACCOUNT_ADDRESS")
.required(true),
"Stake account to merge into")
)
.arg(
pubkey!(Arg::with_name("source_stake_account_pubkey")
.index(2)
.value_name("SOURCE_STAKE_ACCOUNT_ADDRESS")
.required(true),
"Source stake account for the merge. If successful, this stake account will no longer exist after the merge")
)
.arg(stake_authority_arg())
.offline_args()
.arg(nonce_arg())
.arg(nonce_authority_arg())
.arg(fee_payer_arg())
)
.subcommand(
SubCommand::with_name("withdraw-stake")
.about("Withdraw the unstaked SOL from the stake account")
@@ -606,6 +629,47 @@ pub fn parse_split_stake(
})
}
pub fn parse_merge_stake(
matches: &ArgMatches<'_>,
default_signer_path: &str,
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey =
pubkey_of_signer(matches, "stake_account_pubkey", wallet_manager)?.unwrap();
let source_stake_account_pubkey = pubkey_of(matches, "source_stake_account_pubkey").unwrap();
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
let nonce_account = pubkey_of(matches, NONCE_ARG.name);
let (stake_authority, stake_authority_pubkey) =
signer_of(matches, STAKE_AUTHORITY_ARG.name, wallet_manager)?;
let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
let (fee_payer, fee_payer_pubkey) = signer_of(matches, FEE_PAYER_ARG.name, wallet_manager)?;
let mut bulk_signers = vec![stake_authority, fee_payer];
if nonce_account.is_some() {
bulk_signers.push(nonce_authority);
}
let signer_info =
generate_unique_signers(bulk_signers, matches, default_signer_path, wallet_manager)?;
Ok(CliCommandInfo {
command: CliCommand::MergeStake {
stake_account_pubkey,
source_stake_account_pubkey,
stake_authority: signer_info.index_of(stake_authority_pubkey).unwrap(),
sign_only,
blockhash_query,
nonce_account,
nonce_authority: signer_info.index_of(nonce_authority_pubkey).unwrap(),
fee_payer: signer_info.index_of(fee_payer_pubkey).unwrap(),
},
signers: signer_info.signers,
})
}
pub fn parse_stake_deactivate_stake(
matches: &ArgMatches<'_>,
default_signer_path: &str,
@@ -1199,6 +1263,99 @@ pub fn process_split_stake(
}
}
#[allow(clippy::too_many_arguments)]
pub fn process_merge_stake(
rpc_client: &RpcClient,
config: &CliConfig,
stake_account_pubkey: &Pubkey,
source_stake_account_pubkey: &Pubkey,
stake_authority: SignerIndex,
sign_only: bool,
blockhash_query: &BlockhashQuery,
nonce_account: Option<Pubkey>,
nonce_authority: SignerIndex,
fee_payer: SignerIndex,
) -> ProcessResult {
let fee_payer = config.signers[fee_payer];
check_unique_pubkeys(
(&fee_payer.pubkey(), "fee-payer keypair".to_string()),
(&stake_account_pubkey, "stake_account".to_string()),
)?;
check_unique_pubkeys(
(&fee_payer.pubkey(), "fee-payer keypair".to_string()),
(
&source_stake_account_pubkey,
"source_stake_account".to_string(),
),
)?;
check_unique_pubkeys(
(&stake_account_pubkey, "stake_account".to_string()),
(
&source_stake_account_pubkey,
"source_stake_account".to_string(),
),
)?;
let stake_authority = config.signers[stake_authority];
if !sign_only {
for stake_account_address in &[stake_account_pubkey, source_stake_account_pubkey] {
if let Ok(stake_account) = rpc_client.get_account(stake_account_address) {
if stake_account.owner != solana_stake_program::id() {
return Err(CliError::BadParameter(format!(
"Account {} is not a stake account",
stake_account_address
))
.into());
}
}
}
}
let (recent_blockhash, fee_calculator) =
blockhash_query.get_blockhash_and_fee_calculator(rpc_client)?;
let ixs = stake_instruction::merge(
&stake_account_pubkey,
&source_stake_account_pubkey,
&stake_authority.pubkey(),
);
let nonce_authority = config.signers[nonce_authority];
let message = if let Some(nonce_account) = &nonce_account {
Message::new_with_nonce(
ixs,
Some(&fee_payer.pubkey()),
nonce_account,
&nonce_authority.pubkey(),
)
} else {
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx, &config)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
}
check_account_for_fee(
rpc_client,
&tx.message.account_keys[0],
&fee_calculator,
&tx.message,
)?;
let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx);
log_instruction_custom_error::<StakeError>(result, &config)
}
}
#[allow(clippy::too_many_arguments)]
pub fn process_stake_set_lockup(
rpc_client: &RpcClient,
@@ -2923,5 +3080,34 @@ mod tests {
],
}
);
// Test MergeStake SubCommand
let (keypair_file, mut tmp_file) = make_tmp_file();
let stake_account_keypair = Keypair::new();
write_keypair(&stake_account_keypair, tmp_file.as_file_mut()).unwrap();
let source_stake_account_pubkey = Pubkey::new_rand();
let test_merge_stake_account = test_commands.clone().get_matches_from(vec![
"test",
"merge-stake",
&keypair_file,
&source_stake_account_pubkey.to_string(),
]);
assert_eq!(
parse_command(&test_merge_stake_account, &default_keypair_file, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::MergeStake {
stake_account_pubkey: stake_account_keypair.pubkey(),
source_stake_account_pubkey,
stake_authority: 0,
sign_only: false,
blockhash_query: BlockhashQuery::default(),
nonce_account: None,
nonce_authority: 0,
fee_payer: 0,
},
signers: vec![read_keypair_file(&default_keypair_file).unwrap().into(),],
}
);
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client"
version = "1.2.1"
version = "1.2.2"
description = "Solana Client"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -19,10 +19,10 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
serde = "1.0.110"
serde_derive = "1.0.103"
serde_json = "1.0.53"
solana-transaction-status = { path = "../transaction-status", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
thiserror = "1.0"
tungstenite = "0.10.1"
url = "2.1.1"
@@ -31,7 +31,7 @@ url = "2.1.1"
assert_matches = "1.3.0"
jsonrpc-core = "14.1.0"
jsonrpc-http-server = "14.1.0"
solana-logger = { path = "../logger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-core"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -42,35 +42,35 @@ regex = "1.3.7"
serde = "1.0.110"
serde_derive = "1.0.103"
serde_json = "1.0.53"
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.1" }
solana-budget-program = { path = "../programs/budget", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.1" }
solana-faucet = { path = "../faucet", version = "1.2.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-measure = { path = "../measure", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-perf = { path = "../perf", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-stake-program = { path = "../programs/stake", version = "1.2.1" }
solana-streamer = { path = "../streamer", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-vote-signer = { path = "../vote-signer", version = "1.2.1" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.1" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.2" }
solana-budget-program = { path = "../programs/budget", version = "1.2.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.2" }
solana-faucet = { path = "../faucet", version = "1.2.2" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
solana-measure = { path = "../measure", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-perf = { path = "../perf", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-stake-program = { path = "../programs/stake", version = "1.2.2" }
solana-streamer = { path = "../streamer", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
solana-vote-signer = { path = "../vote-signer", version = "1.2.2" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.2" }
tempfile = "3.1.0"
thiserror = "1.0"
tokio = "0.1"
tokio-codec = "0.1"
tokio-fs = "0.1"
tokio-io = "0.1"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.2" }
trees = "0.2.1"
[dev-dependencies]

View File

@@ -49,7 +49,7 @@ fn bench_retransmitter(bencher: &mut Bencher) {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(100_000);
let bank0 = Bank::new(&genesis_config);
let bank_forks = BankForks::new(0, bank0);
let bank_forks = BankForks::new(bank0);
let bank = bank_forks.working_bank();
let bank_forks = Arc::new(RwLock::new(bank_forks));
let (packet_sender, packet_receiver) = channel();

View File

@@ -15,11 +15,15 @@ pub struct AccountsBackgroundService {
}
const INTERVAL_MS: u64 = 100;
const SHRUNKEN_ACCOUNT_PER_SEC: usize = 250;
const SHRUNKEN_ACCOUNT_PER_INTERVAL: usize =
SHRUNKEN_ACCOUNT_PER_SEC / (1000 / INTERVAL_MS as usize);
impl AccountsBackgroundService {
pub fn new(bank_forks: Arc<RwLock<BankForks>>, exit: &Arc<AtomicBool>) -> Self {
info!("AccountsBackgroundService active");
let exit = exit.clone();
let mut consumed_budget = 0;
let t_background = Builder::new()
.name("solana-accounts-background".to_string())
.spawn(move || loop {
@@ -30,8 +34,8 @@ impl AccountsBackgroundService {
bank.process_dead_slots();
// Currently, given INTERVAL_MS, we process 1 slot/100 ms
bank.process_stale_slot();
consumed_budget = bank
.process_stale_slot_with_budget(consumed_budget, SHRUNKEN_ACCOUNT_PER_INTERVAL);
sleep(Duration::from_millis(INTERVAL_MS));
})

View File

@@ -0,0 +1,152 @@
use crate::{
consensus::{ComputedBankState, Tower},
fork_choice::ForkChoice,
progress_map::{ForkStats, ProgressMap},
};
use solana_ledger::bank_forks::BankForks;
use solana_runtime::bank::Bank;
use solana_sdk::timing;
use std::time::Instant;
use std::{
collections::{HashMap, HashSet},
sync::{Arc, RwLock},
};
#[derive(Default)]
pub struct BankWeightForkChoice {}
impl ForkChoice for BankWeightForkChoice {
fn compute_bank_stats(
&mut self,
bank: &Bank,
_tower: &Tower,
progress: &mut ProgressMap,
computed_bank_stats: &ComputedBankState,
) {
let bank_slot = bank.slot();
// Only time progress map should be missing a bank slot
// is if this node was the leader for this slot as those banks
// are not replayed in replay_active_banks()
let parent_weight = bank
.parent()
.and_then(|b| progress.get(&b.slot()))
.map(|x| x.fork_stats.fork_weight)
.unwrap_or(0);
let stats = progress
.get_fork_stats_mut(bank_slot)
.expect("All frozen banks must exist in the Progress map");
let ComputedBankState { bank_weight, .. } = computed_bank_stats;
stats.weight = *bank_weight;
stats.fork_weight = stats.weight + parent_weight;
}
// Returns:
// 1) The heaviest overall bank
// 2) The heavest bank on the same fork as the last vote (doesn't require a
// switching proof to vote for)
fn select_forks(
&self,
frozen_banks: &[Arc<Bank>],
tower: &Tower,
progress: &ProgressMap,
ancestors: &HashMap<u64, HashSet<u64>>,
_bank_forks: &RwLock<BankForks>,
) -> (Arc<Bank>, Option<Arc<Bank>>) {
let tower_start = Instant::now();
assert!(!frozen_banks.is_empty());
let num_frozen_banks = frozen_banks.len();
trace!("frozen_banks {}", frozen_banks.len());
let num_old_banks = frozen_banks
.iter()
.filter(|b| b.slot() < tower.root().unwrap_or(0))
.count();
let last_vote = tower.last_vote().slots.last().cloned();
let mut heaviest_bank_on_same_fork = None;
let mut heaviest_same_fork_weight = 0;
let stats: Vec<&ForkStats> = frozen_banks
.iter()
.map(|bank| {
// Only time progress map should be missing a bank slot
// is if this node was the leader for this slot as those banks
// are not replayed in replay_active_banks()
let stats = progress
.get_fork_stats(bank.slot())
.expect("All frozen banks must exist in the Progress map");
if let Some(last_vote) = last_vote {
if ancestors
.get(&bank.slot())
.expect("Entry in frozen banks must exist in ancestors")
.contains(&last_vote)
{
// Descendant of last vote cannot be locked out
assert!(!stats.is_locked_out);
// ancestors(slot) should not contain the slot itself,
// so we should never get the same bank as the last vote
assert_ne!(bank.slot(), last_vote);
// highest weight, lowest slot first. frozen_banks is sorted
// from least slot to greatest slot, so if two banks have
// the same fork weight, the lower slot will be picked
if stats.fork_weight > heaviest_same_fork_weight {
heaviest_bank_on_same_fork = Some(bank.clone());
heaviest_same_fork_weight = stats.fork_weight;
}
}
}
stats
})
.collect();
let num_not_recent = stats.iter().filter(|s| !s.is_recent).count();
let num_has_voted = stats.iter().filter(|s| s.has_voted).count();
let num_empty = stats.iter().filter(|s| s.is_empty).count();
let num_threshold_failure = stats.iter().filter(|s| !s.vote_threshold).count();
let num_votable_threshold_failure = stats
.iter()
.filter(|s| s.is_recent && !s.has_voted && !s.vote_threshold)
.count();
let mut candidates: Vec<_> = frozen_banks.iter().zip(stats.iter()).collect();
//highest weight, lowest slot first
candidates.sort_by_key(|b| (b.1.fork_weight, 0i64 - b.0.slot() as i64));
let rv = candidates
.last()
.expect("frozen banks was nonempty so candidates must also be nonempty");
let ms = timing::duration_as_ms(&tower_start.elapsed());
let weights: Vec<(u128, u64, u64)> = candidates
.iter()
.map(|x| (x.1.weight, x.0.slot(), x.1.block_height))
.collect();
debug!(
"@{:?} tower duration: {:?} len: {}/{} weights: {:?}",
timing::timestamp(),
ms,
candidates.len(),
stats.iter().filter(|s| !s.has_voted).count(),
weights,
);
datapoint_debug!(
"replay_stage-select_forks",
("frozen_banks", num_frozen_banks as i64, i64),
("not_recent", num_not_recent as i64, i64),
("has_voted", num_has_voted as i64, i64),
("old_banks", num_old_banks as i64, i64),
("empty_banks", num_empty as i64, i64),
("threshold_failure", num_threshold_failure as i64, i64),
(
"votable_threshold_failure",
num_votable_threshold_failure as i64,
i64
),
("tower_duration", ms as i64, i64),
);
(rv.0.clone(), heaviest_bank_on_same_fork)
}
}

View File

@@ -51,7 +51,7 @@ type PacketsAndOffsets = (Packets, Vec<usize>);
pub type UnprocessedPackets = Vec<PacketsAndOffsets>;
/// Transaction forwarding
pub const FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET: u64 = 4;
pub const FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET: u64 = 1;
// Fixed thread size seems to be fastest on GCP setup
pub const NUM_THREADS: u32 = 4;

View File

@@ -252,7 +252,7 @@ pub struct ClusterInfo {
my_contact_info: RwLock<ContactInfo>,
id: Pubkey,
stats: GossipStats,
start_time: u64,
socket: UdpSocket,
}
impl Default for ClusterInfo {
@@ -399,7 +399,6 @@ impl ClusterInfo {
let id = contact_info.id;
let me = Self {
gossip: RwLock::new(CrdsGossip::default()),
start_time: timestamp(),
keypair,
entrypoint: RwLock::new(None),
outbound_budget: RwLock::new(DataBudget {
@@ -409,6 +408,7 @@ impl ClusterInfo {
my_contact_info: RwLock::new(contact_info),
id,
stats: GossipStats::default(),
socket: UdpSocket::bind("0.0.0.0:0").unwrap(),
};
{
let mut gossip = me.gossip.write().unwrap();
@@ -434,7 +434,7 @@ impl ClusterInfo {
my_contact_info: RwLock::new(my_contact_info),
id: *new_id,
stats: GossipStats::default(),
start_time: self.start_time,
socket: UdpSocket::bind("0.0.0.0:0").unwrap(),
}
}
@@ -740,6 +740,13 @@ impl ClusterInfo {
.process_push_message(&self.id(), vec![entry], now);
}
pub fn send_vote(&self, vote: &Transaction) -> Result<()> {
let tpu = self.my_contact_info().tpu;
let buf = serialize(vote)?;
self.socket.send_to(&buf, &tpu)?;
Ok(())
}
/// Get votes in the crds
/// * since - The timestamp of when the vote inserted must be greater than
/// since. This allows the bank to query for new votes only.
@@ -1727,18 +1734,9 @@ impl ClusterInfo {
let now = timestamp();
let self_id = me.id();
//skip messages that are likely to be pushed
let min_filter_time = me.start_time + 10 * CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS;
let push_timer = if min_filter_time < now {
// reason for / 3 is to allow push_self which has a /2 timeout to propagate
// first through push before responding with those values.
Some(now - CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS / 3)
} else {
None
};
let pull_responses = me
.time_gossip_read_lock("generate_pull_responses", &me.stats.generate_pull_responses)
.generate_pull_responses(&caller_and_filters, push_timer);
.generate_pull_responses(&caller_and_filters);
me.time_gossip_write_lock("process_pull_reqs", &me.stats.process_pull_requests)
.process_pull_requests(caller_and_filters, now);
@@ -2228,7 +2226,7 @@ impl ClusterInfo {
.name("solana-listen".to_string())
.spawn(move || {
let thread_pool = rayon::ThreadPoolBuilder::new()
.num_threads(get_thread_count())
.num_threads(std::cmp::min(get_thread_count(), 8))
.thread_name(|i| format!("sol-gossip-work-{}", i))
.build()
.unwrap();

View File

@@ -1,6 +1,6 @@
use crate::{
cluster_info::{ClusterInfo, GOSSIP_SLEEP_MILLIS},
consensus::VOTE_THRESHOLD_SIZE,
commitment::VOTE_THRESHOLD_SIZE,
crds_value::CrdsValueLabel,
poh_recorder::PohRecorder,
pubkey_references::LockedPubkeyReferences,
@@ -948,7 +948,7 @@ mod tests {
);
let bank = Bank::new(&genesis_config);
let exit = Arc::new(AtomicBool::new(false));
let bank_forks = BankForks::new(0, bank);
let bank_forks = BankForks::new(bank);
let bank = bank_forks.get(0).unwrap().clone();
let vote_tracker = VoteTracker::new(&bank);
let ledger_path = get_tmp_ledger_path!();
@@ -1064,7 +1064,7 @@ mod tests {
let bank = Bank::new(&genesis_config);
let vote_tracker = VoteTracker::new(&bank);
let exit = Arc::new(AtomicBool::new(false));
let bank_forks = BankForks::new(0, bank);
let bank_forks = BankForks::new(bank);
let bank = bank_forks.get(0).unwrap().clone();
let ledger_path = get_tmp_ledger_path!();
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());

View File

@@ -1,26 +1,10 @@
use crate::{consensus::VOTE_THRESHOLD_SIZE, rpc_subscriptions::RpcSubscriptions};
use solana_ledger::blockstore::Blockstore;
use solana_measure::measure::Measure;
use solana_metrics::datapoint_info;
use solana_runtime::bank::Bank;
use solana_sdk::clock::Slot;
use solana_vote_program::{vote_state::VoteState, vote_state::MAX_LOCKOUT_HISTORY};
use std::{
collections::HashMap,
sync::atomic::{AtomicBool, Ordering},
sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender},
sync::{Arc, RwLock},
thread::{self, Builder, JoinHandle},
time::Duration,
};
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
use std::{collections::HashMap, sync::Arc};
#[derive(Default)]
pub struct CacheSlotInfo {
pub current_slot: Slot,
pub node_root: Slot,
pub largest_confirmed_root: Slot,
pub highest_confirmed_slot: Slot,
}
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
pub type BlockCommitmentArray = [u64; MAX_LOCKOUT_HISTORY + 1];
@@ -59,9 +43,9 @@ pub struct BlockCommitmentCache {
largest_confirmed_root: Slot,
total_stake: u64,
bank: Arc<Bank>,
blockstore: Arc<Blockstore>,
pub blockstore: Arc<Blockstore>,
root: Slot,
highest_confirmed_slot: Slot,
pub highest_confirmed_slot: Slot,
}
impl std::fmt::Debug for BlockCommitmentCache {
@@ -151,7 +135,7 @@ impl BlockCommitmentCache {
self.root
}
fn calculate_highest_confirmed_slot(&self) -> Slot {
pub fn calculate_highest_confirmed_slot(&self) -> Slot {
self.highest_slot_with_confirmation_count(1)
}
@@ -219,222 +203,11 @@ impl BlockCommitmentCache {
}
}
pub struct CommitmentAggregationData {
bank: Arc<Bank>,
root: Slot,
total_staked: u64,
}
impl CommitmentAggregationData {
pub fn new(bank: Arc<Bank>, root: Slot, total_staked: u64) -> Self {
Self {
bank,
root,
total_staked,
}
}
}
fn get_largest_confirmed_root(mut rooted_stake: Vec<(Slot, u64)>, total_stake: u64) -> Slot {
rooted_stake.sort_by(|a, b| a.0.cmp(&b.0).reverse());
let mut stake_sum = 0;
for (root, stake) in rooted_stake {
stake_sum += stake;
if (stake_sum as f64 / total_stake as f64) > VOTE_THRESHOLD_SIZE {
return root;
}
}
0
}
pub struct AggregateCommitmentService {
t_commitment: JoinHandle<()>,
}
impl AggregateCommitmentService {
pub fn new(
exit: &Arc<AtomicBool>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
subscriptions: Arc<RpcSubscriptions>,
) -> (Sender<CommitmentAggregationData>, Self) {
let (sender, receiver): (
Sender<CommitmentAggregationData>,
Receiver<CommitmentAggregationData>,
) = channel();
let exit_ = exit.clone();
(
sender,
Self {
t_commitment: Builder::new()
.name("solana-aggregate-stake-lockouts".to_string())
.spawn(move || loop {
if exit_.load(Ordering::Relaxed) {
break;
}
if let Err(RecvTimeoutError::Disconnected) =
Self::run(&receiver, &block_commitment_cache, &subscriptions, &exit_)
{
break;
}
})
.unwrap(),
},
)
}
fn run(
receiver: &Receiver<CommitmentAggregationData>,
block_commitment_cache: &RwLock<BlockCommitmentCache>,
subscriptions: &Arc<RpcSubscriptions>,
exit: &Arc<AtomicBool>,
) -> Result<(), RecvTimeoutError> {
loop {
if exit.load(Ordering::Relaxed) {
return Ok(());
}
let mut aggregation_data = receiver.recv_timeout(Duration::from_secs(1))?;
while let Ok(new_data) = receiver.try_recv() {
aggregation_data = new_data;
}
let ancestors = aggregation_data.bank.status_cache_ancestors();
if ancestors.is_empty() {
continue;
}
let mut aggregate_commitment_time = Measure::start("aggregate-commitment-ms");
let (block_commitment, rooted_stake) =
Self::aggregate_commitment(&ancestors, &aggregation_data.bank);
let largest_confirmed_root =
get_largest_confirmed_root(rooted_stake, aggregation_data.total_staked);
let mut new_block_commitment = BlockCommitmentCache::new(
block_commitment,
largest_confirmed_root,
aggregation_data.total_staked,
aggregation_data.bank,
block_commitment_cache.read().unwrap().blockstore.clone(),
aggregation_data.root,
aggregation_data.root,
);
new_block_commitment.highest_confirmed_slot =
new_block_commitment.calculate_highest_confirmed_slot();
let mut w_block_commitment_cache = block_commitment_cache.write().unwrap();
std::mem::swap(&mut *w_block_commitment_cache, &mut new_block_commitment);
aggregate_commitment_time.stop();
datapoint_info!(
"block-commitment-cache",
(
"aggregate-commitment-ms",
aggregate_commitment_time.as_ms() as i64,
i64
)
);
subscriptions.notify_subscribers(CacheSlotInfo {
current_slot: w_block_commitment_cache.slot(),
node_root: w_block_commitment_cache.root(),
largest_confirmed_root: w_block_commitment_cache.largest_confirmed_root(),
highest_confirmed_slot: w_block_commitment_cache.highest_confirmed_slot(),
});
}
}
pub fn aggregate_commitment(
ancestors: &[Slot],
bank: &Bank,
) -> (HashMap<Slot, BlockCommitment>, Vec<(Slot, u64)>) {
assert!(!ancestors.is_empty());
// Check ancestors is sorted
for a in ancestors.windows(2) {
assert!(a[0] < a[1]);
}
let mut commitment = HashMap::new();
let mut rooted_stake: Vec<(Slot, u64)> = Vec::new();
for (_, (lamports, account)) in bank.vote_accounts().into_iter() {
if lamports == 0 {
continue;
}
let vote_state = VoteState::from(&account);
if vote_state.is_none() {
continue;
}
let vote_state = vote_state.unwrap();
Self::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
ancestors,
lamports,
);
}
(commitment, rooted_stake)
}
fn aggregate_commitment_for_vote_account(
commitment: &mut HashMap<Slot, BlockCommitment>,
rooted_stake: &mut Vec<(Slot, u64)>,
vote_state: &VoteState,
ancestors: &[Slot],
lamports: u64,
) {
assert!(!ancestors.is_empty());
let mut ancestors_index = 0;
if let Some(root) = vote_state.root_slot {
for (i, a) in ancestors.iter().enumerate() {
if *a <= root {
commitment
.entry(*a)
.or_insert_with(BlockCommitment::default)
.increase_rooted_stake(lamports);
} else {
ancestors_index = i;
break;
}
}
rooted_stake.push((root, lamports));
}
for vote in &vote_state.votes {
while ancestors[ancestors_index] <= vote.slot {
commitment
.entry(ancestors[ancestors_index])
.or_insert_with(BlockCommitment::default)
.increase_confirmation_stake(vote.confirmation_count as usize, lamports);
ancestors_index += 1;
if ancestors_index == ancestors.len() {
return;
}
}
}
}
pub fn join(self) -> thread::Result<()> {
self.t_commitment.join()
}
}
#[cfg(test)]
mod tests {
use super::*;
use solana_ledger::{
genesis_utils::{create_genesis_config, GenesisConfigInfo},
get_tmp_ledger_path,
};
use solana_ledger::get_tmp_ledger_path;
use solana_sdk::{genesis_config::GenesisConfig, pubkey::Pubkey};
use solana_stake_program::stake_state;
use solana_vote_program::vote_state::{self, VoteStateVersions};
#[test]
fn test_block_commitment() {
@@ -512,21 +285,6 @@ mod tests {
assert!(!block_commitment_cache.is_confirmed_rooted(3));
}
#[test]
fn test_get_largest_confirmed_root() {
assert_eq!(get_largest_confirmed_root(vec![], 10), 0);
let mut rooted_stake = vec![];
rooted_stake.push((0, 5));
rooted_stake.push((1, 5));
assert_eq!(get_largest_confirmed_root(rooted_stake, 10), 0);
let mut rooted_stake = vec![];
rooted_stake.push((1, 5));
rooted_stake.push((0, 10));
rooted_stake.push((2, 5));
rooted_stake.push((1, 4));
assert_eq!(get_largest_confirmed_root(rooted_stake, 10), 1);
}
#[test]
fn test_highest_confirmed_slot() {
let bank = Arc::new(Bank::new(&GenesisConfig::default()));
@@ -634,211 +392,4 @@ mod tests {
assert_eq!(block_commitment_cache.calculate_highest_confirmed_slot(), 0);
}
#[test]
fn test_aggregate_commitment_for_vote_account_1() {
let ancestors = vec![3, 4, 5, 7, 9, 11];
let mut commitment = HashMap::new();
let mut rooted_stake = vec![];
let lamports = 5;
let mut vote_state = VoteState::default();
let root = *ancestors.last().unwrap();
vote_state.root_slot = Some(root);
AggregateCommitmentService::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
&ancestors,
lamports,
);
for a in ancestors {
let mut expected = BlockCommitment::default();
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
assert_eq!(rooted_stake[0], (root, lamports));
}
#[test]
fn test_aggregate_commitment_for_vote_account_2() {
let ancestors = vec![3, 4, 5, 7, 9, 11];
let mut commitment = HashMap::new();
let mut rooted_stake = vec![];
let lamports = 5;
let mut vote_state = VoteState::default();
let root = ancestors[2];
vote_state.root_slot = Some(root);
vote_state.process_slot_vote_unchecked(*ancestors.last().unwrap());
AggregateCommitmentService::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
&ancestors,
lamports,
);
for a in ancestors {
if a <= root {
let mut expected = BlockCommitment::default();
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
}
assert_eq!(rooted_stake[0], (root, lamports));
}
#[test]
fn test_aggregate_commitment_for_vote_account_3() {
let ancestors = vec![3, 4, 5, 7, 9, 10, 11];
let mut commitment = HashMap::new();
let mut rooted_stake = vec![];
let lamports = 5;
let mut vote_state = VoteState::default();
let root = ancestors[2];
vote_state.root_slot = Some(root);
assert!(ancestors[4] + 2 >= ancestors[6]);
vote_state.process_slot_vote_unchecked(ancestors[4]);
vote_state.process_slot_vote_unchecked(ancestors[6]);
AggregateCommitmentService::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
&ancestors,
lamports,
);
for (i, a) in ancestors.iter().enumerate() {
if *a <= root {
let mut expected = BlockCommitment::default();
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if i <= 4 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(2, lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if i <= 6 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
}
assert_eq!(rooted_stake[0], (root, lamports));
}
#[test]
fn test_aggregate_commitment_validity() {
let ancestors = vec![3, 4, 5, 7, 9, 10, 11];
let GenesisConfigInfo {
mut genesis_config, ..
} = create_genesis_config(10_000);
let rooted_stake_amount = 40;
let sk1 = Pubkey::new_rand();
let pk1 = Pubkey::new_rand();
let mut vote_account1 = vote_state::create_account(&pk1, &Pubkey::new_rand(), 0, 100);
let stake_account1 =
stake_state::create_account(&sk1, &pk1, &vote_account1, &genesis_config.rent, 100);
let sk2 = Pubkey::new_rand();
let pk2 = Pubkey::new_rand();
let mut vote_account2 = vote_state::create_account(&pk2, &Pubkey::new_rand(), 0, 50);
let stake_account2 =
stake_state::create_account(&sk2, &pk2, &vote_account2, &genesis_config.rent, 50);
let sk3 = Pubkey::new_rand();
let pk3 = Pubkey::new_rand();
let mut vote_account3 = vote_state::create_account(&pk3, &Pubkey::new_rand(), 0, 1);
let stake_account3 = stake_state::create_account(
&sk3,
&pk3,
&vote_account3,
&genesis_config.rent,
rooted_stake_amount,
);
let sk4 = Pubkey::new_rand();
let pk4 = Pubkey::new_rand();
let mut vote_account4 = vote_state::create_account(&pk4, &Pubkey::new_rand(), 0, 1);
let stake_account4 = stake_state::create_account(
&sk4,
&pk4,
&vote_account4,
&genesis_config.rent,
rooted_stake_amount,
);
genesis_config.accounts.extend(vec![
(pk1, vote_account1.clone()),
(sk1, stake_account1),
(pk2, vote_account2.clone()),
(sk2, stake_account2),
(pk3, vote_account3.clone()),
(sk3, stake_account3),
(pk4, vote_account4.clone()),
(sk4, stake_account4),
]);
// Create bank
let bank = Arc::new(Bank::new(&genesis_config));
let mut vote_state1 = VoteState::from(&vote_account1).unwrap();
vote_state1.process_slot_vote_unchecked(3);
vote_state1.process_slot_vote_unchecked(5);
let versioned = VoteStateVersions::Current(Box::new(vote_state1));
VoteState::to(&versioned, &mut vote_account1).unwrap();
bank.store_account(&pk1, &vote_account1);
let mut vote_state2 = VoteState::from(&vote_account2).unwrap();
vote_state2.process_slot_vote_unchecked(9);
vote_state2.process_slot_vote_unchecked(10);
let versioned = VoteStateVersions::Current(Box::new(vote_state2));
VoteState::to(&versioned, &mut vote_account2).unwrap();
bank.store_account(&pk2, &vote_account2);
let mut vote_state3 = VoteState::from(&vote_account3).unwrap();
vote_state3.root_slot = Some(1);
let versioned = VoteStateVersions::Current(Box::new(vote_state3));
VoteState::to(&versioned, &mut vote_account3).unwrap();
bank.store_account(&pk3, &vote_account3);
let mut vote_state4 = VoteState::from(&vote_account4).unwrap();
vote_state4.root_slot = Some(2);
let versioned = VoteStateVersions::Current(Box::new(vote_state4));
VoteState::to(&versioned, &mut vote_account4).unwrap();
bank.store_account(&pk4, &vote_account4);
let (commitment, rooted_stake) =
AggregateCommitmentService::aggregate_commitment(&ancestors, &bank);
for a in ancestors {
if a <= 3 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(2, 150);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if a <= 5 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, 100);
expected.increase_confirmation_stake(2, 50);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if a <= 9 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(2, 50);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if a <= 10 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, 50);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else {
assert!(commitment.get(&a).is_none());
}
}
assert_eq!(rooted_stake.len(), 2);
assert_eq!(get_largest_confirmed_root(rooted_stake, 100), 1)
}
}

View File

@@ -0,0 +1,454 @@
use crate::{
commitment::{BlockCommitment, BlockCommitmentCache, VOTE_THRESHOLD_SIZE},
rpc_subscriptions::{CacheSlotInfo, RpcSubscriptions},
};
use solana_measure::measure::Measure;
use solana_metrics::datapoint_info;
use solana_runtime::bank::Bank;
use solana_sdk::clock::Slot;
use solana_vote_program::vote_state::VoteState;
use std::{
collections::HashMap,
sync::atomic::{AtomicBool, Ordering},
sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender},
sync::{Arc, RwLock},
thread::{self, Builder, JoinHandle},
time::Duration,
};
pub struct CommitmentAggregationData {
bank: Arc<Bank>,
root: Slot,
total_staked: u64,
}
impl CommitmentAggregationData {
pub fn new(bank: Arc<Bank>, root: Slot, total_staked: u64) -> Self {
Self {
bank,
root,
total_staked,
}
}
}
fn get_largest_confirmed_root(mut rooted_stake: Vec<(Slot, u64)>, total_stake: u64) -> Slot {
rooted_stake.sort_by(|a, b| a.0.cmp(&b.0).reverse());
let mut stake_sum = 0;
for (root, stake) in rooted_stake {
stake_sum += stake;
if (stake_sum as f64 / total_stake as f64) > VOTE_THRESHOLD_SIZE {
return root;
}
}
0
}
pub struct AggregateCommitmentService {
t_commitment: JoinHandle<()>,
}
impl AggregateCommitmentService {
pub fn new(
exit: &Arc<AtomicBool>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
subscriptions: Arc<RpcSubscriptions>,
) -> (Sender<CommitmentAggregationData>, Self) {
let (sender, receiver): (
Sender<CommitmentAggregationData>,
Receiver<CommitmentAggregationData>,
) = channel();
let exit_ = exit.clone();
(
sender,
Self {
t_commitment: Builder::new()
.name("solana-aggregate-stake-lockouts".to_string())
.spawn(move || loop {
if exit_.load(Ordering::Relaxed) {
break;
}
if let Err(RecvTimeoutError::Disconnected) =
Self::run(&receiver, &block_commitment_cache, &subscriptions, &exit_)
{
break;
}
})
.unwrap(),
},
)
}
fn run(
receiver: &Receiver<CommitmentAggregationData>,
block_commitment_cache: &RwLock<BlockCommitmentCache>,
subscriptions: &Arc<RpcSubscriptions>,
exit: &Arc<AtomicBool>,
) -> Result<(), RecvTimeoutError> {
loop {
if exit.load(Ordering::Relaxed) {
return Ok(());
}
let mut aggregation_data = receiver.recv_timeout(Duration::from_secs(1))?;
while let Ok(new_data) = receiver.try_recv() {
aggregation_data = new_data;
}
let ancestors = aggregation_data.bank.status_cache_ancestors();
if ancestors.is_empty() {
continue;
}
let mut aggregate_commitment_time = Measure::start("aggregate-commitment-ms");
let (block_commitment, rooted_stake) =
Self::aggregate_commitment(&ancestors, &aggregation_data.bank);
let largest_confirmed_root =
get_largest_confirmed_root(rooted_stake, aggregation_data.total_staked);
let mut new_block_commitment = BlockCommitmentCache::new(
block_commitment,
largest_confirmed_root,
aggregation_data.total_staked,
aggregation_data.bank,
block_commitment_cache.read().unwrap().blockstore.clone(),
aggregation_data.root,
aggregation_data.root,
);
new_block_commitment.highest_confirmed_slot =
new_block_commitment.calculate_highest_confirmed_slot();
let mut w_block_commitment_cache = block_commitment_cache.write().unwrap();
std::mem::swap(&mut *w_block_commitment_cache, &mut new_block_commitment);
aggregate_commitment_time.stop();
datapoint_info!(
"block-commitment-cache",
(
"aggregate-commitment-ms",
aggregate_commitment_time.as_ms() as i64,
i64
)
);
subscriptions.notify_subscribers(CacheSlotInfo {
current_slot: w_block_commitment_cache.slot(),
node_root: w_block_commitment_cache.root(),
largest_confirmed_root: w_block_commitment_cache.largest_confirmed_root(),
highest_confirmed_slot: w_block_commitment_cache.highest_confirmed_slot(),
});
}
}
pub fn aggregate_commitment(
ancestors: &[Slot],
bank: &Bank,
) -> (HashMap<Slot, BlockCommitment>, Vec<(Slot, u64)>) {
assert!(!ancestors.is_empty());
// Check ancestors is sorted
for a in ancestors.windows(2) {
assert!(a[0] < a[1]);
}
let mut commitment = HashMap::new();
let mut rooted_stake: Vec<(Slot, u64)> = Vec::new();
for (_, (lamports, account)) in bank.vote_accounts().into_iter() {
if lamports == 0 {
continue;
}
let vote_state = VoteState::from(&account);
if vote_state.is_none() {
continue;
}
let vote_state = vote_state.unwrap();
Self::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
ancestors,
lamports,
);
}
(commitment, rooted_stake)
}
fn aggregate_commitment_for_vote_account(
commitment: &mut HashMap<Slot, BlockCommitment>,
rooted_stake: &mut Vec<(Slot, u64)>,
vote_state: &VoteState,
ancestors: &[Slot],
lamports: u64,
) {
assert!(!ancestors.is_empty());
let mut ancestors_index = 0;
if let Some(root) = vote_state.root_slot {
for (i, a) in ancestors.iter().enumerate() {
if *a <= root {
commitment
.entry(*a)
.or_insert_with(BlockCommitment::default)
.increase_rooted_stake(lamports);
} else {
ancestors_index = i;
break;
}
}
rooted_stake.push((root, lamports));
}
for vote in &vote_state.votes {
while ancestors[ancestors_index] <= vote.slot {
commitment
.entry(ancestors[ancestors_index])
.or_insert_with(BlockCommitment::default)
.increase_confirmation_stake(vote.confirmation_count as usize, lamports);
ancestors_index += 1;
if ancestors_index == ancestors.len() {
return;
}
}
}
}
pub fn join(self) -> thread::Result<()> {
self.t_commitment.join()
}
}
#[cfg(test)]
mod tests {
use super::*;
use solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo};
use solana_sdk::pubkey::Pubkey;
use solana_stake_program::stake_state;
use solana_vote_program::vote_state::{self, VoteStateVersions};
#[test]
fn test_get_largest_confirmed_root() {
assert_eq!(get_largest_confirmed_root(vec![], 10), 0);
let mut rooted_stake = vec![];
rooted_stake.push((0, 5));
rooted_stake.push((1, 5));
assert_eq!(get_largest_confirmed_root(rooted_stake, 10), 0);
let mut rooted_stake = vec![];
rooted_stake.push((1, 5));
rooted_stake.push((0, 10));
rooted_stake.push((2, 5));
rooted_stake.push((1, 4));
assert_eq!(get_largest_confirmed_root(rooted_stake, 10), 1);
}
#[test]
fn test_aggregate_commitment_for_vote_account_1() {
let ancestors = vec![3, 4, 5, 7, 9, 11];
let mut commitment = HashMap::new();
let mut rooted_stake = vec![];
let lamports = 5;
let mut vote_state = VoteState::default();
let root = *ancestors.last().unwrap();
vote_state.root_slot = Some(root);
AggregateCommitmentService::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
&ancestors,
lamports,
);
for a in ancestors {
let mut expected = BlockCommitment::default();
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
assert_eq!(rooted_stake[0], (root, lamports));
}
#[test]
fn test_aggregate_commitment_for_vote_account_2() {
let ancestors = vec![3, 4, 5, 7, 9, 11];
let mut commitment = HashMap::new();
let mut rooted_stake = vec![];
let lamports = 5;
let mut vote_state = VoteState::default();
let root = ancestors[2];
vote_state.root_slot = Some(root);
vote_state.process_slot_vote_unchecked(*ancestors.last().unwrap());
AggregateCommitmentService::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
&ancestors,
lamports,
);
for a in ancestors {
if a <= root {
let mut expected = BlockCommitment::default();
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
}
assert_eq!(rooted_stake[0], (root, lamports));
}
#[test]
fn test_aggregate_commitment_for_vote_account_3() {
let ancestors = vec![3, 4, 5, 7, 9, 10, 11];
let mut commitment = HashMap::new();
let mut rooted_stake = vec![];
let lamports = 5;
let mut vote_state = VoteState::default();
let root = ancestors[2];
vote_state.root_slot = Some(root);
assert!(ancestors[4] + 2 >= ancestors[6]);
vote_state.process_slot_vote_unchecked(ancestors[4]);
vote_state.process_slot_vote_unchecked(ancestors[6]);
AggregateCommitmentService::aggregate_commitment_for_vote_account(
&mut commitment,
&mut rooted_stake,
&vote_state,
&ancestors,
lamports,
);
for (i, a) in ancestors.iter().enumerate() {
if *a <= root {
let mut expected = BlockCommitment::default();
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if i <= 4 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(2, lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if i <= 6 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
}
assert_eq!(rooted_stake[0], (root, lamports));
}
#[test]
fn test_aggregate_commitment_validity() {
let ancestors = vec![3, 4, 5, 7, 9, 10, 11];
let GenesisConfigInfo {
mut genesis_config, ..
} = create_genesis_config(10_000);
let rooted_stake_amount = 40;
let sk1 = Pubkey::new_rand();
let pk1 = Pubkey::new_rand();
let mut vote_account1 = vote_state::create_account(&pk1, &Pubkey::new_rand(), 0, 100);
let stake_account1 =
stake_state::create_account(&sk1, &pk1, &vote_account1, &genesis_config.rent, 100);
let sk2 = Pubkey::new_rand();
let pk2 = Pubkey::new_rand();
let mut vote_account2 = vote_state::create_account(&pk2, &Pubkey::new_rand(), 0, 50);
let stake_account2 =
stake_state::create_account(&sk2, &pk2, &vote_account2, &genesis_config.rent, 50);
let sk3 = Pubkey::new_rand();
let pk3 = Pubkey::new_rand();
let mut vote_account3 = vote_state::create_account(&pk3, &Pubkey::new_rand(), 0, 1);
let stake_account3 = stake_state::create_account(
&sk3,
&pk3,
&vote_account3,
&genesis_config.rent,
rooted_stake_amount,
);
let sk4 = Pubkey::new_rand();
let pk4 = Pubkey::new_rand();
let mut vote_account4 = vote_state::create_account(&pk4, &Pubkey::new_rand(), 0, 1);
let stake_account4 = stake_state::create_account(
&sk4,
&pk4,
&vote_account4,
&genesis_config.rent,
rooted_stake_amount,
);
genesis_config.accounts.extend(vec![
(pk1, vote_account1.clone()),
(sk1, stake_account1),
(pk2, vote_account2.clone()),
(sk2, stake_account2),
(pk3, vote_account3.clone()),
(sk3, stake_account3),
(pk4, vote_account4.clone()),
(sk4, stake_account4),
]);
// Create bank
let bank = Arc::new(Bank::new(&genesis_config));
let mut vote_state1 = VoteState::from(&vote_account1).unwrap();
vote_state1.process_slot_vote_unchecked(3);
vote_state1.process_slot_vote_unchecked(5);
let versioned = VoteStateVersions::Current(Box::new(vote_state1));
VoteState::to(&versioned, &mut vote_account1).unwrap();
bank.store_account(&pk1, &vote_account1);
let mut vote_state2 = VoteState::from(&vote_account2).unwrap();
vote_state2.process_slot_vote_unchecked(9);
vote_state2.process_slot_vote_unchecked(10);
let versioned = VoteStateVersions::Current(Box::new(vote_state2));
VoteState::to(&versioned, &mut vote_account2).unwrap();
bank.store_account(&pk2, &vote_account2);
let mut vote_state3 = VoteState::from(&vote_account3).unwrap();
vote_state3.root_slot = Some(1);
let versioned = VoteStateVersions::Current(Box::new(vote_state3));
VoteState::to(&versioned, &mut vote_account3).unwrap();
bank.store_account(&pk3, &vote_account3);
let mut vote_state4 = VoteState::from(&vote_account4).unwrap();
vote_state4.root_slot = Some(2);
let versioned = VoteStateVersions::Current(Box::new(vote_state4));
VoteState::to(&versioned, &mut vote_account4).unwrap();
bank.store_account(&pk4, &vote_account4);
let (commitment, rooted_stake) =
AggregateCommitmentService::aggregate_commitment(&ancestors, &bank);
for a in ancestors {
if a <= 3 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(2, 150);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if a <= 5 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, 100);
expected.increase_confirmation_stake(2, 50);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if a <= 9 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(2, 50);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if a <= 10 {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(1, 50);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else {
assert!(commitment.get(&a).is_none());
}
}
assert_eq!(rooted_stake.len(), 2);
assert_eq!(get_largest_confirmed_root(rooted_stake, 100), 1)
}
}

View File

@@ -1,4 +1,5 @@
use crate::{
commitment::VOTE_THRESHOLD_SIZE,
progress_map::{LockoutIntervals, ProgressMap},
pubkey_references::PubkeyReferences,
};
@@ -9,19 +10,55 @@ use solana_sdk::{
account::Account,
clock::{Slot, UnixTimestamp},
hash::Hash,
instruction::Instruction,
pubkey::Pubkey,
};
use solana_vote_program::vote_state::{
BlockTimestamp, Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY, TIMESTAMP_SLOT_INTERVAL,
use solana_vote_program::{
vote_instruction,
vote_state::{
BlockTimestamp, Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY, TIMESTAMP_SLOT_INTERVAL,
},
};
use std::{
collections::{BTreeMap, HashMap, HashSet},
ops::Bound::{Included, Unbounded},
sync::Arc,
sync::{Arc, RwLock},
};
#[derive(PartialEq, Clone, Debug)]
pub enum SwitchForkDecision {
SwitchProof(Hash),
NoSwitch,
FailedSwitchThreshold,
}
impl SwitchForkDecision {
pub fn to_vote_instruction(
&self,
vote: Vote,
vote_account_pubkey: &Pubkey,
authorized_voter_pubkey: &Pubkey,
) -> Option<Instruction> {
match self {
SwitchForkDecision::FailedSwitchThreshold => None,
SwitchForkDecision::NoSwitch => Some(vote_instruction::vote(
vote_account_pubkey,
authorized_voter_pubkey,
vote,
)),
SwitchForkDecision::SwitchProof(switch_proof_hash) => {
Some(vote_instruction::vote_switch(
vote_account_pubkey,
authorized_voter_pubkey,
vote,
*switch_proof_hash,
))
}
}
}
}
pub const VOTE_THRESHOLD_DEPTH: usize = 8;
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
pub const SWITCH_FORK_THRESHOLD: f64 = 0.38;
#[derive(Default, Debug, Clone)]
@@ -42,6 +79,14 @@ impl StakeLockout {
}
}
pub(crate) struct ComputedBankState {
pub stake_lockouts: HashMap<Slot, StakeLockout>,
pub total_staked: u64,
pub bank_weight: u128,
pub lockout_intervals: LockoutIntervals,
pub pubkey_votes: Vec<(Pubkey, Slot)>,
}
pub struct Tower {
node_pubkey: Pubkey,
threshold_depth: usize,
@@ -65,10 +110,14 @@ impl Default for Tower {
}
impl Tower {
pub fn new(node_pubkey: &Pubkey, vote_account_pubkey: &Pubkey, bank_forks: &BankForks) -> Self {
pub fn new(
node_pubkey: &Pubkey,
vote_account_pubkey: &Pubkey,
root: Slot,
heaviest_bank: &Bank,
) -> Self {
let mut tower = Self::new_with_key(node_pubkey);
tower.initialize_lockouts_from_bank_forks(&bank_forks, vote_account_pubkey);
tower.initialize_lockouts_from_bank_forks(vote_account_pubkey, root, heaviest_bank);
tower
}
@@ -89,27 +138,28 @@ impl Tower {
}
}
pub fn collect_vote_lockouts<F>(
&self,
pub(crate) fn collect_vote_lockouts<F>(
node_pubkey: &Pubkey,
bank_slot: u64,
vote_accounts: F,
ancestors: &HashMap<Slot, HashSet<u64>>,
all_pubkeys: &mut PubkeyReferences,
) -> (HashMap<Slot, StakeLockout>, u64, u128, LockoutIntervals)
) -> ComputedBankState
where
F: Iterator<Item = (Pubkey, (u64, Account))>,
{
let mut stake_lockouts = HashMap::new();
let mut total_stake = 0;
let mut total_weight = 0;
let mut total_staked = 0;
let mut bank_weight = 0;
// Tree of intervals of lockouts of the form [slot, slot + slot.lockout],
// keyed by end of the range
let mut lockout_intervals = BTreeMap::new();
let mut pubkey_votes = vec![];
for (key, (lamports, account)) in vote_accounts {
if lamports == 0 {
continue;
}
trace!("{} {} with stake {}", self.node_pubkey, key, lamports);
trace!("{} {} with stake {}", node_pubkey, key, lamports);
let vote_state = VoteState::from(&account);
if vote_state.is_none() {
datapoint_warn!(
@@ -128,11 +178,11 @@ impl Tower {
let key = all_pubkeys.get_or_insert(&key);
lockout_intervals
.entry(vote.expiration_slot())
.or_insert_with(|| vec![])
.or_insert_with(Vec::new)
.push((vote.slot, key));
}
if key == self.node_pubkey || vote_state.node_pubkey == self.node_pubkey {
if key == *node_pubkey || vote_state.node_pubkey == *node_pubkey {
debug!("vote state {:?}", vote_state);
debug!(
"observed slot {}",
@@ -151,10 +201,15 @@ impl Tower {
}
let start_root = vote_state.root_slot;
// Add the latest vote to update the `heaviest_subtree_fork_choice`
if let Some(latest_vote) = vote_state.votes.back() {
pubkey_votes.push((key, latest_vote.slot));
}
vote_state.process_slot_vote_unchecked(bank_slot);
for vote in &vote_state.votes {
total_weight += vote.lockout() as u128 * lamports as u128;
bank_weight += vote.lockout() as u128 * lamports as u128;
Self::update_ancestor_lockouts(&mut stake_lockouts, &vote, ancestors);
}
@@ -165,7 +220,7 @@ impl Tower {
slot: root,
};
trace!("ROOT: {}", vote.slot);
total_weight += vote.lockout() as u128 * lamports as u128;
bank_weight += vote.lockout() as u128 * lamports as u128;
Self::update_ancestor_lockouts(&mut stake_lockouts, &vote, ancestors);
}
}
@@ -174,7 +229,7 @@ impl Tower {
confirmation_count: MAX_LOCKOUT_HISTORY as u32,
slot: root,
};
total_weight += vote.lockout() as u128 * lamports as u128;
bank_weight += vote.lockout() as u128 * lamports as u128;
Self::update_ancestor_lockouts(&mut stake_lockouts, &vote, ancestors);
}
@@ -195,9 +250,16 @@ impl Tower {
// Update all the parents of this last vote with the stake of this vote account
Self::update_ancestor_stakes(&mut stake_lockouts, vote.slot, lamports, ancestors);
}
total_stake += lamports;
total_staked += lamports;
}
ComputedBankState {
stake_lockouts,
total_staked,
bank_weight,
lockout_intervals,
pubkey_votes,
}
(stake_lockouts, total_stake, total_weight, lockout_intervals)
}
pub fn is_slot_confirmed(
@@ -345,7 +407,7 @@ impl Tower {
progress: &ProgressMap,
total_stake: u64,
epoch_vote_accounts: &HashMap<Pubkey, (u64, Account)>,
) -> bool {
) -> SwitchForkDecision {
self.last_vote()
.slots
.last()
@@ -355,14 +417,18 @@ impl Tower {
if switch_slot == *last_vote || switch_slot_ancestors.contains(last_vote) {
// If the `switch_slot is a descendant of the last vote,
// no switching proof is neceessary
return true;
// no switching proof is necessary
return SwitchForkDecision::NoSwitch;
}
// Should never consider switching to an ancestor
// of your last vote
assert!(!last_vote_ancestors.contains(&switch_slot));
// By this point, we know the `switch_slot` is on a different fork
// (is neither an ancestor nor descendant of `last_vote`), so a
// switching proof is necessary
let switch_proof = Hash::default();
let mut locked_out_stake = 0;
let mut locked_out_vote_accounts = HashSet::new();
for (candidate_slot, descendants) in descendants.iter() {
@@ -423,9 +489,14 @@ impl Tower {
}
}
}
(locked_out_stake as f64 / total_stake as f64) > SWITCH_FORK_THRESHOLD
if (locked_out_stake as f64 / total_stake as f64) > SWITCH_FORK_THRESHOLD {
SwitchForkDecision::SwitchProof(switch_proof)
} else {
SwitchForkDecision::FailedSwitchThreshold
}
})
.unwrap_or(true)
.unwrap_or(SwitchForkDecision::NoSwitch)
}
pub fn check_vote_stake_threshold(
@@ -463,7 +534,7 @@ impl Tower {
}
/// Update lockouts for all the ancestors
fn update_ancestor_lockouts(
pub(crate) fn update_ancestor_lockouts(
stake_lockouts: &mut HashMap<Slot, StakeLockout>,
vote: &Lockout,
ancestors: &HashMap<Slot, HashSet<Slot>>,
@@ -483,6 +554,28 @@ impl Tower {
}
}
pub(crate) fn find_heaviest_bank(
bank_forks: &RwLock<BankForks>,
node_pubkey: &Pubkey,
) -> Option<Arc<Bank>> {
let ancestors = bank_forks.read().unwrap().ancestors();
let mut bank_weights: Vec<_> = bank_forks
.read()
.unwrap()
.frozen_banks()
.values()
.map(|b| {
(
Self::bank_weight(node_pubkey, b, &ancestors),
b.parents().len(),
b.clone(),
)
})
.collect();
bank_weights.sort_by_key(|b| (b.0, b.1));
bank_weights.pop().map(|b| b.2)
}
/// Update stake for all the ancestors.
/// Note, stake is the same for all the ancestor.
fn update_ancestor_stakes(
@@ -491,9 +584,8 @@ impl Tower {
lamports: u64,
ancestors: &HashMap<Slot, HashSet<Slot>>,
) {
// If there's no ancestors, that means this slot must be from before the current root,
// in which case the lockouts won't be calculated in bank_weight anyways, so ignore
// this slot
// If there's no ancestors, that means this slot must be from
// before the current root, so ignore this slot
let vote_slot_ancestors = ancestors.get(&slot);
if vote_slot_ancestors.is_none() {
return;
@@ -506,8 +598,13 @@ impl Tower {
}
}
fn bank_weight(&self, bank: &Bank, ancestors: &HashMap<Slot, HashSet<Slot>>) -> u128 {
let (_, _, bank_weight, _) = self.collect_vote_lockouts(
fn bank_weight(
node_pubkey: &Pubkey,
bank: &Bank,
ancestors: &HashMap<Slot, HashSet<Slot>>,
) -> u128 {
let ComputedBankState { bank_weight, .. } = Self::collect_vote_lockouts(
node_pubkey,
bank.slot(),
bank.vote_accounts().into_iter(),
ancestors,
@@ -516,47 +613,28 @@ impl Tower {
bank_weight
}
fn find_heaviest_bank(&self, bank_forks: &BankForks) -> Option<Arc<Bank>> {
let ancestors = bank_forks.ancestors();
let mut bank_weights: Vec<_> = bank_forks
.frozen_banks()
.values()
.map(|b| {
(
self.bank_weight(b, &ancestors),
b.parents().len(),
b.clone(),
)
})
.collect();
bank_weights.sort_by_key(|b| (b.0, b.1));
bank_weights.pop().map(|b| b.2)
}
fn initialize_lockouts_from_bank_forks(
&mut self,
bank_forks: &BankForks,
vote_account_pubkey: &Pubkey,
root: Slot,
heaviest_bank: &Bank,
) {
if let Some(bank) = self.find_heaviest_bank(bank_forks) {
let root = bank_forks.root();
if let Some((_stake, vote_account)) = bank.vote_accounts().get(vote_account_pubkey) {
let mut vote_state = VoteState::deserialize(&vote_account.data)
.expect("vote_account isn't a VoteState?");
vote_state.root_slot = Some(root);
vote_state.votes.retain(|v| v.slot > root);
trace!(
"{} lockouts initialized to {:?}",
self.node_pubkey,
vote_state
);
assert_eq!(
vote_state.node_pubkey, self.node_pubkey,
"vote account's node_pubkey doesn't match",
);
self.lockouts = vote_state;
}
if let Some((_stake, vote_account)) = heaviest_bank.vote_accounts().get(vote_account_pubkey)
{
let mut vote_state = VoteState::deserialize(&vote_account.data)
.expect("vote_account isn't a VoteState?");
vote_state.root_slot = Some(root);
vote_state.votes.retain(|v| v.slot > root);
trace!(
"{} lockouts initialized to {:?}",
self.node_pubkey,
vote_state
);
assert_eq!(
vote_state.node_pubkey, self.node_pubkey,
"vote account's node_pubkey doesn't match",
);
self.lockouts = vote_state;
}
}
@@ -580,8 +658,11 @@ impl Tower {
pub mod test {
use super::*;
use crate::{
bank_weight_fork_choice::BankWeightForkChoice,
cluster_info_vote_listener::VoteTracker,
cluster_slots::ClusterSlots,
fork_choice::SelectVoteAndResetForkResult,
heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice,
progress_map::ForkProgress,
replay_stage::{HeaviestForkFailures, ReplayStage},
};
@@ -599,7 +680,7 @@ pub mod test {
signature::{Keypair, Signer},
};
use solana_vote_program::{
vote_state::{Vote, VoteStateVersions},
vote_state::{Vote, VoteStateVersions, MAX_LOCKOUT_HISTORY},
vote_transaction,
};
use std::{
@@ -616,18 +697,26 @@ pub mod test {
pub vote_pubkeys: Vec<Pubkey>,
pub bank_forks: RwLock<BankForks>,
pub progress: ProgressMap,
pub heaviest_subtree_fork_choice: HeaviestSubtreeForkChoice,
}
impl VoteSimulator {
pub(crate) fn new(num_keypairs: usize) -> Self {
let (validator_keypairs, node_pubkeys, vote_pubkeys, bank_forks, progress) =
Self::init_state(num_keypairs);
let (
validator_keypairs,
node_pubkeys,
vote_pubkeys,
bank_forks,
progress,
heaviest_subtree_fork_choice,
) = Self::init_state(num_keypairs);
Self {
validator_keypairs,
node_pubkeys,
vote_pubkeys,
bank_forks: RwLock::new(bank_forks),
progress,
heaviest_subtree_fork_choice,
}
}
pub(crate) fn fill_bank_forks(
@@ -670,6 +759,8 @@ pub mod test {
}
}
new_bank.freeze();
self.heaviest_subtree_fork_choice
.add_new_leaf_slot(new_bank.slot(), Some(new_bank.parent_slot()));
self.bank_forks.write().unwrap().insert(new_bank);
walk.forward();
}
@@ -704,6 +795,8 @@ pub mod test {
&ClusterSlots::default(),
&self.bank_forks,
&mut PubkeyReferences::default(),
&mut self.heaviest_subtree_fork_choice,
&mut BankWeightForkChoice::default(),
);
let vote_bank = self
@@ -716,8 +809,11 @@ pub mod test {
// Try to vote on the given slot
let descendants = self.bank_forks.read().unwrap().descendants();
let (_, _, failure_reasons) = ReplayStage::select_vote_and_reset_forks(
&Some(vote_bank.clone()),
let SelectVoteAndResetForkResult {
heaviest_fork_failures,
..
} = ReplayStage::select_vote_and_reset_forks(
&vote_bank,
&None,
&ancestors,
&descendants,
@@ -727,8 +823,8 @@ pub mod test {
// Make sure this slot isn't locked out or failing threshold
info!("Checking vote: {}", vote_bank.slot());
if !failure_reasons.is_empty() {
return failure_reasons;
if !heaviest_fork_failures.is_empty() {
return heaviest_fork_failures;
}
let vote = tower.new_vote_from_bank(&vote_bank, &my_vote_pubkey).0;
if let Some(new_root) = tower.record_bank_vote(vote) {
@@ -746,6 +842,7 @@ pub mod test {
&None,
&mut PubkeyReferences::default(),
None,
&mut self.heaviest_subtree_fork_choice,
)
}
@@ -831,6 +928,7 @@ pub mod test {
Vec<Pubkey>,
BankForks,
ProgressMap,
HeaviestSubtreeForkChoice,
) {
let keypairs: HashMap<_, _> = std::iter::repeat_with(|| {
let node_keypair = Keypair::new();
@@ -853,8 +951,16 @@ pub mod test {
.map(|keys| keys.vote_keypair.pubkey())
.collect();
let (bank_forks, progress) = initialize_state(&keypairs, 10_000);
(keypairs, node_pubkeys, vote_pubkeys, bank_forks, progress)
let (bank_forks, progress, heaviest_subtree_fork_choice) =
initialize_state(&keypairs, 10_000);
(
keypairs,
node_pubkeys,
vote_pubkeys,
bank_forks,
progress,
heaviest_subtree_fork_choice,
)
}
}
@@ -862,7 +968,7 @@ pub mod test {
pub(crate) fn initialize_state(
validator_keypairs_map: &HashMap<Pubkey, ValidatorVoteKeypairs>,
stake: u64,
) -> (BankForks, ProgressMap) {
) -> (BankForks, ProgressMap, HeaviestSubtreeForkChoice) {
let validator_keypairs: Vec<_> = validator_keypairs_map.values().collect();
let GenesisConfigInfo {
genesis_config,
@@ -882,7 +988,10 @@ pub mod test {
0,
ForkProgress::new(bank0.last_blockhash(), None, None, 0, 0),
);
(BankForks::new(0, bank0), progress)
let bank_forks = BankForks::new(bank0);
let heaviest_subtree_fork_choice =
HeaviestSubtreeForkChoice::new_from_bank_forks(&bank_forks);
(bank_forks, progress, heaviest_subtree_fork_choice)
}
fn gen_stakes(stake_votes: &[(u64, &[u64])]) -> Vec<(Pubkey, (u64, Account))> {
@@ -905,6 +1014,34 @@ pub mod test {
stakes
}
#[test]
fn test_to_vote_instruction() {
let vote = Vote::default();
let mut decision = SwitchForkDecision::FailedSwitchThreshold;
assert!(decision
.to_vote_instruction(vote.clone(), &Pubkey::default(), &Pubkey::default())
.is_none());
decision = SwitchForkDecision::NoSwitch;
assert_eq!(
decision.to_vote_instruction(vote.clone(), &Pubkey::default(), &Pubkey::default()),
Some(vote_instruction::vote(
&Pubkey::default(),
&Pubkey::default(),
vote.clone(),
))
);
decision = SwitchForkDecision::SwitchProof(Hash::default());
assert_eq!(
decision.to_vote_instruction(vote.clone(), &Pubkey::default(), &Pubkey::default()),
Some(vote_instruction::vote_switch(
&Pubkey::default(),
&Pubkey::default(),
vote,
Hash::default()
))
);
}
#[test]
fn test_simple_votes() {
// Init state
@@ -975,85 +1112,106 @@ pub mod test {
tower.record_vote(47, Hash::default());
// Trying to switch to a descendant of last vote should always work
assert!(tower.check_switch_threshold(
48,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
48,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::NoSwitch
);
// Trying to switch to another fork at 110 should fail
assert!(!tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::FailedSwitchThreshold
);
// Adding another validator lockout on a descendant of last vote should
// not count toward the switch threshold
vote_simulator.simulate_lockout_interval(50, (49, 100), &other_vote_account);
assert!(!tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::FailedSwitchThreshold
);
// Adding another validator lockout on an ancestor of last vote should
// not count toward the switch threshold
vote_simulator.simulate_lockout_interval(50, (45, 100), &other_vote_account);
assert!(!tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::FailedSwitchThreshold
);
// Adding another validator lockout on a different fork, but the lockout
// doesn't cover the last vote, should not satisfy the switch threshold
vote_simulator.simulate_lockout_interval(14, (12, 46), &other_vote_account);
assert!(!tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::FailedSwitchThreshold
);
// Adding another validator lockout on a different fork, and the lockout
// covers the last vote, should satisfy the switch threshold
vote_simulator.simulate_lockout_interval(14, (12, 47), &other_vote_account);
assert!(tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
110,
&ancestors,
&descendants,
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::SwitchProof(Hash::default())
);
// If we set a root, then any lockout intervals below the root shouldn't
// count toward the switch threshold. This means the other validator's
// vote lockout no longer counts
vote_simulator.set_root(43);
assert!(!tower.check_switch_threshold(
110,
&vote_simulator.bank_forks.read().unwrap().ancestors(),
&vote_simulator.bank_forks.read().unwrap().descendants(),
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
));
assert_eq!(
tower.check_switch_threshold(
110,
&vote_simulator.bank_forks.read().unwrap().ancestors(),
&vote_simulator.bank_forks.read().unwrap().descendants(),
&vote_simulator.progress,
total_stake,
bank0.epoch_vote_accounts(0).unwrap(),
),
SwitchForkDecision::FailedSwitchThreshold
);
}
#[test]
@@ -1193,20 +1351,32 @@ pub mod test {
#[test]
fn test_collect_vote_lockouts_sums() {
//two accounts voting for slot 0 with 1 token staked
let accounts = gen_stakes(&[(1, &[0]), (1, &[0])]);
let tower = Tower::new_for_tests(0, 0.67);
let mut accounts = gen_stakes(&[(1, &[0]), (1, &[0])]);
accounts.sort_by_key(|(pk, _)| *pk);
let account_latest_votes: Vec<(Pubkey, Slot)> =
accounts.iter().map(|(pubkey, _)| (*pubkey, 0)).collect();
let ancestors = vec![(1, vec![0].into_iter().collect()), (0, HashSet::new())]
.into_iter()
.collect();
let (staked_lockouts, total_staked, bank_weight, _) = tower.collect_vote_lockouts(
let ComputedBankState {
stake_lockouts,
total_staked,
bank_weight,
mut pubkey_votes,
..
} = Tower::collect_vote_lockouts(
&Pubkey::default(),
1,
accounts.into_iter(),
&ancestors,
&mut PubkeyReferences::default(),
);
assert_eq!(staked_lockouts[&0].stake, 2);
assert_eq!(staked_lockouts[&0].lockout, 2 + 2 + 4 + 4);
assert_eq!(stake_lockouts[&0].stake, 2);
assert_eq!(stake_lockouts[&0].lockout, 2 + 2 + 4 + 4);
assert_eq!(total_staked, 2);
pubkey_votes.sort();
assert_eq!(pubkey_votes, account_latest_votes);
// Each acccount has 1 vote in it. After simulating a vote in collect_vote_lockouts,
// the account will have 2 votes, with lockout 2 + 4 = 6. So expected weight for
@@ -1218,7 +1388,12 @@ pub mod test {
fn test_collect_vote_lockouts_root() {
let votes: Vec<u64> = (0..MAX_LOCKOUT_HISTORY as u64).collect();
//two accounts voting for slots 0..MAX_LOCKOUT_HISTORY with 1 token staked
let accounts = gen_stakes(&[(1, &votes), (1, &votes)]);
let mut accounts = gen_stakes(&[(1, &votes), (1, &votes)]);
accounts.sort_by_key(|(pk, _)| *pk);
let account_latest_votes: Vec<(Pubkey, Slot)> = accounts
.iter()
.map(|(pubkey, _)| (*pubkey, (MAX_LOCKOUT_HISTORY - 1) as Slot))
.collect();
let mut tower = Tower::new_for_tests(0, 0.67);
let mut ancestors = HashMap::new();
for i in 0..(MAX_LOCKOUT_HISTORY + 1) {
@@ -1239,18 +1414,27 @@ pub mod test {
+ root_weight;
let expected_bank_weight = 2 * vote_account_expected_weight;
assert_eq!(tower.lockouts.root_slot, Some(0));
let (staked_lockouts, _total_staked, bank_weight, _) = tower.collect_vote_lockouts(
let ComputedBankState {
stake_lockouts,
bank_weight,
mut pubkey_votes,
..
} = Tower::collect_vote_lockouts(
&Pubkey::default(),
MAX_LOCKOUT_HISTORY as u64,
accounts.into_iter(),
&ancestors,
&mut PubkeyReferences::default(),
);
for i in 0..MAX_LOCKOUT_HISTORY {
assert_eq!(staked_lockouts[&(i as u64)].stake, 2);
assert_eq!(stake_lockouts[&(i as u64)].stake, 2);
}
// should be the sum of all the weights for root
assert!(staked_lockouts[&0].lockout > (2 * (1 << MAX_LOCKOUT_HISTORY)));
assert!(stake_lockouts[&0].lockout > (2 * (1 << MAX_LOCKOUT_HISTORY)));
assert_eq!(bank_weight, expected_bank_weight);
pubkey_votes.sort();
assert_eq!(pubkey_votes, account_latest_votes);
}
#[test]
@@ -1283,7 +1467,7 @@ pub mod test {
);
tower.record_vote(i, Hash::default());
}
assert!(!tower.check_vote_stake_threshold(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2));
assert!(!tower.check_vote_stake_threshold(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2,));
}
#[test]
@@ -1511,48 +1695,7 @@ pub mod test {
tower.record_vote(0, Hash::default());
tower.record_vote(1, Hash::default());
tower.record_vote(2, Hash::default());
assert!(tower.check_vote_stake_threshold(6, &stakes, 2));
}
#[test]
fn test_lockout_is_updated_for_entire_branch() {
let mut stake_lockouts = HashMap::new();
let vote = Lockout {
slot: 2,
confirmation_count: 1,
};
let set: HashSet<u64> = vec![0u64, 1u64].into_iter().collect();
let mut ancestors = HashMap::new();
ancestors.insert(2, set);
let set: HashSet<u64> = vec![0u64].into_iter().collect();
ancestors.insert(1, set);
Tower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors);
assert_eq!(stake_lockouts[&0].lockout, 2);
assert_eq!(stake_lockouts[&1].lockout, 2);
assert_eq!(stake_lockouts[&2].lockout, 2);
}
#[test]
fn test_lockout_is_updated_for_slot_or_lower() {
let mut stake_lockouts = HashMap::new();
let set: HashSet<u64> = vec![0u64, 1u64].into_iter().collect();
let mut ancestors = HashMap::new();
ancestors.insert(2, set);
let set: HashSet<u64> = vec![0u64].into_iter().collect();
ancestors.insert(1, set);
let vote = Lockout {
slot: 2,
confirmation_count: 1,
};
Tower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors);
let vote = Lockout {
slot: 1,
confirmation_count: 2,
};
Tower::update_ancestor_lockouts(&mut stake_lockouts, &vote, &ancestors);
assert_eq!(stake_lockouts[&0].lockout, 2 + 4);
assert_eq!(stake_lockouts[&1].lockout, 2 + 4);
assert_eq!(stake_lockouts[&2].lockout, 2);
assert!(tower.check_vote_stake_threshold(6, &stakes, 2,));
}
#[test]
@@ -1631,7 +1774,7 @@ pub mod test {
let total_stake = 4;
let threshold_size = 0.67;
let threshold_stake = (f64::ceil(total_stake as f64 * threshold_size)) as u64;
let tower_votes: Vec<u64> = (0..VOTE_THRESHOLD_DEPTH as u64).collect();
let tower_votes: Vec<Slot> = (0..VOTE_THRESHOLD_DEPTH as u64).collect();
let accounts = gen_stakes(&[
(threshold_stake, &[(VOTE_THRESHOLD_DEPTH - 2) as u64]),
(total_stake - threshold_stake, &tower_votes[..]),
@@ -1648,29 +1791,35 @@ pub mod test {
for vote in &tower_votes {
tower.record_vote(*vote, Hash::default());
}
let (staked_lockouts, total_staked, _, _) = tower.collect_vote_lockouts(
let ComputedBankState {
stake_lockouts,
total_staked,
..
} = Tower::collect_vote_lockouts(
&Pubkey::default(),
vote_to_evaluate,
accounts.clone().into_iter(),
&ancestors,
&mut PubkeyReferences::default(),
);
assert!(tower.check_vote_stake_threshold(vote_to_evaluate, &staked_lockouts, total_staked));
assert!(tower.check_vote_stake_threshold(vote_to_evaluate, &stake_lockouts, total_staked,));
// CASE 2: Now we want to evaluate a vote for slot VOTE_THRESHOLD_DEPTH + 1. This slot
// will expire the vote in one of the vote accounts, so we should have insufficient
// stake to pass the threshold
let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64 + 1;
let (staked_lockouts, total_staked, _, _) = tower.collect_vote_lockouts(
let ComputedBankState {
stake_lockouts,
total_staked,
..
} = Tower::collect_vote_lockouts(
&Pubkey::default(),
vote_to_evaluate,
accounts.into_iter(),
&ancestors,
&mut PubkeyReferences::default(),
);
assert!(!tower.check_vote_stake_threshold(
vote_to_evaluate,
&staked_lockouts,
total_staked
));
assert!(!tower.check_vote_stake_threshold(vote_to_evaluate, &stake_lockouts, total_staked,));
}
fn vote_and_check_recent(num_votes: usize) {

View File

@@ -36,6 +36,7 @@ use std::collections::HashMap;
pub struct Crds {
/// Stores the map of labels and values
pub table: IndexMap<CrdsValueLabel, VersionedCrdsValue>,
pub num_inserts: usize,
}
#[derive(PartialEq, Debug)]
@@ -84,6 +85,7 @@ impl Default for Crds {
fn default() -> Self {
Crds {
table: IndexMap::new(),
num_inserts: 0,
}
}
}
@@ -125,6 +127,7 @@ impl Crds {
.unwrap_or(true);
if do_insert {
let old = self.table.insert(label, new_value);
self.num_inserts += 1;
Ok(old)
} else {
trace!("INSERT FAILED data: {} new.wallclock: {}", label, wallclock,);

View File

@@ -76,17 +76,10 @@ impl CrdsGossip {
stakes: &HashMap<Pubkey, u64>,
) -> HashMap<Pubkey, HashSet<Pubkey>> {
let id = &self.id;
let crds = &self.crds;
let push = &mut self.push;
let versioned = labels
.into_iter()
.filter_map(|label| crds.lookup_versioned(&label));
let mut prune_map: HashMap<Pubkey, HashSet<_>> = HashMap::new();
for val in versioned {
let origin = val.value.pubkey();
let hash = val.value_hash;
let peers = push.prune_received_cache(id, &origin, hash, stakes);
for origin in labels.iter().map(|k| k.pubkey()) {
let peers = push.prune_received_cache(id, &origin, stakes);
for from in peers {
prune_map.entry(from).or_default().insert(origin);
}
@@ -113,7 +106,7 @@ impl CrdsGossip {
return Err(CrdsGossipError::PruneMessageTimeout);
}
if self.id == *destination {
self.push.process_prune_msg(peer, origin);
self.push.process_prune_msg(&self.id, peer, origin);
Ok(())
} else {
Err(CrdsGossipError::BadPruneDestination)
@@ -166,9 +159,8 @@ impl CrdsGossip {
pub fn generate_pull_responses(
&self,
filters: &[(CrdsValue, CrdsFilter)],
now: Option<u64>,
) -> Vec<Vec<CrdsValue>> {
self.pull.generate_pull_responses(&self.crds, filters, now)
self.pull.generate_pull_responses(&self.crds, filters)
}
pub fn filter_pull_responses(
@@ -191,14 +183,15 @@ impl CrdsGossip {
now: u64,
process_pull_stats: &mut ProcessPullStats,
) {
self.pull.process_pull_responses(
let success = self.pull.process_pull_responses(
&mut self.crds,
from,
responses,
responses_expired_timeout,
now,
process_pull_stats,
)
);
self.push.push_pull_responses(success, now);
}
pub fn make_timeouts_test(&self) -> HashMap<Pubkey, u64> {

View File

@@ -2,7 +2,6 @@
pub enum CrdsGossipError {
NoPeers,
PushMessageTimeout,
PushMessageAlreadyReceived,
PushMessageOldVersion,
BadPruneDestination,
PruneMessageTimeout,

View File

@@ -100,9 +100,6 @@ impl CrdsFilter {
accum
}
pub fn test_mask(&self, item: &Hash) -> bool {
if self.mask_bits == 0 {
return true;
}
// only consider the highest mask_bits bits from the hash and set the rest to 1.
let ones = (!0u64).checked_shr(self.mask_bits).unwrap_or(!0u64);
let bits = Self::hash_as_u64(item) | ones;
@@ -137,6 +134,7 @@ pub struct CrdsGossipPull {
purged_values: VecDeque<(Hash, u64)>,
pub crds_timeout: u64,
pub msg_timeout: u64,
pub num_pulls: usize,
}
impl Default for CrdsGossipPull {
@@ -146,6 +144,7 @@ impl Default for CrdsGossipPull {
pull_request_time: HashMap::new(),
crds_timeout: CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS,
msg_timeout: CRDS_GOSSIP_PULL_MSG_TIMEOUT_MS,
num_pulls: 0,
}
}
}
@@ -238,9 +237,8 @@ impl CrdsGossipPull {
&self,
crds: &Crds,
requests: &[(CrdsValue, CrdsFilter)],
now: Option<u64>,
) -> Vec<Vec<CrdsValue>> {
Self::filter_crds_values(crds, requests, now)
self.filter_crds_values(crds, requests)
}
// Checks if responses should be inserted and
@@ -317,18 +315,24 @@ impl CrdsGossipPull {
responses_expired_timeout: Vec<VersionedCrdsValue>,
now: u64,
stats: &mut ProcessPullStats,
) {
) -> Vec<(CrdsValueLabel, Hash, u64)> {
let mut success = vec![];
let mut owners = HashSet::new();
for r in responses_expired_timeout {
stats.failed_insert += crds.insert_versioned(r).is_err() as usize;
}
for r in responses {
let owner = r.value.label().pubkey();
let label = r.value.label();
let wc = r.value.wallclock();
let hash = r.value_hash;
let old = crds.insert_versioned(r);
if old.is_err() {
stats.failed_insert += 1;
} else {
stats.success += 1;
self.num_pulls += 1;
success.push((label, hash, wc));
}
old.ok().map(|opt| {
owners.insert(owner);
@@ -342,6 +346,7 @@ impl CrdsGossipPull {
for owner in owners {
crds.update_record_timestamp(&owner, now);
}
success
}
// build a set of filters of the current crds table
// num_filters - used to increase the likelyhood of a value in crds being added to some filter
@@ -363,17 +368,12 @@ impl CrdsGossipPull {
}
/// filter values that fail the bloom filter up to max_bytes
fn filter_crds_values(
&self,
crds: &Crds,
filters: &[(CrdsValue, CrdsFilter)],
now: Option<u64>,
) -> Vec<Vec<CrdsValue>> {
let mut ret = vec![vec![]; filters.len()];
let now = now.unwrap_or(u64::MAX);
for v in crds.table.values() {
//skip messages that are newer than now
if v.insert_timestamp > now {
continue;
}
filters.iter().enumerate().for_each(|(i, (_, filter))| {
if !filter.contains(&v.value_hash) {
ret[i].push(v.value.clone());
@@ -664,7 +664,7 @@ mod test {
let mut dest = CrdsGossipPull::default();
let (_, filters, caller) = req.unwrap();
let filters: Vec<_> = filters.into_iter().map(|f| (caller.clone(), f)).collect();
let rsp = dest.generate_pull_responses(&dest_crds, &filters, None);
let rsp = dest.generate_pull_responses(&dest_crds, &filters);
dest.process_pull_requests(&mut dest_crds, filters, 1);
assert!(rsp.iter().all(|rsp| rsp.is_empty()));
assert!(dest_crds.lookup(&caller.label()).is_some());
@@ -735,7 +735,7 @@ mod test {
);
let (_, filters, caller) = req.unwrap();
let filters: Vec<_> = filters.into_iter().map(|f| (caller.clone(), f)).collect();
let mut rsp = dest.generate_pull_responses(&dest_crds, &filters, None);
let mut rsp = dest.generate_pull_responses(&dest_crds, &filters);
dest.process_pull_requests(&mut dest_crds, filters, 0);
// if there is a false positive this is empty
// prob should be around 0.1 per iteration
@@ -777,37 +777,6 @@ mod test {
}
assert!(done);
}
#[test]
fn test_filter_crds_values() {
let mut node_crds = Crds::default();
let entry = CrdsValue::new_unsigned(CrdsData::ContactInfo(ContactInfo::new_localhost(
&Pubkey::new_rand(),
0,
)));
let caller = CrdsValue::new_unsigned(CrdsData::ContactInfo(ContactInfo::new_localhost(
&Pubkey::new_rand(),
0,
)));
let node_label = entry.label();
let node_pubkey = node_label.pubkey();
node_crds.insert(entry, 1).unwrap();
let mut filter = CrdsFilter::new_rand(1, 128);
filter.mask_bits = 0;
let requests = [(caller, filter)];
let rsp = CrdsGossipPull::filter_crds_values(&node_crds, &requests, None);
assert_eq!(rsp[0][0].pubkey(), node_pubkey);
//skip 1 since its newer than 0
let rsp = CrdsGossipPull::filter_crds_values(&node_crds, &requests, Some(0));
assert!(rsp[0].is_empty());
let rsp = CrdsGossipPull::filter_crds_values(&node_crds, &requests, Some(1));
assert_eq!(rsp[0][0].pubkey(), node_pubkey);
}
#[test]
fn test_gossip_purge() {
let mut node_crds = Crds::default();
@@ -871,15 +840,6 @@ mod test {
let h: Hash = hash(h.as_ref());
assert!(!filter.contains(&h));
}
#[test]
fn test_crds_filter_test_mask_default() {
let filter = CrdsFilter::default();
assert_eq!(filter.mask_bits, 0);
let h: Hash = Hash::default();
assert_eq!(filter.test_mask(&h), true);
}
#[test]
fn test_crds_filter_add_mask() {
let mut filter = CrdsFilter::new_rand(1000, 10);

View File

@@ -5,7 +5,7 @@
//!
//! Main differences are:
//! 1. There is no `max hop`. Messages are signed with a local wallclock. If they are outside of
//! the local nodes wallclock window they are drooped silently.
//! the local nodes wallclock window they are dropped silently.
//! 2. The prune set is stored in a Bloom filter.
use crate::{
@@ -35,6 +35,7 @@ pub const CRDS_GOSSIP_PUSH_FANOUT: usize = 6;
pub const CRDS_GOSSIP_PUSH_MSG_TIMEOUT_MS: u64 = 30000;
pub const CRDS_GOSSIP_PRUNE_MSG_TIMEOUT_MS: u64 = 500;
pub const CRDS_GOSSIP_PRUNE_STAKE_THRESHOLD_PCT: f64 = 0.15;
pub const CRDS_GOSSIP_PRUNE_MIN_INGRESS_NODES: usize = 2;
#[derive(Clone)]
pub struct CrdsGossipPush {
@@ -44,12 +45,18 @@ pub struct CrdsGossipPush {
active_set: IndexMap<Pubkey, Bloom<Pubkey>>,
/// push message queue
push_messages: HashMap<CrdsValueLabel, Hash>,
/// cache that tracks which validators a message was received from
received_cache: HashMap<Hash, (u64, HashSet<Pubkey>)>,
/// Cache that tracks which validators a message was received from
/// bool indicates it has been pruned.
/// This cache represents a lagging view of which validators
/// currently have this node in their `active_set`
received_cache: HashMap<Pubkey, HashMap<Pubkey, (bool, u64)>>,
pub num_active: usize,
pub push_fanout: usize,
pub msg_timeout: u64,
pub prune_timeout: u64,
pub num_total: usize,
pub num_old: usize,
pub num_pushes: usize,
}
impl Default for CrdsGossipPush {
@@ -64,6 +71,9 @@ impl Default for CrdsGossipPush {
push_fanout: CRDS_GOSSIP_PUSH_FANOUT,
msg_timeout: CRDS_GOSSIP_PUSH_MSG_TIMEOUT_MS,
prune_timeout: CRDS_GOSSIP_PRUNE_MSG_TIMEOUT_MS,
num_total: 0,
num_old: 0,
num_pushes: 0,
}
}
}
@@ -81,18 +91,21 @@ impl CrdsGossipPush {
&mut self,
self_pubkey: &Pubkey,
origin: &Pubkey,
hash: Hash,
stakes: &HashMap<Pubkey, u64>,
) -> Vec<Pubkey> {
let origin_stake = stakes.get(origin).unwrap_or(&0);
let self_stake = stakes.get(self_pubkey).unwrap_or(&0);
let cache = self.received_cache.get(&hash);
let cache = self.received_cache.get(origin);
if cache.is_none() {
return Vec::new();
}
let peers = cache.unwrap();
let peers = &cache.unwrap().1;
let peer_stake_total: u64 = peers.iter().map(|p| stakes.get(p).unwrap_or(&0)).sum();
let peer_stake_total: u64 = peers
.iter()
.filter(|v| !(v.1).0)
.map(|v| stakes.get(v.0).unwrap_or(&0))
.sum();
let prune_stake_threshold = Self::prune_stake_threshold(*self_stake, *origin_stake);
if peer_stake_total < prune_stake_threshold {
return Vec::new();
@@ -100,7 +113,8 @@ impl CrdsGossipPush {
let staked_peers: Vec<(Pubkey, u64)> = peers
.iter()
.filter_map(|p| stakes.get(p).map(|s| (*p, *s)))
.filter(|v| !(v.1).0)
.filter_map(|p| stakes.get(p.0).map(|s| (*p.0, *s)))
.filter(|(_, s)| *s > 0)
.collect();
@@ -117,16 +131,27 @@ impl CrdsGossipPush {
let (next_peer, next_stake) = staked_peers[next];
keep.insert(next_peer);
peer_stake_sum += next_stake;
if peer_stake_sum >= prune_stake_threshold {
if peer_stake_sum >= prune_stake_threshold
&& keep.len() >= CRDS_GOSSIP_PRUNE_MIN_INGRESS_NODES
{
break;
}
}
peers
.iter()
let pruned_peers: Vec<Pubkey> = peers
.keys()
.filter(|p| !keep.contains(p))
.cloned()
.collect()
.collect();
pruned_peers.iter().for_each(|p| {
self.received_cache
.get_mut(origin)
.unwrap()
.get_mut(p)
.unwrap()
.0 = true;
});
pruned_peers
}
/// process a push message to the network
@@ -137,6 +162,7 @@ impl CrdsGossipPush {
value: CrdsValue,
now: u64,
) -> Result<Option<VersionedCrdsValue>, CrdsGossipError> {
self.num_total += 1;
if now
> value
.wallclock()
@@ -149,21 +175,32 @@ impl CrdsGossipPush {
return Err(CrdsGossipError::PushMessageTimeout);
}
let label = value.label();
let origin = label.pubkey();
let new_value = crds.new_versioned(now, value);
let value_hash = new_value.value_hash;
if let Some((_, ref mut received_set)) = self.received_cache.get_mut(&value_hash) {
received_set.insert(from.clone());
return Err(CrdsGossipError::PushMessageAlreadyReceived);
}
let received_set = self
.received_cache
.entry(origin)
.or_insert_with(HashMap::new);
received_set.entry(*from).or_insert((false, 0)).1 = now;
let old = crds.insert_versioned(new_value);
if old.is_err() {
self.num_old += 1;
return Err(CrdsGossipError::PushMessageOldVersion);
}
let mut received_set = HashSet::new();
received_set.insert(from.clone());
self.push_messages.insert(label, value_hash);
self.received_cache.insert(value_hash, (now, received_set));
Ok(old.ok().and_then(|opt| opt))
Ok(old.unwrap())
}
/// push pull responses
pub fn push_pull_responses(&mut self, values: Vec<(CrdsValueLabel, Hash, u64)>, now: u64) {
for (label, value_hash, wc) in values {
if now > wc.checked_add(self.msg_timeout).unwrap_or_else(|| 0) {
continue;
}
self.push_messages.insert(label, value_hash);
}
}
/// New push message to broadcast to peers.
@@ -172,18 +209,10 @@ impl CrdsGossipPush {
/// The list of push messages is created such that all the randomly selected peers have not
/// pruned the source addresses.
pub fn new_push_messages(&mut self, crds: &Crds, now: u64) -> HashMap<Pubkey, Vec<CrdsValue>> {
let max = self.active_set.len();
let mut nodes: Vec<_> = (0..max).collect();
nodes.shuffle(&mut rand::thread_rng());
let peers: Vec<Pubkey> = nodes
.into_iter()
.filter_map(|n| self.active_set.get_index(n))
.take(self.push_fanout)
.map(|n| *n.0)
.collect();
let mut total_bytes: usize = 0;
let mut values = vec![];
let mut push_messages: HashMap<Pubkey, Vec<CrdsValue>> = HashMap::new();
trace!("new_push_messages {}", self.push_messages.len());
for (label, hash) in &self.push_messages {
let res = crds.lookup_versioned(label);
if res.is_none() {
@@ -203,21 +232,37 @@ impl CrdsGossipPush {
}
values.push(value.clone());
}
trace!(
"new_push_messages {} {}",
values.len(),
self.active_set.len()
);
for v in values {
for p in peers.iter() {
let filter = self.active_set.get_mut(p);
if filter.is_some() && !filter.unwrap().contains(&v.label().pubkey()) {
push_messages.entry(*p).or_default().push(v.clone());
//use a consistent index for the same origin so
//the active set learns the MST for that origin
let start = v.label().pubkey().as_ref()[0] as usize;
let max = self.push_fanout.min(self.active_set.len());
for i in start..(start + max) {
let ix = i % self.active_set.len();
if let Some((p, filter)) = self.active_set.get_index(ix) {
if !filter.contains(&v.label().pubkey()) {
trace!("new_push_messages insert {} {:?}", *p, v);
push_messages.entry(*p).or_default().push(v.clone());
self.num_pushes += 1;
}
}
self.push_messages.remove(&v.label());
}
self.push_messages.remove(&v.label());
}
push_messages
}
/// add the `from` to the peer's filter of nodes
pub fn process_prune_msg(&mut self, peer: &Pubkey, origins: &[Pubkey]) {
pub fn process_prune_msg(&mut self, self_pubkey: &Pubkey, peer: &Pubkey, origins: &[Pubkey]) {
for origin in origins {
if origin == self_pubkey {
continue;
}
if let Some(p) = self.active_set.get_mut(peer) {
p.add(origin)
}
@@ -339,15 +384,11 @@ impl CrdsGossipPush {
/// purge received push message cache
pub fn purge_old_received_cache(&mut self, min_time: u64) {
let old_msgs: Vec<Hash> = self
.received_cache
.iter()
.filter_map(|(k, (rcvd_time, _))| if *rcvd_time < min_time { Some(k) } else { None })
.cloned()
.collect();
for k in old_msgs {
self.received_cache.remove(&k);
}
self.received_cache
.iter_mut()
.for_each(|v| v.1.retain(|_, v| v.1 > min_time));
self.received_cache.retain(|_, v| !v.is_empty());
}
}
@@ -371,7 +412,6 @@ mod test {
let value = CrdsValue::new_unsigned(CrdsData::ContactInfo(ContactInfo::new_localhost(
&origin, 0,
)));
let label = value.label();
let low_staked_peers = (0..10).map(|_| Pubkey::new_rand());
let mut low_staked_set = HashSet::new();
low_staked_peers.for_each(|p| {
@@ -380,11 +420,7 @@ mod test {
stakes.insert(p, 1);
});
let versioned = crds
.lookup_versioned(&label)
.expect("versioned value should exist");
let hash = versioned.value_hash;
let pruned = push.prune_received_cache(&self_id, &origin, hash, &stakes);
let pruned = push.prune_received_cache(&self_id, &origin, &stakes);
assert!(
pruned.is_empty(),
"should not prune if min threshold has not been reached"
@@ -395,7 +431,7 @@ mod test {
stakes.insert(high_staked_peer, high_stake);
let _ = push.process_push_message(&mut crds, &high_staked_peer, value, 0);
let pruned = push.prune_received_cache(&self_id, &origin, hash, &stakes);
let pruned = push.prune_received_cache(&self_id, &origin, &stakes);
assert!(
pruned.len() < low_staked_set.len() + 1,
"should not prune all peers"
@@ -409,7 +445,7 @@ mod test {
}
#[test]
fn test_process_push() {
fn test_process_push_one() {
let mut crds = Crds::default();
let mut push = CrdsGossipPush::default();
let value = CrdsValue::new_unsigned(CrdsData::ContactInfo(ContactInfo::new_localhost(
@@ -425,9 +461,9 @@ mod test {
assert_eq!(crds.lookup(&label), Some(&value));
// push it again
assert_eq!(
assert_matches!(
push.process_push_message(&mut crds, &Pubkey::default(), value, 0),
Err(CrdsGossipError::PushMessageAlreadyReceived)
Err(CrdsGossipError::PushMessageOldVersion)
);
}
#[test]
@@ -690,6 +726,7 @@ mod test {
#[test]
fn test_process_prune() {
let mut crds = Crds::default();
let self_id = Pubkey::new_rand();
let mut push = CrdsGossipPush::default();
let peer = CrdsValue::new_unsigned(CrdsData::ContactInfo(ContactInfo::new_localhost(
&Pubkey::new_rand(),
@@ -707,7 +744,11 @@ mod test {
push.process_push_message(&mut crds, &Pubkey::default(), new_msg.clone(), 0),
Ok(None)
);
push.process_prune_msg(&peer.label().pubkey(), &[new_msg.label().pubkey()]);
push.process_prune_msg(
&self_id,
&peer.label().pubkey(),
&[new_msg.label().pubkey()],
);
assert_eq!(push.new_push_messages(&crds, 0), expected);
}
#[test]
@@ -749,9 +790,9 @@ mod test {
assert_eq!(crds.lookup(&label), Some(&value));
// push it again
assert_eq!(
assert_matches!(
push.process_push_message(&mut crds, &Pubkey::default(), value.clone(), 0),
Err(CrdsGossipError::PushMessageAlreadyReceived)
Err(CrdsGossipError::PushMessageOldVersion)
);
// purge the old pushed

40
core/src/fork_choice.rs Normal file
View File

@@ -0,0 +1,40 @@
use crate::{
consensus::{ComputedBankState, SwitchForkDecision, Tower},
progress_map::ProgressMap,
replay_stage::HeaviestForkFailures,
};
use solana_ledger::bank_forks::BankForks;
use solana_runtime::bank::Bank;
use std::{
collections::{HashMap, HashSet},
sync::{Arc, RwLock},
};
pub(crate) struct SelectVoteAndResetForkResult {
pub vote_bank: Option<(Arc<Bank>, SwitchForkDecision)>,
pub reset_bank: Option<Arc<Bank>>,
pub heaviest_fork_failures: Vec<HeaviestForkFailures>,
}
pub(crate) trait ForkChoice {
fn compute_bank_stats(
&mut self,
bank: &Bank,
tower: &Tower,
progress: &mut ProgressMap,
computed_bank_stats: &ComputedBankState,
);
// Returns:
// 1) The heaviest overall bbank
// 2) The heavest bank on the same fork as the last vote (doesn't require a
// switching proof to vote for)
fn select_forks(
&self,
frozen_banks: &[Arc<Bank>],
tower: &Tower,
progress: &ProgressMap,
ancestors: &HashMap<u64, HashSet<u64>>,
bank_forks: &RwLock<BankForks>,
) -> (Arc<Bank>, Option<Arc<Bank>>);
}

View File

@@ -0,0 +1,72 @@
use crate::{
consensus::{ComputedBankState, Tower},
fork_choice::ForkChoice,
heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice,
progress_map::ProgressMap,
};
use solana_ledger::bank_forks::BankForks;
use solana_runtime::bank::Bank;
use std::{
collections::{HashMap, HashSet},
sync::{Arc, RwLock},
};
impl ForkChoice for HeaviestSubtreeForkChoice {
fn compute_bank_stats(
&mut self,
bank: &Bank,
_tower: &Tower,
_progress: &mut ProgressMap,
computed_bank_stats: &ComputedBankState,
) {
let ComputedBankState { pubkey_votes, .. } = computed_bank_stats;
// Update `heaviest_subtree_fork_choice` to find the best fork to build on
let best_overall_slot = self.add_votes(
&pubkey_votes,
bank.epoch_stakes_map(),
bank.epoch_schedule(),
);
datapoint_info!(
"best_slot",
("slot", bank.slot(), i64),
("best_slot", best_overall_slot, i64),
);
}
// Returns:
// 1) The heaviest overall bbank
// 2) The heavest bank on the same fork as the last vote (doesn't require a
// switching proof to vote for)
fn select_forks(
&self,
_frozen_banks: &[Arc<Bank>],
tower: &Tower,
_progress: &ProgressMap,
_ancestors: &HashMap<u64, HashSet<u64>>,
bank_forks: &RwLock<BankForks>,
) -> (Arc<Bank>, Option<Arc<Bank>>) {
let last_vote = tower.last_vote().slots.last().cloned();
let heaviest_slot_on_same_voted_fork = last_vote.map(|last_vote| {
let heaviest_slot_on_same_voted_fork =
self.best_slot(last_vote).expect("last_vote is a frozen bank so must have been added to heaviest_subtree_fork_choice at time of freezing");
if heaviest_slot_on_same_voted_fork == last_vote {
None
} else {
Some(heaviest_slot_on_same_voted_fork)
}
}).unwrap_or(None);
let heaviest_slot = self.best_overall_slot();
let r_bank_forks = bank_forks.read().unwrap();
(
r_bank_forks.get(heaviest_slot).unwrap().clone(),
heaviest_slot_on_same_voted_fork.map(|heaviest_slot_on_same_voted_fork| {
r_bank_forks
.get(heaviest_slot_on_same_voted_fork)
.unwrap()
.clone()
}),
)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,10 +11,12 @@ pub mod banking_stage;
pub mod broadcast_stage;
pub mod cluster_info_vote_listener;
pub mod commitment;
pub mod commitment_service;
mod deprecated;
pub mod shred_fetch_stage;
#[macro_use]
pub mod contact_info;
pub mod bank_weight_fork_choice;
pub mod cluster_info;
pub mod cluster_slots;
pub mod consensus;
@@ -26,8 +28,10 @@ pub mod crds_gossip_push;
pub mod crds_value;
pub mod epoch_slots;
pub mod fetch_stage;
pub mod fork_choice;
pub mod gen_keys;
pub mod gossip_service;
pub mod heaviest_subtree_fork_choice;
pub mod ledger_cleanup_service;
pub mod local_vote_signer_service;
pub mod non_circulating_supply;

View File

@@ -57,8 +57,8 @@ solana_sdk::pubkeys!(
[
"9huDUZfxoJ7wGMTffUE7vh1xePqef7gyrLJu9NApncqA",
"GK2zqSsXLA2rwVZk347RYhh6jJpRsCA69FjLW93ZGi3B",
"CWeRmXme7LmbaUWTZWFLt6FMnpzLCHaQLuR2TdgFn4Lq",
"HCV5dGFJXRrJ3jhDYA4DCeb9TEDTwGGYXtT3wHksu2Zr",
"25odAafVXnd63L6Hq5Cx6xGmhKqkhE2y6UrLVuqUfWZj",
"14FUT96s9swbmH7ZjpDvfEDywnAYy9zaNhv4xvezySGu",
"HbZ5FfmKWNHC7uwk6TF1hVi6TCs7dtYfdjEcuPGgzFAg",
"C7C8odR8oashR5Feyrq2tJKaXL18id1dSj2zbkDGL2C2",
@@ -85,6 +85,7 @@ solana_sdk::pubkeys!(
[
"8CUUMKYNGxdgYio5CLHRHyzMEhhVRMcqefgE6dLqnVRK",
"3FFaheyqtyAXZSYxDzsr5CVKvJuvZD1WE1VEsBtDbRqB",
"FdGYQdiRky8NZzN9wZtczTBcWLYYRXrJ3LMDhqDPn5rM",
]
);

View File

@@ -3,7 +3,7 @@
use crate::{
cluster_info::ClusterInfo,
cluster_slots::ClusterSlots,
consensus::VOTE_THRESHOLD_SIZE,
commitment::VOTE_THRESHOLD_SIZE,
result::Result,
serve_repair::{RepairType, ServeRepair, DEFAULT_NONCE},
};

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,7 @@ use solana_client::{
DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE,
MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS, NUM_LARGEST_ACCOUNTS,
},
rpc_response::Response as RpcResponse,
rpc_response::*,
};
use solana_faucet::faucet::request_airdrop_transaction;
@@ -50,9 +51,7 @@ use std::{
sync::{Arc, RwLock},
};
type RpcResponse<T> = Result<Response<T>>;
fn new_response<T>(bank: &Bank, value: T) -> RpcResponse<T> {
fn new_response<T>(bank: &Bank, value: T) -> Result<RpcResponse<T>> {
let context = RpcResponseContext { slot: bank.slot() };
Ok(Response { context, value })
}
@@ -155,7 +154,7 @@ impl JsonRpcRequestProcessor {
&self,
pubkey: Result<Pubkey>,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcAccount>> {
) -> Result<RpcResponse<Option<RpcAccount>>> {
let bank = &*self.bank(commitment)?;
pubkey.and_then(|key| new_response(bank, bank.get_account(&key).map(RpcAccount::encode)))
}
@@ -219,7 +218,7 @@ impl JsonRpcRequestProcessor {
&self,
pubkey: Result<Pubkey>,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<u64> {
) -> Result<RpcResponse<u64>> {
let bank = &*self.bank(commitment)?;
pubkey.and_then(|key| new_response(bank, bank.get_balance(&key)))
}
@@ -227,7 +226,7 @@ impl JsonRpcRequestProcessor {
fn get_recent_blockhash(
&self,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcBlockhashFeeCalculator> {
) -> Result<RpcResponse<RpcBlockhashFeeCalculator>> {
let bank = &*self.bank(commitment)?;
let (blockhash, fee_calculator) = bank.confirmed_last_blockhash();
new_response(
@@ -239,7 +238,7 @@ impl JsonRpcRequestProcessor {
)
}
fn get_fees(&self, commitment: Option<CommitmentConfig>) -> RpcResponse<RpcFees> {
fn get_fees(&self, commitment: Option<CommitmentConfig>) -> Result<RpcResponse<RpcFees>> {
let bank = &*self.bank(commitment)?;
let (blockhash, fee_calculator) = bank.confirmed_last_blockhash();
let last_valid_slot = bank
@@ -259,7 +258,7 @@ impl JsonRpcRequestProcessor {
&self,
blockhash: &Hash,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcFeeCalculator>> {
) -> Result<RpcResponse<Option<RpcFeeCalculator>>> {
let bank = &*self.bank(commitment)?;
let fee_calculator = bank.get_fee_calculator(blockhash);
new_response(
@@ -268,7 +267,7 @@ impl JsonRpcRequestProcessor {
)
}
fn get_fee_rate_governor(&self) -> RpcResponse<RpcFeeRateGovernor> {
fn get_fee_rate_governor(&self) -> Result<RpcResponse<RpcFeeRateGovernor>> {
let bank = &*self.bank(None)?;
let fee_rate_governor = bank.get_fee_rate_governor();
new_response(
@@ -283,7 +282,7 @@ impl JsonRpcRequestProcessor {
&self,
signature: Result<Signature>,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<bool> {
) -> Result<RpcResponse<bool>> {
let bank = &*self.bank(commitment)?;
match signature {
Err(e) => Err(e),
@@ -339,7 +338,7 @@ impl JsonRpcRequestProcessor {
fn get_largest_accounts(
&self,
config: Option<RpcLargestAccountsConfig>,
) -> RpcResponse<Vec<RpcAccountBalance>> {
) -> Result<RpcResponse<Vec<RpcAccountBalance>>> {
let config = config.unwrap_or_default();
let bank = self.bank(config.commitment)?;
let (addresses, address_filter) = if let Some(filter) = config.filter {
@@ -365,7 +364,7 @@ impl JsonRpcRequestProcessor {
)
}
fn get_supply(&self, commitment: Option<CommitmentConfig>) -> RpcResponse<RpcSupply> {
fn get_supply(&self, commitment: Option<CommitmentConfig>) -> Result<RpcResponse<RpcSupply>> {
let bank = self.bank(commitment)?;
let non_circulating_supply = calculate_non_circulating_supply(&bank);
let total_supply = bank.capitalization();
@@ -586,7 +585,7 @@ impl JsonRpcRequestProcessor {
&self,
signatures: Vec<Signature>,
config: Option<RpcSignatureStatusConfig>,
) -> RpcResponse<Vec<Option<TransactionStatus>>> {
) -> Result<RpcResponse<Vec<Option<TransactionStatus>>>> {
let mut statuses: Vec<Option<TransactionStatus>> = vec![];
let search_transaction_history = config
@@ -741,7 +740,7 @@ fn run_transaction_simulation(
(executed[0].0.clone().map(|_| ()), log_collector.output())
}
#[rpc(server)]
#[rpc]
pub trait RpcSol {
type Metadata;
@@ -752,7 +751,7 @@ pub trait RpcSol {
meta: Self::Metadata,
signature_str: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<bool>;
) -> Result<RpcResponse<bool>>;
// DEPRECATED
#[rpc(meta, name = "getSignatureStatus")]
@@ -778,7 +777,7 @@ pub trait RpcSol {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcAccount>>;
) -> Result<RpcResponse<Option<RpcAccount>>>;
#[rpc(meta, name = "getProgramAccounts")]
fn get_program_accounts(
@@ -819,7 +818,7 @@ pub trait RpcSol {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<u64>;
) -> Result<RpcResponse<u64>>;
#[rpc(meta, name = "getClusterNodes")]
fn get_cluster_nodes(&self, meta: Self::Metadata) -> Result<Vec<RpcContactInfo>>;
@@ -854,14 +853,14 @@ pub trait RpcSol {
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcBlockhashFeeCalculator>;
) -> Result<RpcResponse<RpcBlockhashFeeCalculator>>;
#[rpc(meta, name = "getFees")]
fn get_fees(
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcFees>;
) -> Result<RpcResponse<RpcFees>>;
#[rpc(meta, name = "getFeeCalculatorForBlockhash")]
fn get_fee_calculator_for_blockhash(
@@ -869,10 +868,13 @@ pub trait RpcSol {
meta: Self::Metadata,
blockhash: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcFeeCalculator>>;
) -> Result<RpcResponse<Option<RpcFeeCalculator>>>;
#[rpc(meta, name = "getFeeRateGovernor")]
fn get_fee_rate_governor(&self, meta: Self::Metadata) -> RpcResponse<RpcFeeRateGovernor>;
fn get_fee_rate_governor(
&self,
meta: Self::Metadata,
) -> Result<RpcResponse<RpcFeeRateGovernor>>;
#[rpc(meta, name = "getSignatureStatuses")]
fn get_signature_statuses(
@@ -880,7 +882,7 @@ pub trait RpcSol {
meta: Self::Metadata,
signature_strs: Vec<String>,
config: Option<RpcSignatureStatusConfig>,
) -> RpcResponse<Vec<Option<TransactionStatus>>>;
) -> Result<RpcResponse<Vec<Option<TransactionStatus>>>>;
#[rpc(meta, name = "getSlot")]
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64>;
@@ -905,14 +907,14 @@ pub trait RpcSol {
&self,
meta: Self::Metadata,
config: Option<RpcLargestAccountsConfig>,
) -> RpcResponse<Vec<RpcAccountBalance>>;
) -> Result<RpcResponse<Vec<RpcAccountBalance>>>;
#[rpc(meta, name = "getSupply")]
fn get_supply(
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcSupply>;
) -> Result<RpcResponse<RpcSupply>>;
#[rpc(meta, name = "requestAirdrop")]
fn request_airdrop(
@@ -937,7 +939,7 @@ pub trait RpcSol {
meta: Self::Metadata,
data: String,
config: Option<RpcSimulateTransactionConfig>,
) -> RpcResponse<RpcSimulateTransactionResult>;
) -> Result<RpcResponse<RpcSimulateTransactionResult>>;
#[rpc(meta, name = "getSlotLeader")]
fn get_slot_leader(
@@ -1017,7 +1019,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
id: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<bool> {
) -> Result<RpcResponse<bool>> {
debug!("confirm_transaction rpc request received: {:?}", id);
let signature = verify_signature(&id);
meta.confirm_transaction(signature, commitment)
@@ -1028,7 +1030,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcAccount>> {
) -> Result<RpcResponse<Option<RpcAccount>>> {
debug!("get_account_info rpc request received: {:?}", pubkey_str);
let pubkey = verify_pubkey(pubkey_str);
meta.get_account_info(pubkey, commitment)
@@ -1089,7 +1091,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
pubkey_str: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<u64> {
) -> Result<RpcResponse<u64>> {
debug!("get_balance rpc request received: {:?}", pubkey_str);
let pubkey = verify_pubkey(pubkey_str);
meta.get_balance(pubkey, commitment)
@@ -1181,7 +1183,7 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcBlockhashFeeCalculator> {
) -> Result<RpcResponse<RpcBlockhashFeeCalculator>> {
debug!("get_recent_blockhash rpc request received");
meta.get_recent_blockhash(commitment)
}
@@ -1190,7 +1192,7 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcFees> {
) -> Result<RpcResponse<RpcFees>> {
debug!("get_fees rpc request received");
meta.get_fees(commitment)
}
@@ -1200,14 +1202,17 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
blockhash: String,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcFeeCalculator>> {
) -> Result<RpcResponse<Option<RpcFeeCalculator>>> {
debug!("get_fee_calculator_for_blockhash rpc request received");
let blockhash =
Hash::from_str(&blockhash).map_err(|e| Error::invalid_params(format!("{:?}", e)))?;
meta.get_fee_calculator_for_blockhash(&blockhash, commitment)
}
fn get_fee_rate_governor(&self, meta: Self::Metadata) -> RpcResponse<RpcFeeRateGovernor> {
fn get_fee_rate_governor(
&self,
meta: Self::Metadata,
) -> Result<RpcResponse<RpcFeeRateGovernor>> {
debug!("get_fee_rate_governor rpc request received");
meta.get_fee_rate_governor()
}
@@ -1241,7 +1246,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
signature_strs: Vec<String>,
config: Option<RpcSignatureStatusConfig>,
) -> RpcResponse<Vec<Option<TransactionStatus>>> {
) -> Result<RpcResponse<Vec<Option<TransactionStatus>>>> {
if signature_strs.len() > MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS {
return Err(Error::invalid_params(format!(
"Too many inputs provided; max {}",
@@ -1281,7 +1286,7 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
config: Option<RpcLargestAccountsConfig>,
) -> RpcResponse<Vec<RpcAccountBalance>> {
) -> Result<RpcResponse<Vec<RpcAccountBalance>>> {
debug!("get_largest_accounts rpc request received");
meta.get_largest_accounts(config)
}
@@ -1290,7 +1295,7 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcSupply> {
) -> Result<RpcResponse<RpcSupply>> {
debug!("get_supply rpc request received");
meta.get_supply(commitment)
}
@@ -1392,7 +1397,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
data: String,
config: Option<RpcSimulateTransactionConfig>,
) -> RpcResponse<RpcSimulateTransactionResult> {
) -> Result<RpcResponse<RpcSimulateTransactionResult>> {
let (_, transaction) = deserialize_bs58_transaction(data)?;
let config = config.unwrap_or_default();
@@ -1558,7 +1563,10 @@ pub mod tests {
replay_stage::tests::create_test_transactions_and_populate_blockstore,
};
use bincode::deserialize;
use jsonrpc_core::{ErrorCode, MetaIoHandler, Output, Response, Value};
use jsonrpc_core::{
futures::future::Future, ErrorCode, MetaIoHandler, Output, Response, Value,
};
use jsonrpc_core_client::transports::local;
use solana_ledger::{
blockstore::entries_to_test_shreds,
blockstore_processor::fill_blockstore_slot_with_ticks,
@@ -1822,6 +1830,20 @@ pub mod tests {
assert_eq!(expected, result);
}
#[test]
fn test_rpc_get_balance_via_client() {
let bob_pubkey = Pubkey::new_rand();
let handler = start_rpc_handler_with_tx(&bob_pubkey);
let fut = {
let (client, server) =
local::connect_with_metadata::<gen_client::Client, _, _>(&handler.io, handler.meta);
client
.get_balance(bob_pubkey.to_string(), None)
.join(server)
};
assert_eq!(20, fut.wait().unwrap().0.value);
}
#[test]
fn test_rpc_get_cluster_nodes() {
let bob_pubkey = Pubkey::new_rand();
@@ -2886,7 +2908,7 @@ pub mod tests {
let bank = Bank::new(&genesis_config);
(
Arc::new(RwLock::new(BankForks::new(bank.slot(), bank))),
Arc::new(RwLock::new(BankForks::new(bank))),
mint_keypair,
voting_keypair,
)

View File

@@ -355,8 +355,8 @@ mod tests {
use super::*;
use crate::{
cluster_info_vote_listener::{ClusterInfoVoteListener, VoteTracker},
commitment::{BlockCommitmentCache, CacheSlotInfo},
rpc_subscriptions::tests::robust_poll_or_panic,
commitment::BlockCommitmentCache,
rpc_subscriptions::{tests::robust_poll_or_panic, CacheSlotInfo},
};
use crossbeam_channel::unbounded;
use jsonrpc_core::{futures::sync::mpsc, Response};
@@ -420,7 +420,7 @@ mod tests {
let bob_pubkey = bob.pubkey();
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let ledger_path = get_tmp_ledger_path!();
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let rpc = RpcSolPubSubImpl {
@@ -471,7 +471,7 @@ mod tests {
let bob_pubkey = Pubkey::new_rand();
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let ledger_path = get_tmp_ledger_path!();
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
@@ -528,7 +528,7 @@ mod tests {
let budget_program_id = solana_budget_program::id();
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let bank0 = bank_forks.read().unwrap().get(0).unwrap().clone();
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
bank_forks.write().unwrap().insert(bank1);
@@ -638,7 +638,7 @@ mod tests {
let ledger_path = get_tmp_ledger_path!();
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, Bank::new(&genesis_config))));
let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config))));
let mut io = PubSubHandler::default();
let rpc = RpcSolPubSubImpl::default_with_blockstore_bank_forks(blockstore, bank_forks);
@@ -680,7 +680,7 @@ mod tests {
} = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(1, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let ledger_path = get_tmp_ledger_path!();
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let bob = Keypair::new();
@@ -731,7 +731,7 @@ mod tests {
} = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let bank0 = bank_forks.read().unwrap().get(0).unwrap().clone();
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
bank_forks.write().unwrap().insert(bank1);
@@ -807,7 +807,7 @@ mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let rpc = RpcSolPubSubImpl::default_with_blockstore_bank_forks(blockstore, bank_forks);
let session = create_session();
let (subscriber, _id_receiver, receiver) = Subscriber::new_test("slotNotification");
@@ -837,7 +837,7 @@ mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let rpc = RpcSolPubSubImpl::default_with_blockstore_bank_forks(blockstore, bank_forks);
let session = create_session();
let (subscriber, _id_receiver, receiver) = Subscriber::new_test("slotNotification");
@@ -884,7 +884,7 @@ mod tests {
create_genesis_config_with_vote_accounts(10_000, &validator_voting_keypairs, 100);
let exit = Arc::new(AtomicBool::new(false));
let bank = Bank::new(&genesis_config);
let bank_forks = BankForks::new(0, bank);
let bank_forks = BankForks::new(bank);
let bank = bank_forks.get(0).unwrap().clone();
let bank_forks = Arc::new(RwLock::new(bank_forks));
@@ -944,7 +944,7 @@ mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let rpc = RpcSolPubSubImpl::default_with_blockstore_bank_forks(blockstore, bank_forks);
let session = create_session();
let (subscriber, _id_receiver, _) = Subscriber::new_test("voteNotification");

View File

@@ -93,7 +93,7 @@ mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let subscriptions = Arc::new(RpcSubscriptions::new(
&exit,
bank_forks,

View File

@@ -374,7 +374,7 @@ mod tests {
ip_addr,
solana_net_utils::find_available_port_in_range(ip_addr, (10000, 65535)).unwrap(),
);
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank.slot(), bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let ledger_path = get_tmp_ledger_path!();
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let block_commitment_cache = Arc::new(RwLock::new(
@@ -412,7 +412,7 @@ mod tests {
fn create_bank_forks() -> Arc<RwLock<BankForks>> {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
Arc::new(RwLock::new(BankForks::new(bank.slot(), bank)))
Arc::new(RwLock::new(BankForks::new(bank)))
}
#[test]

View File

@@ -1,6 +1,6 @@
//! The `pubsub` module implements a threaded subscription service on client RPC request
use crate::commitment::{BlockCommitmentCache, CacheSlotInfo};
use crate::commitment::BlockCommitmentCache;
use core::hash::Hash;
use jsonrpc_core::futures::Future;
use jsonrpc_pubsub::{
@@ -44,6 +44,14 @@ pub struct SlotInfo {
pub root: Slot,
}
#[derive(Default)]
pub struct CacheSlotInfo {
pub current_slot: Slot,
pub node_root: Slot,
pub largest_confirmed_root: Slot,
pub highest_confirmed_slot: Slot,
}
// A more human-friendly version of Vote, with the bank state signature base58 encoded.
#[derive(Serialize, Deserialize, Debug)]
pub struct RpcVote {
@@ -880,7 +888,7 @@ pub(crate) mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let bank0 = bank_forks.read().unwrap().get(0).unwrap().clone();
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
bank_forks.write().unwrap().insert(bank1);
@@ -974,7 +982,7 @@ pub(crate) mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let alice = Keypair::new();
let tx = system_transaction::create_account(
&mint_keypair,
@@ -1062,7 +1070,7 @@ pub(crate) mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let mut bank_forks = BankForks::new(0, bank);
let mut bank_forks = BankForks::new(bank);
let alice = Keypair::new();
let past_bank_tx =
@@ -1218,7 +1226,7 @@ pub(crate) mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let subscriptions = RpcSubscriptions::new(
&exit,
bank_forks,
@@ -1270,7 +1278,7 @@ pub(crate) mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let subscriptions = RpcSubscriptions::new(
&exit,
bank_forks,
@@ -1368,7 +1376,7 @@ pub(crate) mod tests {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let bank = Bank::new(&genesis_config);
let blockhash = bank.last_blockhash();
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let bank0 = bank_forks.read().unwrap().get(0).unwrap().clone();
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
bank_forks.write().unwrap().insert(bank1);

View File

@@ -127,7 +127,7 @@ pub mod tests {
let bank =
Bank::new(&create_genesis_config_with_leader(100, &leader_pubkey, 10).genesis_config);
let cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank));
let bf = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bf = Arc::new(RwLock::new(BankForks::new(bank)));
let verifier = ShredSigVerifier::new(bf, cache);
let mut batch = vec![Packets::default()];

View File

@@ -256,7 +256,7 @@ pub mod tests {
let starting_balance = 10_000;
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(starting_balance);
let bank_forks = BankForks::new(0, Bank::new(&genesis_config));
let bank_forks = BankForks::new(Bank::new(&genesis_config));
//start cluster_info1
let cluster_info1 = ClusterInfo::new_with_invalid_keypair(target1.info.clone());

View File

@@ -49,7 +49,7 @@ mod tests {
&[],
);
bank0.freeze();
let mut bank_forks = BankForks::new(0, bank0);
let mut bank_forks = BankForks::new(bank0);
bank_forks.accounts_hash_interval_slots = snapshot_interval_slots;
let snapshot_config = SnapshotConfig {

View File

@@ -96,7 +96,7 @@ fn test_slot_subscription() {
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank)));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
let subscriptions = Arc::new(RpcSubscriptions::new(
&exit,
bank_forks,

View File

@@ -436,7 +436,7 @@ fn network_run_pull(
let rsp = node
.lock()
.unwrap()
.generate_pull_responses(&filters, None)
.generate_pull_responses(&filters)
.into_iter()
.flatten()
.collect();

View File

@@ -4,13 +4,14 @@ extern crate log;
use rayon::iter::*;
use solana_core::cluster_info::{ClusterInfo, Node};
use solana_core::gossip_service::GossipService;
use solana_ledger::bank_forks::BankForks;
use solana_perf::packet::Packet;
use solana_sdk::signature::{Keypair, Signer};
use solana_sdk::timing::timestamp;
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::sync::{Arc, RwLock};
use std::thread::sleep;
use std::time::Duration;
@@ -27,6 +28,28 @@ fn test_node(exit: &Arc<AtomicBool>) -> (Arc<ClusterInfo>, GossipService, UdpSoc
)
}
fn test_node_with_bank(
node_keypair: Keypair,
exit: &Arc<AtomicBool>,
bank_forks: Arc<RwLock<BankForks>>,
) -> (Arc<ClusterInfo>, GossipService, UdpSocket) {
let keypair = Arc::new(node_keypair);
let mut test_node = Node::new_localhost_with_pubkey(&keypair.pubkey());
let cluster_info = Arc::new(ClusterInfo::new(test_node.info.clone(), keypair));
let gossip_service = GossipService::new(
&cluster_info,
Some(bank_forks),
test_node.sockets.gossip,
exit,
);
let _ = cluster_info.my_contact_info();
(
cluster_info,
gossip_service,
test_node.sockets.tvu.pop().unwrap(),
)
}
/// Test that the network converges.
/// Run until every node in the network has a full ContactInfo set.
/// Check that nodes stop sending updates after all the ContactInfo has been shared.
@@ -181,3 +204,120 @@ pub fn cluster_info_retransmit() {
dr2.join().unwrap();
dr3.join().unwrap();
}
#[test]
#[ignore]
pub fn cluster_info_scale() {
use solana_measure::measure::Measure;
use solana_perf::test_tx::test_tx;
use solana_runtime::bank::Bank;
use solana_runtime::genesis_utils::{
create_genesis_config_with_vote_accounts, ValidatorVoteKeypairs,
};
solana_logger::setup();
let exit = Arc::new(AtomicBool::new(false));
let num_nodes: usize = std::env::var("NUM_NODES")
.unwrap_or_else(|_| "10".to_string())
.parse()
.expect("could not parse NUM_NODES as a number");
let vote_keypairs: Vec<_> = (0..num_nodes)
.map(|_| ValidatorVoteKeypairs::new_rand())
.collect();
let genesis_config_info = create_genesis_config_with_vote_accounts(10_000, &vote_keypairs, 100);
let bank0 = Bank::new(&genesis_config_info.genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0)));
let nodes: Vec<_> = vote_keypairs
.into_iter()
.map(|keypairs| test_node_with_bank(keypairs.node_keypair, &exit, bank_forks.clone()))
.collect();
let ci0 = nodes[0].0.my_contact_info();
for node in &nodes[1..] {
node.0.insert_info(ci0.clone());
}
let mut time = Measure::start("time");
let mut done;
let mut success = false;
for _ in 0..30 {
done = true;
for (i, node) in nodes.iter().enumerate() {
warn!("node {} peers: {}", i, node.0.gossip_peers().len());
if node.0.gossip_peers().len() != num_nodes - 1 {
done = false;
break;
}
}
if done {
success = true;
break;
}
sleep(Duration::from_secs(1));
}
time.stop();
warn!("found {} nodes in {} success: {}", num_nodes, time, success);
for num_votes in 1..1000 {
let mut time = Measure::start("votes");
let tx = test_tx();
warn!("tx.message.account_keys: {:?}", tx.message.account_keys);
nodes[0].0.push_vote(0, tx.clone());
let mut success = false;
for _ in 0..(30 * 5) {
let mut not_done = 0;
let mut num_old = 0;
let mut num_push_total = 0;
let mut num_pushes = 0;
let mut num_pulls = 0;
let mut num_inserts = 0;
for node in nodes.iter() {
//if node.0.get_votes(0).1.len() != (num_nodes * num_votes) {
let has_tx = node
.0
.get_votes(0)
.1
.iter()
.filter(|v| v.message.account_keys == tx.message.account_keys)
.count();
num_old += node.0.gossip.read().unwrap().push.num_old;
num_push_total += node.0.gossip.read().unwrap().push.num_total;
num_pushes += node.0.gossip.read().unwrap().push.num_pushes;
num_pulls += node.0.gossip.read().unwrap().pull.num_pulls;
num_inserts += node.0.gossip.read().unwrap().crds.num_inserts;
if has_tx == 0 {
not_done += 1;
}
}
warn!("not_done: {}/{}", not_done, nodes.len());
warn!("num_old: {}", num_old);
warn!("num_push_total: {}", num_push_total);
warn!("num_pushes: {}", num_pushes);
warn!("num_pulls: {}", num_pulls);
warn!("num_inserts: {}", num_inserts);
success = not_done < (nodes.len() / 20);
if success {
break;
}
sleep(Duration::from_millis(200));
}
time.stop();
warn!(
"propagated vote {} in {} success: {}",
num_votes, time, success
);
sleep(Duration::from_millis(200));
for node in nodes.iter() {
node.0.gossip.write().unwrap().push.num_old = 0;
node.0.gossip.write().unwrap().push.num_total = 0;
node.0.gossip.write().unwrap().push.num_pushes = 0;
node.0.gossip.write().unwrap().pull.num_pulls = 0;
node.0.gossip.write().unwrap().crds.num_inserts = 0;
}
}
exit.store(true, Ordering::Relaxed);
for node in nodes {
node.1.join().unwrap();
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-crate-features"
version = "1.2.1"
version = "1.2.2"
description = "Solana Crate Features"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -983,7 +983,7 @@ The result field will be a JSON object with the following fields:
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"solana-core": "1.2.1"},"id":1}
{"jsonrpc":"2.0","result":{"solana-core": "1.2.2"},"id":1}
```
### getVoteAccounts

View File

@@ -7,6 +7,25 @@ experience for most people who are new or experienced with using crypto wallets.
currently the easiest and fastest way to get set up with a new wallet on Solana.
The app is free and getting your wallet set up only takes a few minutes.
### Trust Wallet Security
Tokens held in Trust Wallet are only as secure as the device on which the app is
installed. Anyone who is able to unlock your phone or tablet may be able to
use the Trust Wallet app and transfer your tokens. To improve security,
you can add a passcode to the Trust Wallet application.
To add a Trust Wallet passcode, open the app and go to
Settings -> Security -> Passcode.
If someone gains access to your Trust Wallet application, they can access your
recovery seed phrase.
Anyone who has access to your seed phrase will be able to recreate
your Trust Wallet keys on a different device. From there, they could
sign transactions from that device rather than on your own phone or tablet.
The seed phrase is displayed when a new wallet is created and it can also be
viewed at any later time in the app by following these steps:
- Go to Setting -> Wallets
- Under the Options menu for a particular wallet tap "Show Recovery Phrase"
{% page-ref page="trust-wallet.md" %}
## Ledger Live with Ledger Nano S

View File

@@ -59,7 +59,7 @@ some interface for signing transactions.
A hardware wallet, such as the
[Ledger hardware wallet](https://www.ledger.com/), offers a great blend of
security and convenience for cryptocurrencies. It effectively automates the
process of offline signing while retaining nearly all the convenience of an FS
wallet.
process of offline signing while retaining nearly all the convenience of a file
system wallet.
{% page-ref page="../hardware-wallet/README.md" %}

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-dos"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -13,14 +13,14 @@ clap = "2.33.1"
log = "0.4.8"
rand = "0.7.0"
rayon = "1.3.0"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-core = { path = "../core", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-download-utils"
version = "1.2.1"
version = "1.2.2"
description = "Solana Download Utils"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,8 +14,8 @@ console = "0.10.1"
indicatif = "0.14.0"
log = "0.4.8"
reqwest = { version = "0.10.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
tar = "0.4.28"
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-faucet"
version = "1.2.1"
version = "1.2.2"
description = "Solana Faucet"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,11 +16,11 @@ clap = "2.33"
log = "0.4.8"
serde = "1.0.110"
serde_derive = "1.0.103"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
tokio = "0.1"
tokio-codec = "0.1"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-genesis-programs"
version = "1.2.1"
version = "1.2.2"
description = "Solana genesis programs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,12 +10,12 @@ edition = "2018"
[dependencies]
log = { version = "0.4.8" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.1" }
solana-budget-program = { path = "../programs/budget", version = "1.2.1" }
solana-exchange-program = { path = "../programs/exchange", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-vest-program = { path = "../programs/vest", version = "1.2.1" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.2" }
solana-budget-program = { path = "../programs/budget", version = "1.2.2" }
solana-exchange-program = { path = "../programs/exchange", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-vest-program = { path = "../programs/vest", version = "1.2.2" }
[lib]
crate-type = ["lib"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-genesis"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,14 +15,14 @@ chrono = "0.4"
serde = "1.0.110"
serde_json = "1.0.53"
serde_yaml = "0.8.12"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-stake-program = { path = "../programs/stake", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-stake-program = { path = "../programs/stake", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
tempfile = "3.1.0"
[[bin]]

View File

@@ -3,20 +3,20 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-gossip"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.1"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-net-utils = { path = "../net-utils", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-core = { path = "../core", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-net-utils = { path = "../net-utils", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-install"
description = "The solana cluster software installer"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -24,12 +24,12 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
serde = "1.0.110"
serde_derive = "1.0.103"
serde_yaml = "0.8.12"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-config-program = { path = "../programs/config", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-config-program = { path = "../programs/config", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
semver = "0.9.0"
tar = "0.4.28"
tempdir = "0.3.7"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-keygen"
version = "1.2.1"
version = "1.2.2"
description = "Solana key generation utility"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,11 +13,11 @@ bs58 = "0.3.1"
clap = "2.33"
dirs = "2.0.2"
num_cpus = "1.13.0"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-cli-config = { path = "../cli-config", version = "1.2.1" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-cli-config = { path = "../cli-config", version = "1.2.2" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
tiny-bip39 = "0.7.0"
[[bin]]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-ledger-tool"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -16,16 +16,16 @@ histogram = "*"
log = { version = "0.4.8" }
serde_json = "1.0.53"
serde_yaml = "0.8.12"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-cli = { path = "../cli", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-stake-program = { path = "../programs/stake", version = "1.2.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-cli = { path = "../cli", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-stake-program = { path = "../programs/stake", version = "1.2.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
tempfile = "3.1.0"
[dev-dependencies]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ledger"
version = "1.2.1"
version = "1.2.2"
description = "Solana ledger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -30,19 +30,19 @@ reed-solomon-erasure = { version = "4.0.2", features = ["simd-accel"] }
regex = "1.3.7"
serde = "1.0.110"
serde_bytes = "0.11.4"
solana-transaction-status = { path = "../transaction-status", version = "1.2.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-measure = { path = "../measure", version = "1.2.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-perf = { path = "../perf", version = "1.2.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.2" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-measure = { path = "../measure", version = "1.2.2" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
solana-perf = { path = "../perf", version = "1.2.2" }
ed25519-dalek = "1.0.0-pre.3"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-stake-program = { path = "../programs/stake", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-stake-program = { path = "../programs/stake", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
symlink = "0.1.0"
tar = "0.4.28"
thiserror = "1.0"
@@ -59,7 +59,7 @@ features = ["lz4"]
[dev-dependencies]
assert_matches = "1.3.0"
matches = "0.1.6"
solana-budget-program = { path = "../programs/budget", version = "1.2.1" }
solana-budget-program = { path = "../programs/budget", version = "1.2.2" }
[lib]
crate-type = ["lib"]

View File

@@ -67,19 +67,9 @@ impl Index<u64> for BankForks {
}
impl BankForks {
pub fn new(bank_slot: Slot, bank: Bank) -> Self {
let mut banks = HashMap::new();
let working_bank = Arc::new(bank);
banks.insert(bank_slot, working_bank.clone());
Self {
banks,
working_bank,
root: 0,
snapshot_config: None,
last_snapshot_slot: bank_slot,
accounts_hash_interval_slots: std::u64::MAX,
last_accounts_hash_slot: bank_slot,
}
pub fn new(bank: Bank) -> Self {
let root = bank.slot();
Self::new_from_banks(&[Arc::new(bank)], root)
}
/// Create a map of bank slot id to the set of ancestors for the bank slot.
@@ -384,7 +374,7 @@ mod tests {
fn test_bank_forks_new() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank);
let mut bank_forks = BankForks::new(bank);
let child_bank = Bank::new_from_parent(&bank_forks[0u64], &Pubkey::default(), 1);
child_bank.register_tick(&Hash::default());
bank_forks.insert(child_bank);
@@ -411,7 +401,7 @@ mod tests {
fn test_bank_forks_descendants() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank);
let mut bank_forks = BankForks::new(bank);
let bank0 = bank_forks[0].clone();
let bank = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
bank_forks.insert(bank);
@@ -428,7 +418,7 @@ mod tests {
fn test_bank_forks_ancestors() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank);
let mut bank_forks = BankForks::new(bank);
let bank0 = bank_forks[0].clone();
let bank = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
bank_forks.insert(bank);
@@ -446,7 +436,7 @@ mod tests {
fn test_bank_forks_frozen_banks() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank);
let mut bank_forks = BankForks::new(bank);
let child_bank = Bank::new_from_parent(&bank_forks[0u64], &Pubkey::default(), 1);
bank_forks.insert(child_bank);
assert!(bank_forks.frozen_banks().get(&0).is_some());
@@ -457,7 +447,7 @@ mod tests {
fn test_bank_forks_active_banks() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank);
let mut bank_forks = BankForks::new(bank);
let child_bank = Bank::new_from_parent(&bank_forks[0u64], &Pubkey::default(), 1);
bank_forks.insert(child_bank);
assert_eq!(bank_forks.active_banks(), vec![1]);

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-local-cluster"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -12,22 +12,22 @@ homepage = "https://solana.com/"
itertools = "0.9.0"
log = "0.4.8"
rand = "0.7.0"
solana-config-program = { path = "../programs/config", version = "1.2.1" }
solana-core = { path = "../core", version = "1.2.1" }
solana-client = { path = "../client", version = "1.2.1" }
solana-download-utils = { path = "../download-utils", version = "1.2.1" }
solana-faucet = { path = "../faucet", version = "1.2.1" }
solana-exchange-program = { path = "../programs/exchange", version = "1.2.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.1" }
solana-ledger = { path = "../ledger", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-runtime = { path = "../runtime", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-stake-program = { path = "../programs/stake", version = "1.2.1" }
solana-vest-program = { path = "../programs/vest", version = "1.2.1" }
solana-vote-program = { path = "../programs/vote", version = "1.2.1" }
solana-config-program = { path = "../programs/config", version = "1.2.2" }
solana-core = { path = "../core", version = "1.2.2" }
solana-client = { path = "../client", version = "1.2.2" }
solana-download-utils = { path = "../download-utils", version = "1.2.2" }
solana-faucet = { path = "../faucet", version = "1.2.2" }
solana-exchange-program = { path = "../programs/exchange", version = "1.2.2" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.2" }
solana-ledger = { path = "../ledger", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-runtime = { path = "../runtime", version = "1.2.2" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-stake-program = { path = "../programs/stake", version = "1.2.2" }
solana-vest-program = { path = "../programs/vest", version = "1.2.2" }
solana-vote-program = { path = "../programs/vote", version = "1.2.2" }
tempfile = "3.1.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.2" }
[dev-dependencies]
assert_matches = "1.3.0"

View File

@@ -357,20 +357,18 @@ fn test_cluster_partition_1_1_1() {
#[test]
#[serial]
fn test_kill_partition() {
fn test_kill_heaviest_partition() {
// This test:
// 1) Spins up three partitions
// 2) Forces more slots in the leader schedule for the first partition so
// that this partition will be the heaviiest
// 3) Schedules the other validators for sufficient slots in the schedule
// 1) Spins up four partitions, the heaviest being the first with more stake
// 2) Schedules the other validators for sufficient slots in the schedule
// so that they will still be locked out of voting for the major partitoin
// when the partition resolves
// 4) Kills the major partition. Validators are locked out, but should be
// able to reset to the major partition
// 5) Check for recovery
// 3) Kills the most staked partition. Validators are locked out, but should all
// eventually choose the major partition
// 4) Check for recovery
let mut leader_schedule = vec![];
let num_slots_per_validator = 8;
let partitions: [&[usize]; 3] = [&[9], &[10], &[10]];
let partitions: [&[usize]; 4] = [&[11], &[10], &[10], &[10]];
let validator_keys: Vec<_> = iter::repeat_with(|| Arc::new(Keypair::new()))
.take(partitions.len())
.collect();

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-log-analyzer"
description = "The solana cluster network analysis tool"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,9 +14,9 @@ byte-unit = "3.1.1"
clap = "2.33.1"
serde = "1.0.110"
serde_json = "1.0.53"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
[[bin]]
name = "solana-log-analyzer"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-logger"
version = "1.2.1"
version = "1.2.2"
description = "Solana Logger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-measure"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -12,8 +12,8 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
[target."cfg(unix)".dependencies]
jemallocator = "0.3.2"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-merkle-tree"
version = "1.2.1"
version = "1.2.2"
description = "Solana Merkle Tree"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
fast-math = "0.1"
[dev-dependencies]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-metrics"
version = "1.2.1"
version = "1.2.2"
description = "Solana Metrics"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,7 +14,7 @@ gethostname = "0.2.1"
lazy_static = "1.4.0"
log = "0.4.8"
reqwest = { version = "0.10.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
[dev-dependencies]
rand = "0.7.0"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-net-shaper"
description = "The solana cluster network shaping tool"
version = "1.2.1"
version = "1.2.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -13,8 +13,8 @@ publish = false
clap = "2.33.1"
serde = "1.0.110"
serde_json = "1.0.53"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
rand = "0.7.0"
[[bin]]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-net-utils"
version = "1.2.1"
version = "1.2.2"
description = "Solana Network Utilities"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,9 +18,9 @@ rand = "0.7.0"
serde = "1.0.110"
serde_derive = "1.0.103"
socket2 = "0.3.12"
solana-clap-utils = { path = "../clap-utils", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-version = { path = "../version", version = "1.2.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-version = { path = "../version", version = "1.2.2" }
tokio = "0.1"
tokio-codec = "0.1"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-notifier"
version = "1.2.1"
version = "1.2.2"
description = "Solana Notifier"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-perf"
version = "1.2.1"
version = "1.2.2"
description = "Solana Performance APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -17,11 +17,11 @@ serde = "1.0.110"
dlopen_derive = "0.1.4"
lazy_static = "1.4.0"
log = "0.4.8"
solana-sdk = { path = "../sdk", version = "1.2.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.1" }
solana-budget-program = { path = "../programs/budget", version = "1.2.1" }
solana-logger = { path = "../logger", version = "1.2.1" }
solana-metrics = { path = "../metrics", version = "1.2.1" }
solana-sdk = { path = "../sdk", version = "1.2.2" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.2" }
solana-budget-program = { path = "../programs/budget", version = "1.2.2" }
solana-logger = { path = "../logger", version = "1.2.2" }
solana-metrics = { path = "../metrics", version = "1.2.2" }
curve25519-dalek = { version = "2" }
[lib]

418
programs/bpf/Cargo.lock generated
View File

@@ -104,7 +104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bumpalo"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -165,15 +165,15 @@ name = "chrono"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clear_on_drop"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -222,11 +222,12 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -278,7 +279,7 @@ name = "ed25519-dalek"
version = "1.0.0-pre.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clear_on_drop 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"curve25519-dalek 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -332,10 +333,10 @@ name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -401,9 +402,9 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -429,10 +430,10 @@ dependencies = [
"futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-nested 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -446,11 +447,12 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.14.1"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -498,7 +500,7 @@ dependencies = [
"futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -582,7 +584,7 @@ dependencies = [
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"socket2 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -617,7 +619,7 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.3.2"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -651,7 +653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -845,23 +847,23 @@ name = "num-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.42"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.11"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -917,22 +919,22 @@ dependencies = [
[[package]]
name = "paste"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"paste-impl 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"paste-impl 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "paste-impl"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -951,25 +953,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pin-project"
version = "0.4.17"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pin-project-internal 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-internal 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-project-internal"
version = "0.4.17"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-project-lite"
version = "0.1.5"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -994,7 +996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro-nested"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1007,7 +1009,7 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.17"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1028,10 +1030,10 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1087,7 +1089,7 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1142,10 +1144,10 @@ dependencies = [
"mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1198,7 +1200,7 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1227,9 +1229,9 @@ name = "scroll_derive"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1264,7 +1266,7 @@ dependencies = [
[[package]]
name = "serde_bytes"
version = "0.11.4"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1275,18 +1277,18 @@ name = "serde_derive"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.53"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1343,195 +1345,195 @@ dependencies = [
[[package]]
name = "solana-bpf-loader-program"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 1.2.1",
"solana-runtime 1.2.1",
"solana-sdk 1.2.1",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 1.2.2",
"solana-runtime 1.2.2",
"solana-sdk 1.2.2",
"solana_rbpf 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-programs"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-bpf-loader-program 1.2.1",
"solana-logger 1.2.1",
"solana-runtime 1.2.1",
"solana-sdk 1.2.1",
"solana-bpf-loader-program 1.2.2",
"solana-logger 1.2.2",
"solana-runtime 1.2.2",
"solana-sdk 1.2.2",
"solana_rbpf 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-rust-128bit"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-bpf-rust-128bit-dep 1.2.1",
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-bpf-rust-128bit-dep 1.2.2",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-128bit-dep"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-alloc"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-dep-crate"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-dup-accounts"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-error-handling"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
"thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-rust-external-spend"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-invoke"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-bpf-rust-invoked 1.2.1",
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-bpf-rust-invoked 1.2.2",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-invoked"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-iter"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-bpf-rust-many-args-dep 1.2.1",
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-bpf-rust-many-args-dep 1.2.2",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-many-args-dep"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-noop"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-panic"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-param-passing"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-bpf-rust-param-passing-dep 1.2.1",
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-bpf-rust-param-passing-dep 1.2.2",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-param-passing-dep"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"solana-sdk 1.2.1",
"solana-sdk-bpf-test 1.2.1",
"solana-sdk 1.2.2",
"solana-sdk-bpf-test 1.2.2",
]
[[package]]
name = "solana-config-program"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.2.1",
"solana-sdk 1.2.2",
]
[[package]]
name = "solana-crate-features"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"backtrace 0.3.48 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1547,14 +1549,14 @@ dependencies = [
"reqwest 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-logger"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1563,30 +1565,30 @@ dependencies = [
[[package]]
name = "solana-measure"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-metrics 1.2.1",
"solana-sdk 1.2.1",
"solana-metrics 1.2.2",
"solana-sdk 1.2.2",
]
[[package]]
name = "solana-metrics"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.2.1",
"solana-sdk 1.2.2",
]
[[package]]
name = "solana-rayon-threadlimit"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1594,7 +1596,7 @@ dependencies = [
[[package]]
name = "solana-runtime"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bv 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1608,27 +1610,27 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-config-program 1.2.1",
"solana-logger 1.2.1",
"solana-measure 1.2.1",
"solana-metrics 1.2.1",
"solana-rayon-threadlimit 1.2.1",
"solana-sdk 1.2.1",
"solana-stake-program 1.2.1",
"solana-vote-program 1.2.1",
"solana-config-program 1.2.2",
"solana-logger 1.2.2",
"solana-measure 1.2.2",
"solana-metrics 1.2.2",
"solana-rayon-threadlimit 1.2.2",
"solana-sdk 1.2.2",
"solana-stake-program 1.2.2",
"solana-vote-program 1.2.2",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-sdk"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1637,71 +1639,71 @@ dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-crate-features 1.2.1",
"solana-logger 1.2.1",
"solana-sdk-macro 1.2.1",
"solana-crate-features 1.2.2",
"solana-logger 1.2.2",
"solana-sdk-macro 1.2.2",
"thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-sdk-bpf-test"
version = "1.2.1"
version = "1.2.2"
[[package]]
name = "solana-sdk-macro"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-stake-program"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-config-program 1.2.1",
"solana-metrics 1.2.1",
"solana-sdk 1.2.1",
"solana-vote-program 1.2.1",
"solana-config-program 1.2.2",
"solana-metrics 1.2.2",
"solana-sdk 1.2.2",
"solana-vote-program 1.2.2",
"thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-vote-program"
version = "1.2.1"
version = "1.2.2"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-metrics 1.2.1",
"solana-sdk 1.2.1",
"solana-metrics 1.2.2",
"solana-sdk 1.2.2",
"thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1749,22 +1751,22 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.29"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synstructure"
version = "0.12.3"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1802,9 +1804,9 @@ name = "thiserror-impl"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1860,7 +1862,7 @@ dependencies = [
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1969,7 +1971,7 @@ version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2030,7 +2032,7 @@ dependencies = [
"futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2134,7 +2136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro 0.2.63 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2143,12 +2145,12 @@ name = "wasm-bindgen-backend"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bumpalo 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.63 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2168,7 +2170,7 @@ name = "wasm-bindgen-macro"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro-support 0.2.63 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2177,9 +2179,9 @@ name = "wasm-bindgen-macro-support"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-backend 0.2.63 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.63 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2289,7 +2291,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
"checksum bumpalo 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6"
"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
"checksum bv 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
@@ -2299,12 +2301,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)" = "e450b8da92aa6f274e7c6437692f9f2ce6d701fb73bacfcf87897b3f89a4c20e"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
"checksum clear_on_drop 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c9cc5db465b294c3fa986d5bbb0f3017cd850bff6dd6c52f9ccff8b4d21b7b08"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum combine 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1645a65a99c7c8d345761f4b75a6ffe5be3b3b27a93ee731fccc5050ba6be97c"
"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
"checksum crossbeam-queue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ab6bffe714b6bb07e42f201352c34f51fefd355ace793f9e638ebd52d23f98d2"
"checksum crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
"checksum curve25519-dalek 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5"
@@ -2332,7 +2334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
"checksum futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum generic-array 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2664c2cf08049036f31015b04c6ac3671379a1d86f52ed2416893f16022deb"
"checksum generic-array 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
"checksum gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum gimli 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
@@ -2349,7 +2351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f"
"checksum hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08"
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
"checksum indexmap 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
@@ -2377,31 +2379,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
"checksum num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c8b15b261814f992e33760b1fca9fe8b693d8a65299f20c9901688636cfb746"
"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
"checksum object 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
"checksum paste 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "d53181dcd37421c08d3b69f887784956674d09c3f9a47a04fece2b130a5b346b"
"checksum paste-impl 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "05ca490fa1c034a71412b4d1edcb904ec5a0981a4426c9eb2128c0fda7a68d17"
"checksum paste 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "d508492eeb1e5c38ee696371bf7b9fc33c83d46a7d451606b96458fbbbdc2dec"
"checksum paste-impl 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "84f328a6a63192b333fce5fbb4be79db6758a4d518dfac6d54412f1492f72d32"
"checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum pin-project 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "edc93aeee735e60ecb40cf740eb319ff23eab1c5748abfdb5c180e4ce49f7791"
"checksum pin-project-internal 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40"
"checksum pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f"
"checksum pin-project 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e75373ff9037d112bb19bc61333a06a159eaeb217660dcfbea7d88e1db823919"
"checksum pin-project-internal 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "10b4b44893d3c370407a1d6a5cfde7c41ae0478e31c516c85f67eb3adc51be6d"
"checksum pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
"checksum proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
"checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
"checksum proc-macro-nested 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0afe1bd463b9e9ed51d0e0f0b50b6b146aec855c56fd182bb242388710a9b6de"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101"
"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
@@ -2417,7 +2419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1"
"checksum ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
"checksum scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abb2332cb595d33f7edd5700f4cbf94892e680c7f0ae56adab58a35190b66cb1"
@@ -2426,9 +2428,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
"checksum serde_bytes 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3bf487fbf5c6239d7ea2ff8b10cb6b811cd4b5080d1c2aeed1dec18753c06e10"
"checksum serde_bytes 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
"checksum serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
"checksum serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
"checksum serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
"checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
@@ -2440,8 +2442,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
"checksum subtle 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "bb37da98a55b1d08529362d9cbb863be17556873df2585904ab9d2bc951291d0"
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
"checksum syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
"checksum synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
"checksum thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344"

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-bpf-programs"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.1"
version = "1.2.2"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "README.md"
@@ -22,10 +22,10 @@ walkdir = "2"
bincode = "1.1.4"
byteorder = "1.3.2"
elf = "0.0.10"
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.2.1" }
solana-logger = { path = "../../logger", version = "1.2.1" }
solana-runtime = { path = "../../runtime", version = "1.2.1" }
solana-sdk = { path = "../../sdk", version = "1.2.1" }
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.2.2" }
solana-logger = { path = "../../logger", version = "1.2.2" }
solana-runtime = { path = "../../runtime", version = "1.2.2" }
solana-sdk = { path = "../../sdk", version = "1.2.2" }
solana_rbpf = "=0.1.28"
[[bench]]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-128bit"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.2.1" }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.2.2" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-128bit-dep"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-alloc"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-dep-crate"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,10 +13,10 @@ edition = "2018"
[dependencies]
byteorder = { version = "1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-dup-accounts"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-error-handling"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,11 +14,11 @@ edition = "2018"
[dependencies]
num-derive = "0.2"
num-traits = "0.2"
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
thiserror = "1.0"
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-external-spend"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-invoke"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,8 +13,8 @@ edition = "2018"
[dependencies]
solana-bpf-rust-invoked = { path = "../invoked"}
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-invoked"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-iter"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-many-args"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.2.1" }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.2.2" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-many-args-dep"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-noop"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-panic"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-param-passing"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.2.1" }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.2.2" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-param-passing-dep"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-sysval"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.2.1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.2.2", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.1" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.2.2" }
[features]
program = ["solana-sdk/program"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-loader-program"
version = "1.2.1"
version = "1.2.2"
description = "Solana BPF loader"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,9 +15,9 @@ jemalloc-sys = { version = "0.3.2", features = ["disable_initial_exec_tls"] }
log = "0.4.8"
num-derive = { version = "0.3" }
num-traits = { version = "0.2" }
solana-logger = { path = "../../logger", version = "1.2.1" }
solana-runtime = { path = "../../runtime", version = "1.2.1" }
solana-sdk = { path = "../../sdk", version = "1.2.1" }
solana-logger = { path = "../../logger", version = "1.2.2" }
solana-runtime = { path = "../../runtime", version = "1.2.2" }
solana-sdk = { path = "../../sdk", version = "1.2.2" }
solana_rbpf = "=0.1.28"
thiserror = "1.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-btc-spv-program"
version = "1.2.1"
version = "1.2.2"
description = "Solana Bitcoin spv parsing program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,7 +15,7 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.110"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.2.1"}
solana-sdk = { path = "../../sdk", version = "1.2.2"}
hex = "0.4.2"
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "btc_spv_bin"
version = "1.2.1"
version = "1.2.2"
description = "Solana Bitcoin spv parsing program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-budget-program"
version = "1.2.1"
version = "1.2.2"
description = "Solana Budget program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,11 +16,11 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.110"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.2.1" }
solana-sdk = { path = "../../sdk", version = "1.2.2" }
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.2.1" }
solana-runtime = { path = "../../runtime", version = "1.2.2" }
[lib]
crate-type = ["lib", "cdylib"]

Some files were not shown because too many files have changed in this diff Show More