Compare commits

..

18 Commits

Author SHA1 Message Date
mergify[bot]
4b5a05bf38 limits number of crds values associated with a pubkey (bp #14467) (#14490)
* limits number of crds values associated with a pubkey (#14467)

(cherry picked from commit 766195dded)

* updates smallvec

Co-authored-by: behzad nouri <behzadnouri@gmail.com>
2021-01-08 21:52:40 +00:00
mergify[bot]
7dd7141307 Suppress cargo audit failure for difference crate (bp #14488) (#14493)
* Suppress cargo audit failure for `difference` crate, there's no newer crate to upgrade to yet

(cherry picked from commit 3eaa826ad9)

* Bump smallvec version

(cherry picked from commit 21a0a83543)

Co-authored-by: Michael Vines <mvines@gmail.com>
2021-01-08 21:52:28 +00:00
mergify[bot]
e5175c843d Add buffer authority to upgradeable loader (#14482) (#14485)
(cherry picked from commit 58487c6360)

Co-authored-by: Jack May <jack@solana.com>
2021-01-08 18:54:11 +00:00
mergify[bot]
d5ff64b0d7 docs: Validator tuning improvements (bp #14478) (#14480)
* docs: wrap lines

(cherry picked from commit 140642ea21)

* docs: Prefer `dd` to `fallocate` when creating swap file

(cherry picked from commit c035f2a745)

* docs: Add RUST_LOG explainer

(cherry picked from commit 30038a8849)

Co-authored-by: Trent Nelson <trent@solana.com>
2021-01-07 19:41:45 +00:00
mergify[bot]
0fbdc7e152 Enable program upgrades via CPI (#14449) (#14469)
(cherry picked from commit 5eacc5d08d)

Co-authored-by: Jack May <jack@solana.com>
2021-01-06 23:45:10 +00:00
Tyera Eulberg
49aca9ecd8 Add fixed tick rate adjustment (#14447) (#14464)
Co-authored-by: sakridge <sakridge@gmail.com>
2021-01-06 21:44:06 +00:00
mergify[bot]
fcc147b4f2 Gate cpi program account passing (#14443) (#14446)
(cherry picked from commit a8b5a32b50)

Co-authored-by: Jack May <jack@solana.com>
2021-01-06 19:20:49 +00:00
mergify[bot]
c455d1b1c5 Enable program-id account index for supply calculations (#14444) (#14456)
* Enable program-id account index for supply calculations

* Fixup comments

(cherry picked from commit ce1766d798)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2021-01-06 04:04:44 +00:00
mergify[bot]
e9b29fc697 Bump serum-dex pegged commit (#14448) (#14454)
(cherry picked from commit d2b0fd973f)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2021-01-05 19:17:03 -07:00
Ryo Onodera
fdea6fad26 Save 7G mem on mainnet fixing AccIndex overalloc. (#14435)
(cherry picked from commit c9df6134fa)
2021-01-05 17:55:44 -08:00
mergify[bot]
a4bc31341a Lower recycle store count (#14429) (#14442)
Too many stores can cause swap usage which
is detrimental to account store times.

(cherry picked from commit 53d65009a0)

Co-authored-by: sakridge <sakridge@gmail.com>
2021-01-05 21:39:31 +00:00
mergify[bot]
4af797c0a2 Introduce rpc url monikers for cli (#14409) (#14433)
* Introduce rpc url monikers for cli

* Use https:// and support initials as well

(cherry picked from commit 54a5876c48)

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
2021-01-05 12:16:11 +00:00
mergify[bot]
a1e06df4a8 Add validator --account-index docs (#14418) (#14428)
(cherry picked from commit efd9b769fc)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2021-01-05 03:06:15 +00:00
mergify[bot]
1f2480fd9f Fix pre-merge old name in the docs (#14425) (#14427)
(cherry picked from commit 974eb6e1ef)

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
2021-01-05 02:55:02 +00:00
mergify[bot]
8587bd0d69 Improve solana catchup (#14313) (#14424)
* Improve solana catchup

* Overidable port, retry, args error clean up

* print cleanup

* Reduce diff

* Tweak warns a bit

(cherry picked from commit aa4da339ff)

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
2021-01-05 02:34:53 +00:00
mergify[bot]
0063a58e95 Upgradeable programs needs program account's address as program id (#14417) (#14420)
(cherry picked from commit 0619805806)

Co-authored-by: Jack May <jack@solana.com>
2021-01-04 23:00:36 +00:00
mergify[bot]
9aeb3bc5d6 docs: Use "msg!" instead of "info!" (#14411) (#14416)
* docs: Use "msg!" instead of "info!"

* Update docs/src/developing/deployed-programs/developing-rust.md

Co-authored-by: Michael Vines <mvines@gmail.com>

* Fix typo / format

Co-authored-by: Michael Vines <mvines@gmail.com>
(cherry picked from commit a41b5137f6)

Co-authored-by: Jon Cinque <jon.cinque@gmail.com>
2021-01-04 20:02:09 +00:00
Michael Vines
97665b977e Bump version to v1.5.2 2021-01-04 06:44:52 +00:00
146 changed files with 3494 additions and 1510 deletions

293
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-account-decoder"
version = "1.5.1"
version = "1.5.2"
description = "Solana account decoder"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,10 +18,10 @@ lazy_static = "1.4.0"
serde = "1.0.112"
serde_derive = "1.0.103"
serde_json = "1.0.56"
solana-config-program = { path = "../programs/config", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-config-program = { path = "../programs/config", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
spl-token-v2-0 = { package = "spl-token", version = "=3.0.1", features = ["no-entrypoint"] }
thiserror = "1.0"
zstd = "0.5.1"

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-banks-client"
version = "1.5.1"
version = "1.5.2"
description = "Solana banks client"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,15 +12,15 @@ edition = "2018"
bincode = "1.3.1"
futures = "0.3"
mio = "0.7.6"
solana-banks-interface = { path = "../banks-interface", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-banks-interface = { path = "../banks-interface", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
tarpc = { version = "0.23.0", features = ["full"] }
tokio = { version = "0.3.5", features = ["full"] }
tokio-serde = { version = "0.6", features = ["bincode"] }
[dev-dependencies]
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-banks-server = { path = "../banks-server", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-banks-server = { path = "../banks-server", version = "1.5.2" }
[lib]
crate-type = ["lib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-banks-interface"
version = "1.5.1"
version = "1.5.2"
description = "Solana banks RPC interface"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,7 +11,7 @@ edition = "2018"
[dependencies]
mio = "0.7.6"
serde = { version = "1.0.112", features = ["derive"] }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
tarpc = { version = "0.23.0", features = ["full"] }
[dev-dependencies]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-banks-server"
version = "1.5.1"
version = "1.5.2"
description = "Solana banks server"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,10 +13,10 @@ bincode = "1.3.1"
futures = "0.3"
log = "0.4.11"
mio = "0.7.6"
solana-banks-interface = { path = "../banks-interface", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-metrics = { path = "../metrics", version = "1.5.1" }
solana-banks-interface = { path = "../banks-interface", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-metrics = { path = "../metrics", version = "1.5.2" }
tarpc = { version = "0.23.0", features = ["full"] }
tokio = { version = "0.3", features = ["full"] }
tokio-serde = { version = "0.6", features = ["bincode"] }

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-bench-exchange"
version = "1.5.1"
version = "1.5.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.4.0"
serde_json = "1.0.56"
serde_yaml = "0.8.13"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-core = { path = "../core", version = "1.5.1" }
solana-genesis = { path = "../genesis", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-faucet = { path = "../faucet", version = "1.5.1" }
solana-exchange-program = { path = "../programs/exchange", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-metrics = { path = "../metrics", version = "1.5.1" }
solana-net-utils = { path = "../net-utils", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-core = { path = "../core", version = "1.5.2" }
solana-genesis = { path = "../genesis", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-faucet = { path = "../faucet", version = "1.5.2" }
solana-exchange-program = { path = "../programs/exchange", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-metrics = { path = "../metrics", version = "1.5.2" }
solana-net-utils = { path = "../net-utils", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
[dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "1.5.1" }
solana-local-cluster = { path = "../local-cluster", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

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

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-bench-tps"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,23 +15,23 @@ log = "0.4.11"
rayon = "1.4.0"
serde_json = "1.0.56"
serde_yaml = "0.8.13"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-core = { path = "../core", version = "1.5.1" }
solana-genesis = { path = "../genesis", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-faucet = { path = "../faucet", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-metrics = { path = "../metrics", version = "1.5.1" }
solana-measure = { path = "../measure", version = "1.5.1" }
solana-net-utils = { path = "../net-utils", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-core = { path = "../core", version = "1.5.2" }
solana-genesis = { path = "../genesis", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-faucet = { path = "../faucet", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-metrics = { path = "../metrics", version = "1.5.2" }
solana-measure = { path = "../measure", version = "1.5.2" }
solana-net-utils = { path = "../net-utils", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
[dev-dependencies]
serial_test = "0.4.0"
serial_test_derive = "0.4.0"
solana-local-cluster = { path = "../local-cluster", version = "1.5.1" }
solana-local-cluster = { path = "../local-cluster", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -78,6 +78,12 @@ cargo_audit_ignores=(
#
# Blocked on multiple crates updating `time` to >= 0.2.23
--ignore RUSTSEC-2020-0071
# difference is unmaintained
#
# Blocked on predicates v1.0.6 removing its dependency on `difference`
--ignore RUSTSEC-2020-0095
)
_ scripts/cargo-for-all-lock-files.sh +"$rust_stable" audit "${cargo_audit_ignores[@]}"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-clap-utils"
version = "1.5.1"
version = "1.5.2"
description = "Solana utilities for the clap"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
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.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
thiserror = "1.0.21"
tiny-bip39 = "0.7.0"
url = "2.1.0"

View File

@@ -148,6 +148,33 @@ where
}
}
pub fn is_url_or_moniker<T>(string: T) -> Result<(), String>
where
T: AsRef<str> + Display,
{
match url::Url::parse(&normalize_to_url_if_moniker(string.as_ref())) {
Ok(url) => {
if url.has_host() {
Ok(())
} else {
Err("no host provided".to_string())
}
}
Err(err) => Err(format!("{}", err)),
}
}
pub fn normalize_to_url_if_moniker(url_or_moniker: &str) -> String {
match url_or_moniker {
"m" | "mainnet-beta" => "https://api.mainnet-beta.solana.com",
"t" | "testnet" => "https://testnet.solana.com",
"d" | "devnet" => "https://devnet.solana.com",
"l" | "localhost" => "http://localhost:8899",
url => url,
}
.to_string()
}
pub fn is_epoch<T>(epoch: T) -> Result<(), String>
where
T: AsRef<str> + Display,

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-cli-config"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.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.foundation>"]
edition = "2018"
name = "solana-cli-output"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -17,13 +17,13 @@ indicatif = "0.15.0"
serde = "1.0.112"
serde_derive = "1.0.103"
serde_json = "1.0.56"
solana-account-decoder = { path = "../account-decoder", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-account-decoder = { path = "../account-decoder", version = "1.5.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-cli"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -27,29 +27,29 @@ reqwest = { version = "0.10.8", default-features = false, features = ["blocking"
serde = "1.0.112"
serde_derive = "1.0.103"
serde_json = "1.0.56"
solana-account-decoder = { path = "../account-decoder", version = "1.5.1" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-cli-config = { path = "../cli-config", version = "1.5.1" }
solana-cli-output = { path = "../cli-output", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-config-program = { path = "../programs/config", version = "1.5.1" }
solana-faucet = { path = "../faucet", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-net-utils = { path = "../net-utils", version = "1.5.1" }
solana-account-decoder = { path = "../account-decoder", version = "1.5.2" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.5.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-cli-config = { path = "../cli-config", version = "1.5.2" }
solana-cli-output = { path = "../cli-output", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-config-program = { path = "../programs/config", version = "1.5.2" }
solana-faucet = { path = "../faucet", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-net-utils = { path = "../net-utils", version = "1.5.2" }
solana_rbpf = "=0.2.2"
solana-remote-wallet = { path = "../remote-wallet", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
thiserror = "1.0.21"
tiny-bip39 = "0.7.0"
url = "2.1.1"
[dev-dependencies]
solana-core = { path = "../core", version = "1.5.1" }
solana-core = { path = "../core", version = "1.5.2" }
tempfile = "3.1.0"
[[bin]]

View File

@@ -75,9 +75,11 @@ pub const DEFAULT_RPC_TIMEOUT_SECONDS: &str = "30";
pub enum CliCommand {
// Cluster Query Commands
Catchup {
node_pubkey: Pubkey,
node_pubkey: Option<Pubkey>,
node_json_rpc_url: Option<String>,
follow: bool,
our_localhost_port: Option<u16>,
log: bool,
},
ClusterDate,
ClusterVersion,
@@ -463,11 +465,12 @@ impl CliConfig<'_> {
json_rpc_cmd_url: &str,
json_rpc_cfg_url: &str,
) -> (SettingType, String) {
Self::first_nonempty_setting(vec![
let (setting_type, url_or_moniker) = Self::first_nonempty_setting(vec![
(SettingType::Explicit, json_rpc_cmd_url.to_string()),
(SettingType::Explicit, json_rpc_cfg_url.to_string()),
(SettingType::SystemDefault, Self::default_json_rpc_url()),
])
]);
(setting_type, normalize_to_url_if_moniker(&url_or_moniker))
}
pub fn compute_keypair_path_setting(
@@ -1138,7 +1141,17 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
node_pubkey,
node_json_rpc_url,
follow,
} => process_catchup(&rpc_client, config, node_pubkey, node_json_rpc_url, *follow),
our_localhost_port,
log,
} => process_catchup(
&rpc_client,
config,
*node_pubkey,
node_json_rpc_url.clone(),
*follow,
*our_localhost_port,
*log,
),
CliCommand::ClusterDate => process_cluster_date(&rpc_client, config),
CliCommand::ClusterVersion => process_cluster_version(&rpc_client, config),
CliCommand::CreateAddressWithSeed {
@@ -2652,7 +2665,7 @@ mod tests {
let program_id = json
.as_object()
.unwrap()
.get("programId")
.get("ProgramId")
.unwrap()
.as_str()
.unwrap();

View File

@@ -41,6 +41,7 @@ use solana_sdk::{
message::Message,
native_token::lamports_to_sol,
pubkey::{self, Pubkey},
rpc_port::DEFAULT_RPC_PORT_STR,
signature::Signature,
system_instruction, system_program,
sysvar::{
@@ -88,14 +89,14 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.arg(
pubkey!(Arg::with_name("node_pubkey")
.index(1)
.value_name("VALIDATOR_PUBKEY")
.required(true),
.value_name("OUR_VALIDATOR_PUBKEY")
.required(false),
"Identity pubkey of the validator"),
)
.arg(
Arg::with_name("node_json_rpc_url")
.index(2)
.value_name("URL")
.value_name("OUR_URL")
.takes_value(true)
.validator(is_url)
.help("JSON RPC URL for validator, which is useful for validators with a private RPC service")
@@ -106,6 +107,21 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.takes_value(false)
.help("Continue reporting progress even after the validator has caught up"),
)
.arg(
Arg::with_name("our_localhost")
.long("our-localhost")
.takes_value(false)
.value_name("PORT")
.default_value(&DEFAULT_RPC_PORT_STR)
.validator(is_port)
.help("Guess Identity pubkey and validator rpc node assuming local (possibly private) validator"),
)
.arg(
Arg::with_name("log")
.long("log")
.takes_value(false)
.help("Don't update the progress inplace; instead show updates with its own new lines"),
)
.arg(commitment_arg()),
)
.subcommand(
@@ -379,14 +395,31 @@ pub fn parse_catchup(
matches: &ArgMatches<'_>,
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
) -> Result<CliCommandInfo, CliError> {
let node_pubkey = pubkey_of_signer(matches, "node_pubkey", wallet_manager)?.unwrap();
let node_pubkey = pubkey_of_signer(matches, "node_pubkey", wallet_manager)?;
let mut our_localhost_port = value_t!(matches, "our_localhost", u16).ok();
// if there is no explicitly specified --our-localhost,
// disable the guess mode (= our_localhost_port)
if matches.occurrences_of("our_localhost") == 0 {
our_localhost_port = None
}
let node_json_rpc_url = value_t!(matches, "node_json_rpc_url", String).ok();
// requirement of node_pubkey is relaxed only if our_localhost_port
if our_localhost_port.is_none() && node_pubkey.is_none() {
return Err(CliError::BadParameter(
"OUR_VALIDATOR_PUBKEY (and possibly OUR_URL) must be specified \
unless --our-localhost is given"
.into(),
));
}
let follow = matches.is_present("follow");
let log = matches.is_present("log");
Ok(CliCommandInfo {
command: CliCommand::Catchup {
node_pubkey,
node_json_rpc_url,
follow,
our_localhost_port,
log,
},
signers: vec![],
})
@@ -566,38 +599,76 @@ pub fn parse_transaction_history(
pub fn process_catchup(
rpc_client: &RpcClient,
config: &CliConfig,
node_pubkey: &Pubkey,
node_json_rpc_url: &Option<String>,
node_pubkey: Option<Pubkey>,
mut node_json_rpc_url: Option<String>,
follow: bool,
our_localhost_port: Option<u16>,
log: bool,
) -> ProcessResult {
let sleep_interval = 5;
let progress_bar = new_spinner_progress_bar();
progress_bar.set_message("Connecting...");
let node_client = if let Some(node_json_rpc_url) = node_json_rpc_url {
RpcClient::new(node_json_rpc_url.to_string())
} else {
let rpc_addr = loop {
let cluster_nodes = rpc_client.get_cluster_nodes()?;
if let Some(contact_info) = cluster_nodes
.iter()
.find(|contact_info| contact_info.pubkey == node_pubkey.to_string())
{
if let Some(rpc_addr) = contact_info.rpc {
break rpc_addr;
}
progress_bar.set_message(&format!("RPC service not found for {}", node_pubkey));
} else {
progress_bar.set_message(&format!(
"Contact information not found for {}",
node_pubkey
));
}
sleep(Duration::from_secs(sleep_interval as u64));
};
if let Some(our_localhost_port) = our_localhost_port {
let gussed_default = Some(format!("http://localhost:{}", our_localhost_port));
if node_json_rpc_url.is_some() && node_json_rpc_url != gussed_default {
// go to new line to leave this message on console
println!(
"Prefering explicitly given rpc ({}) as us, \
although --our-localhost is given\n",
node_json_rpc_url.as_ref().unwrap()
);
} else {
node_json_rpc_url = gussed_default;
}
}
RpcClient::new_socket(rpc_addr)
let (node_client, node_pubkey) = if our_localhost_port.is_some() {
let client = RpcClient::new(node_json_rpc_url.unwrap());
let guessed_default = Some(client.get_identity()?);
(
client,
(if node_pubkey.is_some() && node_pubkey != guessed_default {
// go to new line to leave this message on console
println!(
"Prefering explicitly given node pubkey ({}) as us, \
although --our-localhost is given\n",
node_pubkey.unwrap()
);
node_pubkey
} else {
guessed_default
})
.unwrap(),
)
} else if let Some(node_pubkey) = node_pubkey {
if let Some(node_json_rpc_url) = node_json_rpc_url {
(RpcClient::new(node_json_rpc_url), node_pubkey)
} else {
let rpc_addr = loop {
let cluster_nodes = rpc_client.get_cluster_nodes()?;
if let Some(contact_info) = cluster_nodes
.iter()
.find(|contact_info| contact_info.pubkey == node_pubkey.to_string())
{
if let Some(rpc_addr) = contact_info.rpc {
break rpc_addr;
}
progress_bar.set_message(&format!("RPC service not found for {}", node_pubkey));
} else {
progress_bar.set_message(&format!(
"Contact information not found for {}",
node_pubkey
));
}
sleep(Duration::from_secs(sleep_interval as u64));
};
(RpcClient::new_socket(rpc_addr), node_pubkey)
}
} else {
unreachable!()
};
let reported_node_pubkey = loop {
@@ -614,7 +685,7 @@ pub fn process_catchup(
}
};
if reported_node_pubkey != *node_pubkey {
if reported_node_pubkey != node_pubkey {
return Err(format!(
"The identity reported by node RPC URL does not match. Expected: {:?}. Reported: {:?}",
node_pubkey, reported_node_pubkey
@@ -622,15 +693,41 @@ pub fn process_catchup(
.into());
}
if rpc_client.get_identity()? == *node_pubkey {
if rpc_client.get_identity()? == node_pubkey {
return Err("Both RPC URLs reference the same node, unable to monitor for catchup. Try a different --url".into());
}
let mut previous_rpc_slot = std::u64::MAX;
let mut previous_slot_distance = 0;
let mut retry_count = 0;
let max_retry_count = 5;
let mut get_slot_while_retrying = |client: &RpcClient| {
loop {
match client.get_slot_with_commitment(config.commitment) {
Ok(r) => {
retry_count = 0;
return Ok(r);
}
Err(e) => {
if retry_count >= max_retry_count {
return Err(e);
}
retry_count += 1;
if log {
// go to new line to leave this message on console
println!("Retrying({}/{}): {}\n", retry_count, max_retry_count, e);
}
sleep(Duration::from_secs(1));
}
};
}
};
loop {
let rpc_slot = rpc_client.get_slot_with_commitment(config.commitment)?;
let node_slot = node_client.get_slot_with_commitment(config.commitment)?;
// humbly retry; the reference node (rpc_client) could be spotty,
// especially if pointing to api.meinnet-beta.solana.com at times
let rpc_slot = get_slot_while_retrying(rpc_client)?;
let node_slot = get_slot_while_retrying(&node_client)?;
if !follow && node_slot > std::cmp::min(previous_rpc_slot, rpc_slot) {
progress_bar.finish_and_clear();
return Ok(format!(
@@ -653,15 +750,21 @@ pub fn process_catchup(
};
progress_bar.set_message(&format!(
"{} slots behind (us:{} them:{}){}",
slot_distance,
"{} slot(s) {} (us:{} them:{}){}",
slot_distance.abs(),
if slot_distance >= 0 {
"behind"
} else {
"ahead"
},
node_slot,
rpc_slot,
if slot_distance == 0 || previous_rpc_slot == std::u64::MAX {
"".to_string()
} else {
format!(
", {} at {:.1} slots/second{}",
", {} node is {} at {:.1} slots/second{}",
if slot_distance >= 0 { "our" } else { "their" },
if slots_per_second < 0.0 {
"falling behind"
} else {
@@ -670,8 +773,11 @@ pub fn process_catchup(
slots_per_second,
time_remaining
)
}
},
));
if log {
println!();
}
sleep(Duration::from_secs(sleep_interval as u64));
previous_rpc_slot = rpc_slot;

View File

@@ -7,7 +7,7 @@ use console::style;
use solana_clap_utils::{
commitment::COMMITMENT_ARG,
input_parsers::commitment_of,
input_validators::is_url,
input_validators::{is_url, is_url_or_moniker},
keypair::{CliSigners, DefaultSigner, SKIP_SEED_PHRASE_VALIDATION_ARG},
DisplayError,
};
@@ -246,11 +246,14 @@ fn main() -> Result<(), Box<dyn error::Error>> {
Arg::with_name("json_rpc_url")
.short("u")
.long("url")
.value_name("URL")
.value_name("URL_OR_MONIKER")
.takes_value(true)
.global(true)
.validator(is_url)
.help("JSON RPC URL for the solana cluster"),
.validator(is_url_or_moniker)
.help(
"URL for Solana's JSON RPC or moniker (or their first letter): \
[mainnet-beta, testnet, devnet, localhost]",
),
)
.arg(
Arg::with_name("websocket_url")

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,7 @@ use solana_client::rpc_client::RpcClient;
use solana_core::test_validator::TestValidator;
use solana_faucet::faucet::run_local_faucet;
use solana_sdk::{
account_utils::StateMut,
bpf_loader,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
commitment_config::CommitmentConfig,
@@ -64,7 +65,7 @@ fn test_cli_program_deploy_non_upgradeable() {
let program_id_str = json
.as_object()
.unwrap()
.get("programId")
.get("ProgramId")
.unwrap()
.as_str()
.unwrap();
@@ -191,13 +192,15 @@ fn test_cli_program_deploy_no_authority() {
// Deploy a program with no authority
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: None,
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: None,
upgrade_authority_pubkey: None,
is_final: false,
max_len: None,
});
let response = process_command(&config);
@@ -205,7 +208,7 @@ fn test_cli_program_deploy_no_authority() {
let program_id_str = json
.as_object()
.unwrap()
.get("programId")
.get("ProgramId")
.unwrap()
.as_str()
.unwrap();
@@ -214,13 +217,15 @@ fn test_cli_program_deploy_no_authority() {
// Attempt to upgrade the program
config.signers = vec![&keypair, &upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: Some(program_id),
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
is_final: false,
max_len: None,
});
process_command(&config).unwrap_err();
@@ -275,27 +280,29 @@ fn test_cli_program_deploy_with_authority() {
let program_keypair = Keypair::new();
config.signers = vec![&keypair, &upgrade_authority, &program_keypair];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: Some(2),
program_pubkey: Some(program_keypair.pubkey()),
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
is_final: false,
max_len: Some(max_len),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let program_id_str = json
let program_pubkey_str = json
.as_object()
.unwrap()
.get("programId")
.get("ProgramId")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
program_keypair.pubkey(),
Pubkey::from_str(&program_id_str).unwrap()
Pubkey::from_str(&program_pubkey_str).unwrap()
);
let program_account = rpc_client
.get_account_with_commitment(&program_keypair.pubkey(), CommitmentConfig::recent())
@@ -328,27 +335,29 @@ fn test_cli_program_deploy_with_authority() {
// Deploy the upgradeable program
config.signers = vec![&keypair, &upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: None,
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
is_final: false,
max_len: Some(max_len),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let program_id_str = json
let program_pubkey_str = json
.as_object()
.unwrap()
.get("programId")
.get("ProgramId")
.unwrap()
.as_str()
.unwrap();
let program_id = Pubkey::from_str(&program_id_str).unwrap();
let program_pubkey = Pubkey::from_str(&program_pubkey_str).unwrap();
let program_account = rpc_client
.get_account_with_commitment(&program_id, CommitmentConfig::recent())
.get_account_with_commitment(&program_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
@@ -356,7 +365,7 @@ fn test_cli_program_deploy_with_authority() {
assert_eq!(program_account.owner, bpf_loader_upgradeable::id());
assert_eq!(program_account.executable, true);
let (programdata_pubkey, _) =
Pubkey::find_program_address(&[program_id.as_ref()], &bpf_loader_upgradeable::id());
Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id());
let programdata_account = rpc_client
.get_account_with_commitment(&programdata_pubkey, CommitmentConfig::recent())
.unwrap()
@@ -376,27 +385,20 @@ fn test_cli_program_deploy_with_authority() {
// Upgrade the program
config.signers = vec![&keypair, &upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: Some(program_id),
program_pubkey: Some(program_pubkey),
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
is_final: false,
max_len: Some(max_len),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let program_id_str = json
.as_object()
.unwrap()
.get("programId")
.unwrap()
.as_str()
.unwrap();
let program_id = Pubkey::from_str(&program_id_str).unwrap();
process_command(&config).unwrap();
let program_account = rpc_client
.get_account_with_commitment(&program_id, CommitmentConfig::recent())
.get_account_with_commitment(&program_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
@@ -404,7 +406,7 @@ fn test_cli_program_deploy_with_authority() {
assert_eq!(program_account.owner, bpf_loader_upgradeable::id());
assert_eq!(program_account.executable, true);
let (programdata_pubkey, _) =
Pubkey::find_program_address(&[program_id.as_ref()], &bpf_loader_upgradeable::id());
Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id());
let programdata_account = rpc_client
.get_account_with_commitment(&programdata_pubkey, CommitmentConfig::recent())
.unwrap()
@@ -425,7 +427,7 @@ fn test_cli_program_deploy_with_authority() {
let new_upgrade_authority = Keypair::new();
config.signers = vec![&keypair, &upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::SetUpgradeAuthority {
program: program_id,
program_pubkey,
upgrade_authority_index: Some(1),
new_upgrade_authority: Some(new_upgrade_authority.pubkey()),
});
@@ -434,7 +436,7 @@ fn test_cli_program_deploy_with_authority() {
let new_upgrade_authority_str = json
.as_object()
.unwrap()
.get("UpgradeAuthority")
.get("Authority")
.unwrap()
.as_str()
.unwrap();
@@ -446,27 +448,20 @@ fn test_cli_program_deploy_with_authority() {
// Upgrade with new authority
config.signers = vec![&keypair, &new_upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: Some(program_id),
program_pubkey: Some(program_pubkey),
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(new_upgrade_authority.pubkey()),
is_final: false,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let program_id_str = json
.as_object()
.unwrap()
.get("programId")
.unwrap()
.as_str()
.unwrap();
let program_id = Pubkey::from_str(&program_id_str).unwrap();
process_command(&config).unwrap();
let program_account = rpc_client
.get_account_with_commitment(&program_id, CommitmentConfig::recent())
.get_account_with_commitment(&program_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
@@ -474,7 +469,7 @@ fn test_cli_program_deploy_with_authority() {
assert_eq!(program_account.owner, bpf_loader_upgradeable::id());
assert_eq!(program_account.executable, true);
let (programdata_pubkey, _) =
Pubkey::find_program_address(&[program_id.as_ref()], &bpf_loader_upgradeable::id());
Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id());
let programdata_account = rpc_client
.get_account_with_commitment(&programdata_pubkey, CommitmentConfig::recent())
.unwrap()
@@ -494,7 +489,7 @@ fn test_cli_program_deploy_with_authority() {
// Set no authority
config.signers = vec![&keypair, &new_upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::SetUpgradeAuthority {
program: program_id,
program_pubkey,
upgrade_authority_index: Some(1),
new_upgrade_authority: None,
});
@@ -503,7 +498,7 @@ fn test_cli_program_deploy_with_authority() {
let new_upgrade_authority_str = json
.as_object()
.unwrap()
.get("UpgradeAuthority")
.get("Authority")
.unwrap()
.as_str()
.unwrap();
@@ -512,14 +507,452 @@ fn test_cli_program_deploy_with_authority() {
// Upgrade with no authority
config.signers = vec![&keypair, &new_upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: pathbuf.to_str().unwrap().to_string(),
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: Some(program_id),
program_pubkey: Some(program_pubkey),
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(new_upgrade_authority.pubkey()),
is_final: false,
max_len: None,
});
process_command(&config).unwrap_err();
// deploy with finality
config.signers = vec![&keypair, &new_upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: None,
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(new_upgrade_authority.pubkey()),
is_final: true,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let program_pubkey_str = json
.as_object()
.unwrap()
.get("ProgramId")
.unwrap()
.as_str()
.unwrap();
let program_pubkey = Pubkey::from_str(&program_pubkey_str).unwrap();
let (programdata_pubkey, _) =
Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id());
let programdata_account = rpc_client
.get_account_with_commitment(&programdata_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
if let UpgradeableLoaderState::ProgramData {
slot: _,
upgrade_authority_address,
} = programdata_account.state().unwrap()
{
assert_eq!(upgrade_authority_address, None);
} else {
panic!("not a buffer account");
}
}
#[test]
fn test_cli_program_write_buffer() {
solana_logger::setup();
let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
pathbuf.push("tests");
pathbuf.push("fixtures");
pathbuf.push("noop");
pathbuf.set_extension("so");
let mint_keypair = Keypair::new();
let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey());
let (sender, receiver) = channel();
run_local_faucet(mint_keypair, sender, None);
let faucet_addr = receiver.recv().unwrap();
let rpc_client = RpcClient::new(test_validator.rpc_url());
let mut file = File::open(pathbuf.to_str().unwrap()).unwrap();
let mut program_data = Vec::new();
file.read_to_end(&mut program_data).unwrap();
let max_len = program_data.len();
let minimum_balance_for_buffer = rpc_client
.get_minimum_balance_for_rent_exemption(
UpgradeableLoaderState::programdata_len(max_len).unwrap(),
)
.unwrap();
let minimum_balance_for_buffer_default = rpc_client
.get_minimum_balance_for_rent_exemption(
UpgradeableLoaderState::programdata_len(max_len * 2).unwrap(),
)
.unwrap();
let mut config = CliConfig::recent_for_tests();
let keypair = Keypair::new();
config.json_rpc_url = test_validator.rpc_url();
config.signers = vec![&keypair];
config.command = CliCommand::Airdrop {
faucet_host: None,
faucet_port: faucet_addr.port(),
pubkey: None,
lamports: 100 * minimum_balance_for_buffer,
};
process_command(&config).unwrap();
// Write a buffer with default params
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: None,
is_final: false,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer")
.unwrap()
.as_str()
.unwrap();
let new_buffer_pubkey = Pubkey::from_str(&buffer_pubkey_str).unwrap();
let buffer_account = rpc_client
.get_account_with_commitment(&new_buffer_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
assert_eq!(buffer_account.lamports, minimum_balance_for_buffer_default);
assert_eq!(buffer_account.owner, bpf_loader_upgradeable::id());
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(keypair.pubkey()));
} else {
panic!("not a buffer account");
}
assert_eq!(
buffer_account.data[UpgradeableLoaderState::buffer_data_offset().unwrap()..],
program_data[..]
);
// Specify buffer keypair and max_len
let buffer_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: None,
is_final: false,
max_len: Some(max_len),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
buffer_keypair.pubkey(),
Pubkey::from_str(&buffer_pubkey_str).unwrap()
);
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_keypair.pubkey(), CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
assert_eq!(buffer_account.lamports, minimum_balance_for_buffer);
assert_eq!(buffer_account.owner, bpf_loader_upgradeable::id());
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(keypair.pubkey()));
} else {
panic!("not a buffer account");
}
assert_eq!(
buffer_account.data[UpgradeableLoaderState::buffer_data_offset().unwrap()..],
program_data[..]
);
// Specify buffer authority
let buffer_keypair = Keypair::new();
let authority_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair, &authority_keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: Some(2),
is_final: false,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
buffer_keypair.pubkey(),
Pubkey::from_str(&buffer_pubkey_str).unwrap()
);
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_keypair.pubkey(), CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
assert_eq!(buffer_account.lamports, minimum_balance_for_buffer_default);
assert_eq!(buffer_account.owner, bpf_loader_upgradeable::id());
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(authority_keypair.pubkey()));
} else {
panic!("not a buffer account");
}
assert_eq!(
buffer_account.data[UpgradeableLoaderState::buffer_data_offset().unwrap()..],
program_data[..]
);
// Specify authority only
let buffer_keypair = Keypair::new();
let authority_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair, &authority_keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(2),
is_final: false,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer")
.unwrap()
.as_str()
.unwrap();
let buffer_pubkey = Pubkey::from_str(&buffer_pubkey_str).unwrap();
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
assert_eq!(buffer_account.lamports, minimum_balance_for_buffer_default);
assert_eq!(buffer_account.owner, bpf_loader_upgradeable::id());
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(authority_keypair.pubkey()));
} else {
panic!("not a buffer account");
}
assert_eq!(
buffer_account.data[UpgradeableLoaderState::buffer_data_offset().unwrap()..],
program_data[..]
);
// Specify final
let buffer_keypair = Keypair::new();
let authority_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair, &authority_keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(2),
is_final: true,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer")
.unwrap()
.as_str()
.unwrap();
let buffer_pubkey = Pubkey::from_str(&buffer_pubkey_str).unwrap();
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_pubkey, CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, None);
} else {
panic!("not a buffer account");
}
}
#[test]
fn test_cli_program_set_buffer_authority() {
solana_logger::setup();
let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
pathbuf.push("tests");
pathbuf.push("fixtures");
pathbuf.push("noop");
pathbuf.set_extension("so");
let mint_keypair = Keypair::new();
let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey());
let (sender, receiver) = channel();
run_local_faucet(mint_keypair, sender, None);
let faucet_addr = receiver.recv().unwrap();
let rpc_client = RpcClient::new(test_validator.rpc_url());
let mut file = File::open(pathbuf.to_str().unwrap()).unwrap();
let mut program_data = Vec::new();
file.read_to_end(&mut program_data).unwrap();
let max_len = program_data.len();
let minimum_balance_for_buffer = rpc_client
.get_minimum_balance_for_rent_exemption(
UpgradeableLoaderState::programdata_len(max_len).unwrap(),
)
.unwrap();
let mut config = CliConfig::recent_for_tests();
let keypair = Keypair::new();
config.json_rpc_url = test_validator.rpc_url();
config.signers = vec![&keypair];
config.command = CliCommand::Airdrop {
faucet_host: None,
faucet_port: faucet_addr.port(),
pubkey: None,
lamports: 100 * minimum_balance_for_buffer,
};
process_command(&config).unwrap();
// Write a buffer
let buffer_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: None,
is_final: false,
max_len: None,
});
process_command(&config).unwrap();
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_keypair.pubkey(), CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(keypair.pubkey()));
} else {
panic!("not a buffer account");
}
// Set new authority
let new_buffer_authority = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair];
config.command = CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey: buffer_keypair.pubkey(),
buffer_authority_index: Some(0),
new_buffer_authority: Some(new_buffer_authority.pubkey()),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let new_buffer_authority_str = json
.as_object()
.unwrap()
.get("Authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
Pubkey::from_str(&new_buffer_authority_str).unwrap(),
new_buffer_authority.pubkey()
);
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_keypair.pubkey(), CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(new_buffer_authority.pubkey()));
} else {
panic!("not a buffer account");
}
// Set authority to buffer
config.signers = vec![&keypair, &new_buffer_authority];
config.command = CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey: buffer_keypair.pubkey(),
buffer_authority_index: Some(1),
new_buffer_authority: Some(buffer_keypair.pubkey()),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_authority_str = json
.as_object()
.unwrap()
.get("Authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
Pubkey::from_str(&buffer_authority_str).unwrap(),
buffer_keypair.pubkey()
);
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_keypair.pubkey(), CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, Some(buffer_keypair.pubkey()));
} else {
panic!("not a buffer account");
}
// Set authority to None
config.signers = vec![&keypair, &buffer_keypair];
config.command = CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey: buffer_keypair.pubkey(),
buffer_authority_index: Some(1),
new_buffer_authority: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_authority_str = json
.as_object()
.unwrap()
.get("Authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!(buffer_authority_str, "None");
let buffer_account = rpc_client
.get_account_with_commitment(&buffer_keypair.pubkey(), CommitmentConfig::recent())
.unwrap()
.value
.unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, None);
} else {
panic!("not a buffer account");
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client"
version = "1.5.1"
version = "1.5.2"
description = "Solana Client"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -23,13 +23,13 @@ semver = "0.11.0"
serde = "1.0.112"
serde_derive = "1.0.103"
serde_json = "1.0.56"
solana-account-decoder = { path = "../account-decoder", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-net-utils = { path = "../net-utils", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-account-decoder = { path = "../account-decoder", version = "1.5.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-net-utils = { path = "../net-utils", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
thiserror = "1.0"
tungstenite = "0.10.1"
url = "2.1.1"
@@ -38,7 +38,7 @@ url = "2.1.1"
assert_matches = "1.3.0"
jsonrpc-core = "15.0.0"
jsonrpc-http-server = "15.0.0"
solana-logger = { path = "../logger", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.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.5.1"
version = "1.5.2"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -45,34 +45,35 @@ rand_chacha = "0.2.2"
raptorq = "1.4.2"
rayon = "1.4.1"
regex = "1.3.9"
rustversion = "1.0.4"
serde = "1.0.112"
serde_bytes = "0.11"
serde_derive = "1.0.103"
serde_json = "1.0.56"
solana-account-decoder = { path = "../account-decoder", version = "1.5.1" }
solana-banks-server = { path = "../banks-server", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-faucet = { path = "../faucet", version = "1.5.1" }
solana-ledger = { path = "../ledger", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.5.1" }
solana-metrics = { path = "../metrics", version = "1.5.1" }
solana-measure = { path = "../measure", version = "1.5.1" }
solana-net-utils = { path = "../net-utils", version = "1.5.1" }
solana-perf = { path = "../perf", version = "1.5.1" }
solana-program-test = { path = "../program-test", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-frozen-abi = { path = "../frozen-abi", version = "1.5.1" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.1" }
solana-streamer = { path = "../streamer", version = "1.5.1" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.5.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-account-decoder = { path = "../account-decoder", version = "1.5.2" }
solana-banks-server = { path = "../banks-server", version = "1.5.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-faucet = { path = "../faucet", version = "1.5.2" }
solana-ledger = { path = "../ledger", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.5.2" }
solana-metrics = { path = "../metrics", version = "1.5.2" }
solana-measure = { path = "../measure", version = "1.5.2" }
solana-net-utils = { path = "../net-utils", version = "1.5.2" }
solana-perf = { path = "../perf", version = "1.5.2" }
solana-program-test = { path = "../program-test", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-frozen-abi = { path = "../frozen-abi", version = "1.5.2" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.2" }
solana-streamer = { path = "../streamer", version = "1.5.2" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.5.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
spl-token-v2-0 = { package = "spl-token", version = "=3.0.1", features = ["no-entrypoint"] }
tempfile = "3.1.0"
thiserror = "1.0"
@@ -82,7 +83,7 @@ tokio_01_bytes = { version = "0.4.7", package = "bytes" }
tokio_fs_01 = { version = "0.1", package = "tokio-fs" }
tokio_io_01 = { version = "0.1", package = "tokio-io" }
tokio_codec_01 = { version = "0.1", package = "tokio-codec" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.5.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.5.2" }
trees = "0.2.1"
[dev-dependencies]

View File

@@ -40,6 +40,11 @@ use std::collections::{hash_map, HashMap};
use std::ops::{Index, IndexMut};
const CRDS_SHARDS_BITS: u32 = 8;
// Limit number of crds values associated with each unique pubkey. This
// excludes crds values which by label design are limited per each pubkey.
// TODO: Find the right value for this once duplicate shreds and corresponding
// votes are broadcasted over gossip.
const MAX_CRDS_VALUES_PER_PUBKEY: usize = 512;
#[derive(Clone)]
pub struct Crds {
@@ -275,22 +280,59 @@ impl Crds {
now: u64,
timeouts: &HashMap<Pubkey, u64>,
) -> Vec<CrdsValueLabel> {
// TODO: need custom logic for purging duplicate shreds.
#[rustversion::before(1.49.0)]
fn select_nth<T: Ord>(xs: &mut Vec<T>, _nth: usize) {
xs.sort_unstable();
}
#[rustversion::since(1.49.0)]
fn select_nth<T: Ord>(xs: &mut Vec<T>, nth: usize) {
xs.select_nth_unstable(nth);
}
let default_timeout = *timeouts
.get(&Pubkey::default())
.expect("must have default timeout");
thread_pool.install(|| {
self.table
.par_iter()
.with_min_len(1024)
.filter_map(|(k, v)| {
let timeout = timeouts.get(&k.pubkey()).unwrap_or(&default_timeout);
if v.local_timestamp.saturating_add(*timeout) <= now {
Some(k.clone())
} else {
// Given an index of all crd values associated with a pubkey,
// returns crds labels of old values to be evicted.
let evict = |pubkey, index: &IndexSet<usize>| {
let timeout = *timeouts.get(pubkey).unwrap_or(&default_timeout);
let mut old_labels = Vec::new();
// Buffer of crds values to be evicted based on their wallclock.
let mut recent_unlimited_labels: Vec<(u64 /*wallclock*/, usize /*index*/)> = index
.into_iter()
.filter_map(|ix| {
let (label, value) = self.table.get_index(*ix).unwrap();
if value.local_timestamp.saturating_add(timeout) <= now {
old_labels.push(label.clone());
None
} else {
match label.value_space() {
Some(_) => None,
None => Some((value.value.wallclock(), *ix)),
}
}
})
.collect();
// Number of values to discard from the buffer:
let nth = recent_unlimited_labels
.len()
.saturating_sub(MAX_CRDS_VALUES_PER_PUBKEY);
// Partition on wallclock to discard the older ones.
if nth > 0 && nth < recent_unlimited_labels.len() {
select_nth(&mut recent_unlimited_labels, nth);
}
old_labels.extend(
recent_unlimited_labels
.split_at(nth)
.0
.iter()
.map(|(_ /*wallclock*/, ix)| self.table.get_index(*ix).unwrap().0.clone()),
);
old_labels
};
thread_pool.install(|| {
self.records
.par_iter()
.flat_map(|(pubkey, index)| evict(pubkey, index))
.collect()
})
}
@@ -350,10 +392,10 @@ impl Crds {
#[cfg(test)]
mod test {
use super::*;
use crate::contact_info::ContactInfo;
use crate::{contact_info::ContactInfo, crds_value::NodeInstance};
use rand::{thread_rng, Rng};
use rayon::ThreadPoolBuilder;
use std::iter::repeat_with;
use std::{collections::HashSet, iter::repeat_with};
#[test]
fn test_insert() {
@@ -467,6 +509,41 @@ mod test {
vec![val.label()]
);
}
#[test]
fn test_find_old_records_unlimited() {
let thread_pool = ThreadPoolBuilder::new().build().unwrap();
let mut rng = thread_rng();
let now = 1_610_034_423_000;
let pubkey = Pubkey::new_unique();
let mut crds = Crds::default();
let mut timeouts = HashMap::new();
timeouts.insert(Pubkey::default(), 1);
timeouts.insert(pubkey, 180);
for _ in 0..1024 {
let wallclock = now - rng.gen_range(0, 240);
let val = NodeInstance::new(&mut rng, pubkey, wallclock);
let val = CrdsData::NodeInstance(val);
let val = CrdsValue::new_unsigned(val);
assert_eq!(crds.insert(val, now), Ok(None));
}
let now = now + 1;
let labels = crds.find_old_labels(&thread_pool, now, &timeouts);
assert_eq!(crds.table.len() - labels.len(), MAX_CRDS_VALUES_PER_PUBKEY);
let max_wallclock = labels
.iter()
.map(|label| crds.lookup(label).unwrap().wallclock())
.max()
.unwrap();
assert!(max_wallclock > now - 180);
let labels: HashSet<_> = labels.into_iter().collect();
for (label, value) in crds.table.iter() {
if !labels.contains(label) {
assert!(max_wallclock <= value.value.wallclock());
}
}
}
#[test]
fn test_remove_default() {
let thread_pool = ThreadPoolBuilder::new().build().unwrap();

View File

@@ -428,6 +428,23 @@ impl CrdsValueLabel {
CrdsValueLabel::DuplicateShred(_, p) => *p,
}
}
/// Returns number of possible distinct labels of the same type for
/// a fixed pubkey, and None if that is practically unlimited.
pub(crate) fn value_space(&self) -> Option<usize> {
match self {
CrdsValueLabel::ContactInfo(_) => Some(1),
CrdsValueLabel::Vote(_, _) => Some(MAX_VOTES as usize),
CrdsValueLabel::LowestSlot(_) => Some(1),
CrdsValueLabel::SnapshotHashes(_) => Some(1),
CrdsValueLabel::EpochSlots(_, _) => Some(MAX_EPOCH_SLOTS as usize),
CrdsValueLabel::AccountsHashes(_) => Some(1),
CrdsValueLabel::LegacyVersion(_) => Some(1),
CrdsValueLabel::Version(_) => Some(1),
CrdsValueLabel::NodeInstance(_, _) => None,
CrdsValueLabel::DuplicateShred(_, _) => None,
}
}
}
impl CrdsValue {

View File

@@ -1,4 +1,7 @@
use solana_runtime::bank::Bank;
use solana_runtime::{
accounts_index::{AccountIndex, IndexKey},
bank::Bank,
};
use solana_sdk::pubkey::Pubkey;
use solana_stake_program::stake_state::StakeState;
use std::{collections::HashSet, sync::Arc};
@@ -18,7 +21,24 @@ pub fn calculate_non_circulating_supply(bank: &Arc<Bank>) -> NonCirculatingSuppl
let withdraw_authority_list = withdraw_authority();
let clock = bank.clock();
let stake_accounts = bank.get_program_accounts(&solana_stake_program::id());
let stake_accounts = if bank
.rc
.accounts
.accounts_db
.account_indexes
.contains(&AccountIndex::ProgramId)
{
bank.get_filtered_indexed_accounts(
&IndexKey::ProgramId(solana_stake_program::id()),
// The program-id account index checks for Account owner on inclusion. However, due to
// the current AccountsDB implementation, an account may remain in storage as a
// zero-lamport Account::Default() after being wiped and reinitialized in later
// updates. We include the redundant filter here to avoid returning these accounts.
|account| account.owner == solana_stake_program::id(),
)
} else {
bank.get_program_accounts(&solana_stake_program::id())
};
for (pubkey, account) in stake_accounts.iter() {
let stake_account = StakeState::from(&account).unwrap_or_default();
match stake_account {

View File

@@ -21,6 +21,8 @@ pub const NUM_HASHES_PER_BATCH: u64 = 1;
pub const DEFAULT_PINNED_CPU_CORE: usize = 0;
const TARGET_SLOT_ADJUSTMENT_NS: u64 = 50_000_000;
impl PohService {
pub fn new(
poh_recorder: Arc<Mutex<PohRecorder>>,
@@ -52,10 +54,17 @@ impl PohService {
if let Some(cores) = core_affinity::get_core_ids() {
core_affinity::set_for_current(cores[pinned_cpu_core]);
}
// Account for some extra time outside of PoH generation to account
// for processing time outside PoH.
let adjustment_per_tick = if ticks_per_slot > 0 {
TARGET_SLOT_ADJUSTMENT_NS / ticks_per_slot
} else {
0
};
Self::tick_producer(
poh_recorder,
&poh_exit_,
poh_config.target_tick_duration.as_nanos() as u64,
poh_config.target_tick_duration.as_nanos() as u64 - adjustment_per_tick,
ticks_per_slot,
);
}

View File

@@ -1313,6 +1313,11 @@ impl JsonRpcRequestProcessor {
.contains(&AccountIndex::ProgramId)
{
bank.get_filtered_indexed_accounts(&IndexKey::ProgramId(*program_id), |account| {
// The program-id account index checks for Account owner on inclusion. However, due
// to the current AccountsDB implementation, an account may remain in storage as a
// zero-lamport Account::Default() after being wiped and reinitialized in later
// updates. We include the redundant filters here to avoid returning these
// accounts.
account.owner == *program_id && filter_closure(account)
})
} else {
@@ -1327,10 +1332,10 @@ impl JsonRpcRequestProcessor {
owner_key: &Pubkey,
mut filters: Vec<RpcFilterType>,
) -> Vec<(Pubkey, Account)> {
// The by-owner accounts index checks for Token Account state and Owner address on inclusion.
// However, due to the current AccountsDB implementation, accounts may remain in storage as
// be zero-lamport Account::Default() after being wiped and reinitialized in a later updates.
// We include the redundant filters here to avoid returning these accounts.
// The by-owner accounts index checks for Token Account state and Owner address on
// inclusion. However, due to the current AccountsDB implementation, an account may remain
// in storage as a zero-lamport Account::Default() after being wiped and reinitialized in
// later updates. We include the redundant filters here to avoid returning these accounts.
//
// Filter on Token Account state
filters.push(RpcFilterType::DataSize(
@@ -1368,9 +1373,9 @@ impl JsonRpcRequestProcessor {
mut filters: Vec<RpcFilterType>,
) -> Vec<(Pubkey, Account)> {
// The by-mint accounts index checks for Token Account state and Mint address on inclusion.
// However, due to the current AccountsDB implementation, accounts may remain in storage as
// be zero-lamport Account::Default() after being wiped and reinitialized in a later updates.
// We include the redundant filters here to avoid returning these accounts.
// However, due to the current AccountsDB implementation, an account may remain in storage
// as be zero-lamport Account::Default() after being wiped and reinitialized in later
// updates. We include the redundant filters here to avoid returning these accounts.
//
// Filter on Token Account state
filters.push(RpcFilterType::DataSize(

View File

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

View File

@@ -715,7 +715,7 @@ starting at `start_slot` for up to `limit` blocks, inclusive.
Request:
```bash
curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlockWithLimit2","params":[5, 3]}
{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[5, 3]}
'
```
@@ -2571,7 +2571,7 @@ curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
Result:
```json
{"jsonrpc":"2.0","result":{"solana-core": "1.5.1"},"id":1}
{"jsonrpc":"2.0","result":{"solana-core": "1.5.2"},"id":1}
```
### getVoteAccounts

View File

@@ -276,24 +276,24 @@ getrandom = { version = "0.1.14", features = ["dummy"] }
Rust's `println!` macro is computationally expensive and not supported. Instead
the helper macro
[`info!`](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/log.rs#L10)
[`msg!`](https://github.com/solana-labs/solana/blob/6705b5a98c076ac08f3991bb8a6f9fcb280bf51e/sdk/program/src/log.rs#L33)
is provided.
`info!` has two forms:
`msg!` has two forms:
```rust
info!("A string");
msg!("A string");
```
or
```rust
info!(0_64, 1_64, 2_64, 3_64, 4_64)
msg!(0_64, 1_64, 2_64, 3_64, 4_64);
```
Both forms output the results to the program logs. If a program so wishes they
can emulate `println!` by using `format!`:
```rust
info!(&format!("Some varialbe: {:?}", variable));
msg!("Some variable: {:?}", variable);
```
The [debugging](debugging.md#logging) section has more information about working
@@ -333,8 +333,8 @@ Then provide a custom implementation of the panic handler:
#[cfg(all(feature = "custom-panic", target_arch = "bpf"))]
#[no_mangle]
fn custom_panic(info: &core::panic::PanicInfo<'_>) {
solana_program::info!("program custom panic enabled");
solana_program::info!(&format!("{}", info));
solana_program::msg!("program custom panic enabled");
solana_program::msg!("{}", info);
}
```

View File

@@ -336,7 +336,18 @@ Start the service with:
$ sudo systemctl enable --now sol
```
### Log rotation
### Logging
#### Log output tuning
The messages that a validator emits to the log can be controlled by the `RUST_LOG`
environment variable. Details can by found in the [documentation](https://docs.rs/env_logger/latest/env_logger/#enabling-logging)
for the `env_logger` Rust crate.
Note that if logging output is reduced, this may make it difficult to debug issues
encountered later. Should support be sought from the team, any changes will need
to be reverted and the issue reproduced before help can be provided.
#### Log rotation
The validator log file, as specified by `--log ~/solana-validator.log`, can get
very large over time and it's recommended that log rotation be configured.
@@ -344,7 +355,7 @@ very large over time and it's recommended that log rotation be configured.
The validator will re-open its when it receives the `USR1` signal, which is the
basic primitive that enables log rotation.
### Using logrotate
#### Using logrotate
An example setup for the `logrotate`, which assumes that the validator is
running as a systemd service called `sol.service` and writes a log file at
@@ -397,7 +408,11 @@ Example configuration:
(assuming your validator is running under the user "sol"). **CAREFUL: If you
incorrectly edit /etc/fstab your machine may no longer boot**
3. Create at least 250GB of swap space
- Choose a device to use in place of `SWAPDEV` for the remainder of these instructions. Ideally select a free disk partition of 250GB or greater on a fast disk. If one is not available, create a swap file with `sudo fallocate -l 250G /swapfile`, set its permissions with `sudo chmod 0600 /swapfile` and use `/swapfile` as `SWAPDEV` for the remainder of these instructions
- Choose a device to use in place of `SWAPDEV` for the remainder of these instructions.
Ideally select a free disk partition of 250GB or greater on a fast disk. If one is not
available, create a swap file with `sudo dd if=/dev/zero of=/swapfile bs=1MiB count=250KiB`,
set its permissions with `sudo chmod 0600 /swapfile` and use `/swapfile` as `SWAPDEV` for
the remainder of these instructions
- Format the device for usage as swap with `sudo mkswap SWAPDEV`
4. Add the swap file to `/etc/fstab` with a new line containing `SWAPDEV swap swap defaults 0 0`
5. Enable swap with `sudo swapon -a` and mount the tmpfs with `sudo mount /mnt/solana-accounts/`
@@ -405,3 +420,18 @@ Example configuration:
Now add the `--accounts /mnt/solana-accounts` argument to your `solana-validator`
command-line arguments and restart the validator.
### Account indexing
As the number of populated accounts on the cluster grows, account-data RPC
requests that scan the entire account set -- like
[`getProgramAccounts`](developing/clients/jsonrpc-api.md#getprogramaccounts) and
[SPL-token-specific requests](developing/clients/jsonrpc-api.md#gettokenaccountsbydelegate) --
may perform poorly. If your validator needs to support any of these requests,
you can use the `--account-index` parameter to activate one or more in-memory
account indexes that significantly improve RPC performance by indexing accounts
by the key field. Currently supports the following parameter values:
- `program-id`: each account indexed by its owning program; used by [`getProgramAccounts`](developing/clients/jsonrpc-api.md#getprogramaccounts)
- `spl-token-mint`: each SPL token account indexed by its token Mint; used by [getTokenAccountsByDelegate](developing/clients/jsonrpc-api.md#gettokenaccountsbydelegate), and [getTokenLargestAccounts](developing/clients/jsonrpc-api.md#gettokenlargestaccounts)
- `spl-token-owner`: each SPL token account indexed by the token-owner address; used by [getTokenAccountsByOwner](developing/clients/jsonrpc-api.md#gettokenaccountsbyowner), and [`getProgramAccounts`](developing/clients/jsonrpc-api.md#getprogramaccounts) requests that include an spl-token-owner filter.

View File

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

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-download-utils"
version = "1.5.1"
version = "1.5.2"
description = "Solana Download Utils"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,8 +14,8 @@ console = "0.11.3"
indicatif = "0.15.0"
log = "0.4.11"
reqwest = { version = "0.10.8", default-features = false, features = ["blocking", "rustls-tls", "json"] }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
tar = "0.4.28"
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-faucet"
version = "1.5.1"
version = "1.5.2"
description = "Solana Faucet"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,12 +15,12 @@ clap = "2.33"
log = "0.4.11"
serde = "1.0.112"
serde_derive = "1.0.103"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-cli-config = { path = "../cli-config", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-metrics = { path = "../metrics", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-cli-config = { path = "../cli-config", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-metrics = { path = "../metrics", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
tokio = { version = "0.3.5", features = ["full"] }
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-frozen-abi"
version = "1.5.1"
version = "1.5.2"
description = "Solana Frozen ABI"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,11 +15,11 @@ log = "0.4.11"
serde = "1.0.112"
serde_derive = "1.0.103"
sha2 = "0.8.2"
solana-frozen-abi-macro = { path = "macro", version = "1.5.1" }
solana-frozen-abi-macro = { path = "macro", version = "1.5.2" }
thiserror = "1.0"
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
solana-logger = { path = "../logger", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.2" }
generic-array = { version = "0.14.3", default-features = false, features = ["serde", "more_lengths"]}
memmap2 = "0.1.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-frozen-abi-macro"
version = "1.5.1"
version = "1.5.2"
description = "Solana Frozen ABI Macro"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-genesis"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,18 +15,18 @@ chrono = "0.4"
serde = "1.0.112"
serde_json = "1.0.56"
serde_yaml = "0.8.13"
solana-budget-program = { path = "../programs/budget", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-cli-config = { path = "../cli-config", version = "1.5.1" }
solana-exchange-program = { path = "../programs/exchange", version = "1.5.1" }
solana-ledger = { path = "../ledger", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-vest-program = { path = "../programs/vest", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-budget-program = { path = "../programs/budget", version = "1.5.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-cli-config = { path = "../cli-config", version = "1.5.2" }
solana-exchange-program = { path = "../programs/exchange", version = "1.5.2" }
solana-ledger = { path = "../ledger", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
solana-vest-program = { path = "../programs/vest", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
tempfile = "3.1.0"
[[bin]]

View File

@@ -3,20 +3,20 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-gossip"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.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.5.1" }
solana-core = { path = "../core", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-net-utils = { path = "../net-utils", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-core = { path = "../core", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-net-utils = { path = "../net-utils", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

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

View File

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

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-ledger-tool"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -22,18 +22,18 @@ regex = "1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.56"
serde_yaml = "0.8.13"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-cli-output = { path = "../cli-output", version = "1.5.1" }
solana-ledger = { path = "../ledger", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-measure = { path = "../measure", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-cli-output = { path = "../cli-output", version = "1.5.2" }
solana-ledger = { path = "../ledger", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-measure = { path = "../measure", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
tempfile = "3.1.0"
tokio = { version = "0.2.22", features = ["full"] }

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ledger"
version = "1.5.1"
version = "1.5.2"
description = "Solana ledger"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -32,22 +32,22 @@ reed-solomon-erasure = { version = "4.0.2", features = ["simd-accel"] }
serde = "1.0.112"
serde_bytes = "0.11.4"
sha2 = "0.8.2"
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.5.1" }
solana-frozen-abi = { path = "../frozen-abi", version = "1.5.1" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "1.5.1" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-measure = { path = "../measure", version = "1.5.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.5.1" }
solana-metrics = { path = "../metrics", version = "1.5.1" }
solana-perf = { path = "../perf", version = "1.5.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.1" }
solana-storage-proto = { path = "../storage-proto", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.5.2" }
solana-frozen-abi = { path = "../frozen-abi", version = "1.5.2" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "1.5.2" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-measure = { path = "../measure", version = "1.5.2" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.5.2" }
solana-metrics = { path = "../metrics", version = "1.5.2" }
solana-perf = { path = "../perf", version = "1.5.2" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.2" }
solana-storage-proto = { path = "../storage-proto", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
tempfile = "3.1.0"
thiserror = "1.0"
tokio = { version = "0.2.22", features = ["full"] }
@@ -63,7 +63,7 @@ features = ["lz4"]
[dev-dependencies]
assert_matches = "1.3.0"
matches = "0.1.6"
solana-budget-program = { path = "../programs/budget", version = "1.5.1" }
solana-budget-program = { path = "../programs/budget", version = "1.5.2" }
[build-dependencies]
rustc_version = "0.2"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-local-cluster"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,21 +15,21 @@ gag = "0.1.10"
fs_extra = "1.1.0"
log = "0.4.11"
rand = "0.7.0"
solana-config-program = { path = "../programs/config", version = "1.5.1" }
solana-core = { path = "../core", version = "1.5.1" }
solana-client = { path = "../client", version = "1.5.1" }
solana-download-utils = { path = "../download-utils", version = "1.5.1" }
solana-faucet = { path = "../faucet", version = "1.5.1" }
solana-exchange-program = { path = "../programs/exchange", version = "1.5.1" }
solana-ledger = { path = "../ledger", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-stake-program = { path = "../programs/stake", version = "1.5.1" }
solana-vest-program = { path = "../programs/vest", version = "1.5.1" }
solana-vote-program = { path = "../programs/vote", version = "1.5.1" }
solana-config-program = { path = "../programs/config", version = "1.5.2" }
solana-core = { path = "../core", version = "1.5.2" }
solana-client = { path = "../client", version = "1.5.2" }
solana-download-utils = { path = "../download-utils", version = "1.5.2" }
solana-faucet = { path = "../faucet", version = "1.5.2" }
solana-exchange-program = { path = "../programs/exchange", version = "1.5.2" }
solana-ledger = { path = "../ledger", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-stake-program = { path = "../programs/stake", version = "1.5.2" }
solana-vest-program = { path = "../programs/vest", version = "1.5.2" }
solana-vote-program = { path = "../programs/vote", version = "1.5.2" }
tempfile = "3.1.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.5.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.5.2" }
[dev-dependencies]
assert_matches = "1.3.0"

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.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,9 +14,9 @@ byte-unit = "4.0.8"
clap = "2.33.1"
serde = "1.0.112"
serde_json = "1.0.56"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
[[bin]]
name = "solana-log-analyzer"

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-net-shaper"
description = "The solana cluster network shaping tool"
version = "1.5.1"
version = "1.5.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.112"
serde_json = "1.0.56"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
rand = "0.7.0"
[[bin]]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-net-utils"
version = "1.5.1"
version = "1.5.2"
description = "Solana Network Utilities"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -17,9 +17,9 @@ rand = "0.7.0"
serde = "1.0.112"
serde_derive = "1.0.103"
socket2 = "0.3.17"
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
tokio = { version = "0.3.5", features = ["full"] }
url = "2.1.1"

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2018"
name = "solana-poh-bench"
version = "1.5.1"
version = "1.5.2"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -12,13 +12,13 @@ clap = "2.33.1"
log = "0.4.11"
rand = "0.7.0"
rayon = "1.4.0"
solana-logger = { path = "../logger", version = "1.5.1" }
solana-ledger = { path = "../ledger", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.1" }
solana-measure = { path = "../measure", version = "1.5.1" }
solana-version = { path = "../version", version = "1.5.1" }
solana-perf = { path = "../perf", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-ledger = { path = "../ledger", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
solana-clap-utils = { path = "../clap-utils", version = "1.5.2" }
solana-measure = { path = "../measure", version = "1.5.2" }
solana-version = { path = "../version", version = "1.5.2" }
solana-perf = { path = "../perf", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -5,7 +5,7 @@ edition = "2018"
license = "Apache-2.0"
name = "solana-program-test"
repository = "https://github.com/solana-labs/solana"
version = "1.5.1"
version = "1.5.2"
[dependencies]
async-trait = "0.1.42"
@@ -14,11 +14,11 @@ chrono = "0.4.19"
chrono-humanize = "0.1.1"
log = "0.4.11"
mio = "0.7.6"
solana-banks-client = { path = "../banks-client", version = "1.5.1" }
solana-banks-server = { path = "../banks-server", version = "1.5.1" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.5.1" }
solana-logger = { path = "../logger", version = "1.5.1" }
solana-program = { path = "../sdk/program", version = "1.5.1" }
solana-runtime = { path = "../runtime", version = "1.5.1" }
solana-sdk = { path = "../sdk", version = "1.5.1" }
solana-banks-client = { path = "../banks-client", version = "1.5.2" }
solana-banks-server = { path = "../banks-server", version = "1.5.2" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.5.2" }
solana-logger = { path = "../logger", version = "1.5.2" }
solana-program = { path = "../sdk/program", version = "1.5.2" }
solana-runtime = { path = "../runtime", version = "1.5.2" }
solana-sdk = { path = "../sdk", version = "1.5.2" }
tokio = { version = "0.3.5", features = ["full"] }

116
programs/bpf/Cargo.lock generated
View File

@@ -1308,7 +1308,7 @@ dependencies = [
"libc",
"redox_syscall",
"rustc_version",
"smallvec 0.6.13",
"smallvec 0.6.14",
"winapi 0.3.8",
]
@@ -1816,18 +1816,18 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallvec"
version = "0.6.13"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
dependencies = [
"maybe-uninit",
]
[[package]]
name = "smallvec"
version = "1.4.2"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
name = "socket2"
@@ -1843,7 +1843,7 @@ dependencies = [
[[package]]
name = "solana-bpf-loader-program"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"byteorder 1.3.4",
@@ -1858,7 +1858,7 @@ dependencies = [
[[package]]
name = "solana-bpf-programs"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"byteorder 1.3.4",
@@ -1876,7 +1876,7 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-128bit"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-bpf-rust-128bit-dep",
"solana-program",
@@ -1884,42 +1884,42 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-128bit-dep"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-alloc"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-call-depth"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-caller-access"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-custom-heap"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-dep-crate"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"byteorder 1.3.4",
"solana-program",
@@ -1927,21 +1927,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-deprecated-loader"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-dup-accounts"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-error-handling"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"num-derive 0.2.5",
"num-traits",
@@ -1951,21 +1951,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-external-spend"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-instruction-introspection"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-invoke"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-bpf-rust-invoked",
"solana-program",
@@ -1973,42 +1973,42 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-invoke-and-error"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-invoke-and-ok"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-invoke-and-return"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-invoked"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-iter"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-bpf-rust-many-args-dep",
"solana-program",
@@ -2016,35 +2016,35 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-many-args-dep"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-mem"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-noop"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-panic"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-param-passing"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-bpf-rust-param-passing-dep",
"solana-program",
@@ -2052,14 +2052,14 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-param-passing-dep"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-rand"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"getrandom",
"rand",
@@ -2068,7 +2068,7 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-ristretto"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"curve25519-dalek 3.0.0",
"getrandom",
@@ -2077,63 +2077,63 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-ro-modify"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-sanity"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-sha256"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-spoof1"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-spoof1-system"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-upgradeable"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-bpf-rust-upgraded"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"solana-program",
]
[[package]]
name = "solana-config-program"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"chrono",
@@ -2145,7 +2145,7 @@ dependencies = [
[[package]]
name = "solana-crate-features"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"backtrace",
"bytes 0.4.12",
@@ -2167,7 +2167,7 @@ dependencies = [
[[package]]
name = "solana-frozen-abi"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bs58",
"bv",
@@ -2185,7 +2185,7 @@ dependencies = [
[[package]]
name = "solana-frozen-abi-macro"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"lazy_static",
"proc-macro2 1.0.24",
@@ -2196,7 +2196,7 @@ dependencies = [
[[package]]
name = "solana-logger"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"env_logger",
"lazy_static",
@@ -2205,7 +2205,7 @@ dependencies = [
[[package]]
name = "solana-measure"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"jemalloc-ctl",
"jemallocator",
@@ -2216,7 +2216,7 @@ dependencies = [
[[package]]
name = "solana-metrics"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"env_logger",
"gethostname",
@@ -2228,7 +2228,7 @@ dependencies = [
[[package]]
name = "solana-program"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"bs58",
@@ -2256,7 +2256,7 @@ dependencies = [
[[package]]
name = "solana-rayon-threadlimit"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"lazy_static",
"num_cpus",
@@ -2264,7 +2264,7 @@ dependencies = [
[[package]]
name = "solana-runtime"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"blake3",
@@ -2313,7 +2313,7 @@ dependencies = [
[[package]]
name = "solana-sdk"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"assert_matches",
"bincode",
@@ -2355,7 +2355,7 @@ dependencies = [
[[package]]
name = "solana-sdk-macro"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bs58",
"proc-macro2 1.0.24",
@@ -2366,7 +2366,7 @@ dependencies = [
[[package]]
name = "solana-secp256k1-program"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"digest 0.9.0",
@@ -2379,7 +2379,7 @@ dependencies = [
[[package]]
name = "solana-stake-program"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"log",
@@ -2399,7 +2399,7 @@ dependencies = [
[[package]]
name = "solana-vote-program"
version = "1.5.1"
version = "1.5.2"
dependencies = [
"bincode",
"log",
@@ -2861,7 +2861,7 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
dependencies = [
"smallvec 1.4.2",
"smallvec 1.6.1",
]
[[package]]

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-bpf-programs"
description = "Blockchain, Rebuilt for Scale"
version = "1.5.1"
version = "1.5.2"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "README.md"
@@ -24,11 +24,11 @@ byteorder = "1.3.2"
elf = "0.0.10"
miow = "0.2.2"
net2 = "0.2.37"
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.5.1" }
solana-logger = { path = "../../logger", version = "1.5.1" }
solana-measure = { path = "../../measure", version = "1.5.1" }
solana-runtime = { path = "../../runtime", version = "1.5.1" }
solana-sdk = { path = "../../sdk", version = "1.5.1" }
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.5.2" }
solana-logger = { path = "../../logger", version = "1.5.2" }
solana-measure = { path = "../../measure", version = "1.5.2" }
solana-runtime = { path = "../../runtime", version = "1.5.2" }
solana-sdk = { path = "../../sdk", version = "1.5.2" }
solana_rbpf = "=0.2.2"
[[bench]]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-128bit"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,8 +9,8 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-128bit-dep"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-alloc"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-call-depth"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-caller-access"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-custom-heap"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[features]
default = ["custom-heap"]

View File

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

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-deprecated-loader"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-dup-accounts"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-error-handling"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,7 +11,7 @@ edition = "2018"
[dependencies]
num-derive = "0.2"
num-traits = "0.2"
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
thiserror = "1.0"
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-external-spend"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-instruction-introspection"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-invoke"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,7 +10,7 @@ edition = "2018"
[dependencies]
solana-bpf-rust-invoked = { path = "../invoked", default-features = false }
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-invoke-and-error"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-invoke-and-ok"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-invoke-and-return"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-invoked"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[features]
default = ["program"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-iter"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-many-args"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,8 +9,8 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-many-args-dep"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-mem"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-noop"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-panic"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[features]
default = ["custom-panic"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-param-passing"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,8 +9,8 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-param-passing-dep"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-rand"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,7 +11,7 @@ edition = "2018"
[dependencies]
getrandom = { version = "0.1.14", features = ["dummy"] }
rand = "0.7"
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-ristretto"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,7 +11,7 @@ edition = "2018"
[dependencies]
curve25519-dalek = "3"
getrandom = { version = "0.1.14", features = ["dummy"] }
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-ro-modify"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-sanity"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-sha256"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-spoof1"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-spoof1-system"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-sysval"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
crate-type = ["cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-upgradeable"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
name = "solana_bpf_rust_upgradeable"

View File

@@ -2,16 +2,24 @@
extern crate solana_program;
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
sysvar::{clock, fees},
};
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
msg!("Upgradeable program");
assert_eq!(accounts.len(), 2);
assert_eq!(accounts.len(), 3);
assert_eq!(accounts[0].key, program_id);
assert_eq!(*accounts[1].key, clock::id());
assert_eq!(*accounts[2].key, fees::id());
Err(42.into())
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-rust-upgraded"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "1.5.1" }
solana-program = { path = "../../../../sdk/program", version = "1.5.2" }
[lib]
name = "solana_bpf_rust_upgraded"

View File

@@ -2,16 +2,24 @@
extern crate solana_program;
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
sysvar::{clock, fees},
};
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
msg!("Upgraded program");
assert_eq!(accounts.len(), 2);
assert_eq!(accounts.len(), 3);
assert_eq!(accounts[0].key, program_id);
assert_eq!(*accounts[1].key, clock::id());
assert_eq!(*accounts[2].key, fees::id());
Err(43.into())
}

View File

@@ -21,7 +21,7 @@ use solana_runtime::{
};
use solana_sdk::{
account::Account,
bpf_loader, bpf_loader_deprecated,
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
client::SyncClient,
clock::{DEFAULT_SLOTS_PER_EPOCH, MAX_PROCESSING_AGE},
entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS},
@@ -1533,7 +1533,6 @@ fn test_program_bpf_test_use_latest_executor2() {
fn test_program_bpf_upgrade() {
solana_logger::setup();
let mut nonce = 0;
let GenesisConfigInfo {
genesis_config,
mint_keypair,
@@ -1548,17 +1547,18 @@ fn test_program_bpf_upgrade() {
let (program_id, authority_keypair) =
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
// Call upgrade program
nonce += 1;
let instruction = Instruction::new(
let mut instruction = Instruction::new(
program_id,
&[nonce],
&[0],
vec![
AccountMeta::new(program_id.clone(), false),
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
// Call upgrade program
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(42))
@@ -1574,16 +1574,8 @@ fn test_program_bpf_upgrade() {
);
// Call upgraded program
nonce += 1;
let instruction = Instruction::new(
program_id,
&[nonce],
vec![
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(43))
@@ -1609,15 +1601,7 @@ fn test_program_bpf_upgrade() {
);
// Call original program
nonce += 1;
let instruction = Instruction::new(
program_id,
&[nonce],
vec![
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
assert_eq!(
result.unwrap_err().unwrap(),
@@ -1630,7 +1614,6 @@ fn test_program_bpf_upgrade() {
fn test_program_bpf_invoke_upgradeable_via_cpi() {
solana_logger::setup();
let mut nonce = 0;
let GenesisConfigInfo {
genesis_config,
mint_keypair,
@@ -1649,22 +1632,24 @@ fn test_program_bpf_invoke_upgradeable_via_cpi() {
"solana_bpf_rust_invoke_and_return",
);
// Deploy upgrade program
// Deploy upgradeable program
let (program_id, authority_keypair) =
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
// Call invoker program to invoke the upgradeable program
nonce += 1;
let instruction = Instruction::new(
let mut instruction = Instruction::new(
invoke_and_return,
&[nonce],
&[0],
vec![
AccountMeta::new(program_id, false),
AccountMeta::new(program_id, false),
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
// Call invoker program to invoke the upgradeable program
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(42))
@@ -1680,17 +1665,8 @@ fn test_program_bpf_invoke_upgradeable_via_cpi() {
);
// Call the upgraded program
nonce += 1;
let instruction = Instruction::new(
invoke_and_return,
&[nonce],
vec![
AccountMeta::new(program_id, false),
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(43))
@@ -1716,17 +1692,8 @@ fn test_program_bpf_invoke_upgradeable_via_cpi() {
);
// Call original program
nonce += 1;
let instruction = Instruction::new(
invoke_and_return,
&[nonce],
vec![
AccountMeta::new(program_id, false),
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(42))
@@ -1774,3 +1741,83 @@ fn test_program_bpf_disguised_as_bpf_loader() {
);
}
}
#[cfg(feature = "bpf_rust")]
#[test]
fn test_program_bpf_upgrade_via_cpi() {
solana_logger::setup();
let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_genesis_config(50);
let mut bank = Bank::new(&genesis_config);
let (name, id, entrypoint) = solana_bpf_loader_program!();
bank.add_builtin(&name, id, entrypoint);
let (name, id, entrypoint) = solana_bpf_loader_upgradeable_program!();
bank.add_builtin(&name, id, entrypoint);
let bank_client = BankClient::new(bank);
let invoke_and_return = load_bpf_program(
&bank_client,
&bpf_loader::id(),
&mint_keypair,
"solana_bpf_rust_invoke_and_return",
);
// Deploy upgradeable program
let (program_id, authority_keypair) =
load_upgradeable_bpf_program(&bank_client, &mint_keypair, "solana_bpf_rust_upgradeable");
let mut instruction = Instruction::new(
invoke_and_return,
&[0],
vec![
AccountMeta::new(program_id, false),
AccountMeta::new(program_id, false),
AccountMeta::new(clock::id(), false),
AccountMeta::new(fees::id(), false),
],
);
// Call the upgraded program
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(42))
);
// Load the buffer account
let path = create_bpf_path("solana_bpf_rust_upgraded");
let mut file = File::open(&path).unwrap_or_else(|err| {
panic!("Failed to open {}: {}", path.display(), err);
});
let mut elf = Vec::new();
file.read_to_end(&mut elf).unwrap();
let buffer_pubkey = load_buffer_account(&bank_client, &mint_keypair, &elf);
// Upgrade program via CPI
let mut upgrade_instruction = bpf_loader_upgradeable::upgrade(
&program_id,
&buffer_pubkey,
&authority_keypair.pubkey(),
&mint_keypair.pubkey(),
);
upgrade_instruction.program_id = invoke_and_return;
upgrade_instruction
.accounts
.insert(0, AccountMeta::new(bpf_loader_upgradeable::id(), false));
let message = Message::new(&[upgrade_instruction], Some(&mint_keypair.pubkey()));
bank_client
.send_and_confirm_message(&[&mint_keypair, &authority_keypair], message)
.unwrap();
// Call the upgraded program
instruction.data[0] += 1;
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone());
assert_eq!(
result.unwrap_err().unwrap(),
TransactionError::InstructionError(0, InstructionError::Custom(43))
);
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-loader-program"
version = "1.5.1"
version = "1.5.2"
description = "Solana BPF loader"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,8 +14,8 @@ byteorder = "1.3.4"
curve25519-dalek = "3"
num-derive = "0.3"
num-traits = "0.2"
solana-runtime = { path = "../../runtime", version = "1.5.1" }
solana-sdk = { path = "../../sdk", version = "1.5.1" }
solana-runtime = { path = "../../runtime", version = "1.5.2" }
solana-sdk = { path = "../../sdk", version = "1.5.2" }
solana_rbpf = "=0.2.2"
thiserror = "1.0"

View File

@@ -59,14 +59,14 @@ impl UserDefinedError for BPFError {}
/// Point all log messages to the log collector
macro_rules! log {
($logger:ident, $message:expr) => {
if let Ok(logger) = $logger.try_borrow_mut() {
if let Ok(logger) = $logger.try_borrow_mut() {
if logger.log_enabled() {
logger.log($message);
}
}
};
($logger:ident, $fmt:expr, $($arg:tt)*) => {
if let Ok(logger) = $logger.try_borrow_mut() {
if let Ok(logger) = $logger.try_borrow_mut() {
if logger.log_enabled() {
logger.log(&format!($fmt, $($arg)*));
}
@@ -128,28 +128,19 @@ pub fn create_and_cache_executor(
}
fn write_program_data(
account: &KeyedAccount,
data: &mut [u8],
offset: usize,
bytes: &[u8],
invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let logger = invoke_context.get_logger();
if account.signer_key().is_none() {
log!(logger, "Buffer account did not sign");
return Err(InstructionError::MissingRequiredSignature);
}
let len = bytes.len();
if account.data_len()? < offset + len {
log!(
logger,
"Write overflow: {} < {}",
account.data_len()?,
offset + len
);
if data.len() < offset + len {
log!(logger, "Write overflow: {} < {}", data.len(), offset + len);
return Err(InstructionError::AccountDataTooSmall);
}
account.try_account_ref_mut()?.data[offset..offset + len].copy_from_slice(&bytes);
data[offset..offset + len].copy_from_slice(&bytes);
Ok(())
}
@@ -273,6 +264,7 @@ fn process_instruction_common(
};
executor.execute(
loader_id,
first_account.unsigned_key(),
keyed_accounts,
instruction_data,
invoke_context,
@@ -318,20 +310,41 @@ fn process_loader_upgradeable_instruction(
match limited_deserialize(instruction_data)? {
UpgradeableLoaderInstruction::InitializeBuffer => {
let buffer = next_keyed_account(account_iter)?;
let authority = next_keyed_account(account_iter)
.ok()
.map(|account| account.unsigned_key());
if UpgradeableLoaderState::Uninitialized != buffer.state()? {
log!(logger, "Buffer account already initialized");
return Err(InstructionError::AccountAlreadyInitialized);
}
buffer.set_state(&UpgradeableLoaderState::Buffer)?;
buffer.set_state(&UpgradeableLoaderState::Buffer {
authority_address: authority.cloned(),
})?;
}
UpgradeableLoaderInstruction::Write { offset, bytes } => {
let buffer = next_keyed_account(account_iter)?;
if UpgradeableLoaderState::Buffer != buffer.state()? {
let authority = next_keyed_account(account_iter)?;
if let UpgradeableLoaderState::Buffer { authority_address } = buffer.state()? {
if authority_address == None {
log!(logger, "Buffer is immutable");
return Err(InstructionError::Immutable); // TODO better error code
}
if authority_address != Some(*authority.unsigned_key()) {
log!(logger, "Incorrect buffer authority provided");
return Err(InstructionError::IncorrectAuthority);
}
if authority.signer_key().is_none() {
log!(logger, "Buffer authority did not sign");
return Err(InstructionError::MissingRequiredSignature);
}
} else {
log!(logger, "Invalid Buffer account");
return Err(InstructionError::InvalidAccountData);
}
write_program_data(
buffer,
&mut buffer.try_account_ref_mut()?.data,
UpgradeableLoaderState::buffer_data_offset()? + offset as usize,
&bytes,
invoke_context,
@@ -366,7 +379,11 @@ fn process_loader_upgradeable_instruction(
// Verify Buffer account
if UpgradeableLoaderState::Buffer != buffer.state()? {
if let UpgradeableLoaderState::Buffer {
authority_address: _,
} = buffer.state()?
{
} else {
log!(logger, "Invalid Buffer account");
return Err(InstructionError::InvalidArgument);
}
@@ -472,9 +489,13 @@ fn process_loader_upgradeable_instruction(
// Verify Buffer account
if UpgradeableLoaderState::Buffer != buffer.state()? {
if let UpgradeableLoaderState::Buffer {
authority_address: _,
} = buffer.state()?
{
} else {
log!(logger, "Invalid Buffer account");
return Err(InstructionError::InvalidAccountData);
return Err(InstructionError::InvalidArgument);
}
let buffer_data_offset = UpgradeableLoaderState::buffer_data_offset()?;
@@ -499,11 +520,11 @@ fn process_loader_upgradeable_instruction(
{
if upgrade_authority_address == None {
log!(logger, "Program not upgradeable");
return Err(InstructionError::InvalidArgument);
return Err(InstructionError::Immutable);
}
if upgrade_authority_address != Some(*authority.unsigned_key()) {
log!(logger, "Upgrade authority not present");
return Err(InstructionError::MissingRequiredSignature);
log!(logger, "Incorrect upgrade authority provided");
return Err(InstructionError::IncorrectAuthority);
}
if authority.signer_key().is_none() {
log!(logger, "Upgrade authority did not sign");
@@ -550,36 +571,55 @@ fn process_loader_upgradeable_instruction(
log!(logger, "Upgraded program {:?}", program.unsigned_key());
}
UpgradeableLoaderInstruction::SetAuthority => {
let programdata = next_keyed_account(account_iter)?;
let account = next_keyed_account(account_iter)?;
let present_authority = next_keyed_account(account_iter)?;
let new_authority = next_keyed_account(account_iter)
.ok()
.map(|account| account.unsigned_key());
if let UpgradeableLoaderState::ProgramData {
slot,
upgrade_authority_address,
} = programdata.state()?
{
if upgrade_authority_address == None {
log!(logger, "Program not upgradeable");
return Err(InstructionError::InvalidArgument);
match account.state()? {
UpgradeableLoaderState::Buffer { authority_address } => {
if authority_address == None {
log!(logger, "Buffer is immutable");
return Err(InstructionError::Immutable);
}
if authority_address != Some(*present_authority.unsigned_key()) {
log!(logger, "Incorrect buffer authority provided");
return Err(InstructionError::IncorrectAuthority);
}
if present_authority.signer_key().is_none() {
log!(logger, "Buffer authority did not sign");
return Err(InstructionError::MissingRequiredSignature);
}
account.set_state(&UpgradeableLoaderState::Buffer {
authority_address: new_authority.cloned(),
})?;
}
if upgrade_authority_address != Some(*present_authority.unsigned_key()) {
log!(logger, "Upgrade authority not present");
return Err(InstructionError::MissingRequiredSignature);
}
if present_authority.signer_key().is_none() {
log!(logger, "Upgrade authority did not sign");
return Err(InstructionError::MissingRequiredSignature);
}
programdata.set_state(&UpgradeableLoaderState::ProgramData {
UpgradeableLoaderState::ProgramData {
slot,
upgrade_authority_address: new_authority.cloned(),
})?;
} else {
log!(logger, "Not a ProgramData account");
return Err(InstructionError::InvalidAccountData);
upgrade_authority_address,
} => {
if upgrade_authority_address == None {
log!(logger, "Program not upgradeable");
return Err(InstructionError::Immutable);
}
if upgrade_authority_address != Some(*present_authority.unsigned_key()) {
log!(logger, "Incorrect upgrade authority provided");
return Err(InstructionError::IncorrectAuthority);
}
if present_authority.signer_key().is_none() {
log!(logger, "Upgrade authority did not sign");
return Err(InstructionError::MissingRequiredSignature);
}
account.set_state(&UpgradeableLoaderState::ProgramData {
slot,
upgrade_authority_address: new_authority.cloned(),
})?;
}
_ => {
log!(logger, "Account does not support authorities");
return Err(InstructionError::InvalidAccountData);
}
}
log!(logger, "New authority {:?}", new_authority);
@@ -606,7 +646,16 @@ fn process_loader_instruction(
}
match limited_deserialize(instruction_data)? {
LoaderInstruction::Write { offset, bytes } => {
write_program_data(program, offset as usize, &bytes, invoke_context)?;
if program.signer_key().is_none() {
log!(logger, "Program account did not sign");
return Err(InstructionError::MissingRequiredSignature);
}
write_program_data(
&mut program.try_account_ref_mut()?.data,
offset as usize,
&bytes,
invoke_context,
)?;
}
LoaderInstruction::Finalize => {
if program.signer_key().is_none() {
@@ -664,6 +713,7 @@ impl Executor for BPFExecutor {
fn execute(
&self,
loader_id: &Pubkey,
program_id: &Pubkey,
keyed_accounts: &[KeyedAccount],
instruction_data: &[u8],
invoke_context: &mut dyn InvokeContext,
@@ -676,12 +726,8 @@ impl Executor for BPFExecutor {
let program = next_keyed_account(&mut keyed_accounts_iter)?;
let parameter_accounts = keyed_accounts_iter.as_slice();
let mut parameter_bytes = serialize_parameters(
loader_id,
program.unsigned_key(),
parameter_accounts,
&instruction_data,
)?;
let mut parameter_bytes =
serialize_parameters(loader_id, program_id, parameter_accounts, &instruction_data)?;
{
let compute_meter = invoke_context.get_compute_meter();
let mut vm = match create_vm(
@@ -1152,26 +1198,68 @@ mod tests {
Ok(()),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, false, &buffer_account),],
&[KeyedAccount::new(&buffer_address, false, &buffer_account)],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(state, UpgradeableLoaderState::Buffer);
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: None
}
);
// Case: Already initialized
assert_eq!(
Err(InstructionError::AccountAlreadyInitialized),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, false, &buffer_account),],
&[KeyedAccount::new(&buffer_address, false, &buffer_account)],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(state, UpgradeableLoaderState::Buffer);
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: None
}
);
// Case: With authority
let buffer_account = Account::new_ref(
1,
UpgradeableLoaderState::buffer_len(9).unwrap(),
&bpf_loader_upgradeable::id(),
);
let authority_address = Pubkey::new_unique();
let authority_account = Account::new_ref(
1,
UpgradeableLoaderState::buffer_len(9).unwrap(),
&bpf_loader_upgradeable::id(),
);
assert_eq!(
Ok(()),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&authority_address, false, &authority_account)
],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: Some(authority_address)
}
);
}
#[test]
@@ -1193,7 +1281,10 @@ mod tests {
Err(InstructionError::InvalidAccountData),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, true, &buffer_account),],
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&buffer_address, true, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
@@ -1207,19 +1298,29 @@ mod tests {
.unwrap();
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Ok(()),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, true, &buffer_account),],
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&buffer_address, true, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(state, UpgradeableLoaderState::Buffer);
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address)
}
);
assert_eq!(
&buffer_account.borrow().data[UpgradeableLoaderState::buffer_data_offset().unwrap()..],
&[42; 9]
@@ -1238,19 +1339,29 @@ mod tests {
);
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Ok(()),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, true, &buffer_account),],
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&buffer_address, true, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(state, UpgradeableLoaderState::Buffer);
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address)
}
);
assert_eq!(
&buffer_account.borrow().data[UpgradeableLoaderState::buffer_data_offset().unwrap()..],
&[0, 0, 0, 42, 42, 42, 42, 42, 42]
@@ -1264,13 +1375,18 @@ mod tests {
.unwrap();
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::MissingRequiredSignature),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, false, &buffer_account),],
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&buffer_address, false, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
@@ -1284,13 +1400,18 @@ mod tests {
.unwrap();
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::AccountDataTooSmall),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, true, &buffer_account),],
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&buffer_address, true, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
@@ -1304,13 +1425,44 @@ mod tests {
.unwrap();
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::AccountDataTooSmall),
process_instruction(
&bpf_loader_upgradeable::id(),
&[KeyedAccount::new(&buffer_address, true, &buffer_account),],
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&buffer_address, true, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
);
// Case: wrong authority
let authority_address = Pubkey::new_unique();
let instruction = bincode::serialize(&UpgradeableLoaderInstruction::Write {
offset: 1,
bytes: vec![42; 9],
})
.unwrap();
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::IncorrectAuthority),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new(&authority_address, true, &buffer_account)
],
&instruction,
&mut MockInvokeContext::default()
)
@@ -1351,7 +1503,9 @@ mod tests {
&bpf_loader_upgradeable::id(),
);
buffer_account
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
buffer_account.data[UpgradeableLoaderState::buffer_data_offset().unwrap()..]
.copy_from_slice(&elf);
@@ -1773,6 +1927,7 @@ mod tests {
#[allow(clippy::type_complexity)]
fn get_accounts(
buffer_authority: &Pubkey,
programdata_address: &Pubkey,
upgrade_authority_address: &Pubkey,
slot: u64,
@@ -1793,7 +1948,9 @@ mod tests {
);
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(*buffer_authority),
})
.unwrap();
buffer_account.borrow_mut().data
[UpgradeableLoaderState::buffer_data_offset().unwrap()..]
@@ -1834,6 +1991,7 @@ mod tests {
// Case: Success
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -1888,6 +2046,7 @@ mod tests {
// Case: not upgradable
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -1904,7 +2063,7 @@ mod tests {
})
.unwrap();
assert_eq!(
Err(InstructionError::InvalidArgument),
Err(InstructionError::Immutable),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
@@ -1927,6 +2086,7 @@ mod tests {
// Case: wrong authority
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -1936,7 +2096,7 @@ mod tests {
min_programdata_balance,
);
assert_eq!(
Err(InstructionError::MissingRequiredSignature),
Err(InstructionError::IncorrectAuthority),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
@@ -1959,6 +2119,7 @@ mod tests {
// Case: authority did not sign
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -1991,6 +2152,7 @@ mod tests {
// Case: Program account not executable
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2024,6 +2186,7 @@ mod tests {
// Case: Program account now owned by loader
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2057,6 +2220,7 @@ mod tests {
// Case: Program account not initialized
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2093,6 +2257,7 @@ mod tests {
// Case: ProgramData account not initialized
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2129,6 +2294,7 @@ mod tests {
// Case: Program ProgramData account mismatch
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2161,6 +2327,7 @@ mod tests {
// Case: Buffer account not initialized
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2174,7 +2341,7 @@ mod tests {
.set_state(&UpgradeableLoaderState::Uninitialized)
.unwrap();
assert_eq!(
Err(InstructionError::InvalidAccountData),
Err(InstructionError::InvalidArgument),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
@@ -2197,6 +2364,7 @@ mod tests {
// Case: Buffer account too big
let (_, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2212,7 +2380,9 @@ mod tests {
);
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer)
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(buffer_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::AccountDataTooSmall),
@@ -2238,6 +2408,7 @@ mod tests {
// Case: bad elf data
let (buffer_account, program_account, programdata_account, spill_account) = get_accounts(
&buffer_address,
&programdata_address,
&upgrade_authority_address,
slot,
@@ -2393,7 +2564,7 @@ mod tests {
})
.unwrap();
assert_eq!(
Err(InstructionError::MissingRequiredSignature),
Err(InstructionError::IncorrectAuthority),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
@@ -2423,7 +2594,7 @@ mod tests {
})
.unwrap();
assert_eq!(
Err(InstructionError::InvalidArgument),
Err(InstructionError::Immutable),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
@@ -2464,6 +2635,165 @@ mod tests {
);
}
#[test]
fn test_bpf_loader_upgradeable_set_buffer_authority() {
let instruction = bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap();
let authority_address = Pubkey::new_unique();
let authority_account = Account::new_ref(1, 0, &Pubkey::new_unique());
let new_authority_address = Pubkey::new_unique();
let new_authority_account = Account::new_ref(1, 0, &Pubkey::new_unique());
let buffer_address = Pubkey::new_unique();
let buffer_account = Account::new_ref(
1,
UpgradeableLoaderState::buffer_len(0).unwrap(),
&bpf_loader_upgradeable::id(),
);
// Case: Set to new authority
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(authority_address),
})
.unwrap();
assert_eq!(
Ok(()),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new_readonly(&authority_address, true, &authority_account),
KeyedAccount::new_readonly(
&new_authority_address,
false,
&new_authority_account
)
],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: Some(new_authority_address),
}
);
// Case: Not upgradeable
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(authority_address),
})
.unwrap();
assert_eq!(
Ok(()),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new_readonly(&authority_address, true, &authority_account)
],
&instruction,
&mut MockInvokeContext::default()
)
);
let state: UpgradeableLoaderState = buffer_account.borrow().state().unwrap();
assert_eq!(
state,
UpgradeableLoaderState::Buffer {
authority_address: None,
}
);
// Case: Authority did not sign
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(authority_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::MissingRequiredSignature),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new_readonly(&authority_address, false, &authority_account),
],
&instruction,
&mut MockInvokeContext::default()
)
);
// Case: wrong authority
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: Some(authority_address),
})
.unwrap();
assert_eq!(
Err(InstructionError::IncorrectAuthority),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account),
KeyedAccount::new_readonly(
&new_authority_address,
false,
&new_authority_account
)
],
&instruction,
&mut MockInvokeContext::default()
)
);
// Case: No authority
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Buffer {
authority_address: None,
})
.unwrap();
assert_eq!(
Err(InstructionError::Immutable),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account),
],
&bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(),
&mut MockInvokeContext::default()
)
);
// Case: Not a Buffer account
buffer_account
.borrow_mut()
.set_state(&UpgradeableLoaderState::Program {
programdata_address: Pubkey::new_unique(),
})
.unwrap();
assert_eq!(
Err(InstructionError::InvalidAccountData),
process_instruction(
&bpf_loader_upgradeable::id(),
&[
KeyedAccount::new(&buffer_address, false, &buffer_account),
KeyedAccount::new_readonly(&Pubkey::new_unique(), true, &authority_account),
],
&bincode::serialize(&UpgradeableLoaderInstruction::SetAuthority).unwrap(),
&mut MockInvokeContext::default()
)
);
}
/// fuzzing utility function
fn fuzz<F>(
bytes: &[u8],

View File

@@ -19,7 +19,7 @@ use solana_sdk::{
feature_set::{
limit_cpi_loader_invoke, pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled,
sha256_syscall_enabled, sol_log_compute_units_syscall,
try_find_program_address_syscall_enabled,
try_find_program_address_syscall_enabled, use_loaded_program_accounts,
},
hash::{Hasher, HASH_BYTES},
instruction::{AccountMeta, Instruction, InstructionError},
@@ -851,6 +851,7 @@ trait SyscallInvokeSigned<'a> {
) -> Result<Instruction, EbpfError<BPFError>>;
fn translate_accounts(
&self,
skip_program: bool,
account_keys: &[Pubkey],
program_account_index: usize,
account_infos_addr: u64,
@@ -913,6 +914,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
fn translate_accounts(
&self,
skip_program: bool,
account_keys: &[Pubkey],
program_account_index: usize,
account_infos_addr: u64,
@@ -933,7 +935,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedRust<'a> {
let mut accounts = Vec::with_capacity(account_keys.len());
let mut refs = Vec::with_capacity(account_keys.len());
'root: for (i, account_key) in account_keys.iter().enumerate() {
if i == program_account_index {
if skip_program && i == program_account_index {
// Don't look for caller passed executable, runtime already has it
continue 'root;
}
@@ -1199,6 +1201,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
fn translate_accounts(
&self,
skip_program: bool,
account_keys: &[Pubkey],
program_account_index: usize,
account_infos_addr: u64,
@@ -1214,7 +1217,7 @@ impl<'a> SyscallInvokeSigned<'a> for SyscallInvokeSignedC<'a> {
let mut accounts = Vec::with_capacity(account_keys.len());
let mut refs = Vec::with_capacity(account_keys.len());
'root: for (i, account_key) in account_keys.iter().enumerate() {
if i == program_account_index {
if skip_program && i == program_account_index {
// Don't look for caller passed executable, runtime already has it
continue 'root;
}
@@ -1374,11 +1377,15 @@ fn check_instruction_size(
Ok(())
}
fn check_authorized_program(program_id: &Pubkey) -> Result<(), EbpfError<BPFError>> {
fn check_authorized_program(
program_id: &Pubkey,
instruction_data: &[u8],
) -> Result<(), EbpfError<BPFError>> {
if native_loader::check_id(program_id)
|| bpf_loader::check_id(program_id)
|| bpf_loader_deprecated::check_id(program_id)
|| bpf_loader_upgradeable::check_id(program_id)
|| (bpf_loader_upgradeable::check_id(program_id)
&& !bpf_loader_upgradeable::is_upgrade_instruction(instruction_data))
{
return Err(SyscallError::InstructionError(InstructionError::UnsupportedProgramId).into());
}
@@ -1400,6 +1407,9 @@ fn call<'a>(
.get_compute_meter()
.consume(invoke_context.get_bpf_compute_budget().invoke_units)?;
let use_loaded_program_accounts =
invoke_context.is_feature_active(&use_loaded_program_accounts::id());
// Translate and verify caller's data
let instruction = syscall.translate_instruction(
@@ -1422,15 +1432,16 @@ fn call<'a>(
.get_callers_keyed_accounts()
.iter()
.collect::<Vec<&KeyedAccount>>();
let (message, callee_program_id, program_id_index) =
let (message, callee_program_id, callee_program_id_index) =
MessageProcessor::create_message(&instruction, &keyed_account_refs, &signers)
.map_err(SyscallError::InstructionError)?;
if invoke_context.is_feature_active(&limit_cpi_loader_invoke::id()) {
check_authorized_program(&callee_program_id)?;
check_authorized_program(&callee_program_id, &instruction.data)?;
}
let (mut accounts, mut account_refs) = syscall.translate_accounts(
use_loaded_program_accounts,
&message.account_keys,
program_id_index,
callee_program_id_index,
account_infos_addr,
account_infos_len,
memory_mapping,
@@ -1440,12 +1451,21 @@ fn call<'a>(
invoke_context.record_instruction(&instruction);
let program_account =
invoke_context
.get_account(&callee_program_id)
let program_account = if use_loaded_program_accounts {
let program_account = invoke_context.get_account(&callee_program_id).ok_or(
SyscallError::InstructionError(InstructionError::MissingAccount),
)?;
accounts.insert(callee_program_id_index, Rc::new(program_account.clone()));
account_refs.insert(callee_program_id_index, None);
program_account
} else {
(**accounts
.get(callee_program_id_index)
.ok_or(SyscallError::InstructionError(
InstructionError::MissingAccount,
))?;
))?)
.clone()
};
if !program_account.borrow().executable {
return Err(SyscallError::InstructionError(InstructionError::AccountNotExecutable).into());
}
@@ -1470,8 +1490,6 @@ fn call<'a>(
} else {
None
};
accounts.insert(program_id_index, Rc::new(program_account.clone()));
account_refs.insert(program_id_index, None);
let mut executable_accounts = vec![(callee_program_id, program_account)];
if let Some(programdata) = programdata_executable {
executable_accounts.push(programdata);

View File

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

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-config-program"
version = "1.5.1"
version = "1.5.2"
description = "Solana Config program"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,10 +14,10 @@ chrono = { version = "0.4.11", features = ["serde"] }
log = "0.4.11"
serde = "1.0.112"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.5.1" }
solana-sdk = { path = "../../sdk", version = "1.5.2" }
[dev-dependencies]
solana-logger = { path = "../../logger", version = "1.5.1" }
solana-logger = { path = "../../logger", version = "1.5.2" }
[lib]
crate-type = ["lib"]

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