Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
55836d133e | ||
|
277e402d55 | ||
|
0ab8312b23 | ||
|
bc4c5c5a97 | ||
|
1a9aa78129 | ||
|
798a6db915 | ||
|
0a4a3fd37e | ||
|
66242eab41 | ||
|
7f0d4f0656 | ||
|
acba8d6026 |
1093
Cargo.lock
generated
1093
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ members = [
|
||||
"log-analyzer",
|
||||
"merkle-tree",
|
||||
"stake-o-matic",
|
||||
"storage-bigtable",
|
||||
"streamer",
|
||||
"measure",
|
||||
"metrics",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana account decoder"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,8 +13,8 @@ bincode = "1.2.1"
|
||||
bs58 = "0.3.1"
|
||||
Inflector = "0.11.4"
|
||||
lazy_static = "1.4.0"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
|
||||
serde = "1.0.112"
|
||||
serde_derive = "1.0.103"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-accounts-bench"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -10,10 +10,10 @@ homepage = "https://solana.com/"
|
||||
[dependencies]
|
||||
log = "0.4.6"
|
||||
rayon = "1.3.0"
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
rand = "0.7.0"
|
||||
clap = "2.33.1"
|
||||
crossbeam-channel = "0.4"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-banking-bench"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,16 +13,16 @@ crossbeam-channel = "0.4"
|
||||
log = "0.4.6"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.19" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.20" }
|
||||
solana-perf = { path = "../perf", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-exchange"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -18,21 +18,21 @@ rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.20" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.19" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,18 +2,18 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-streamer"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-tps"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,23 +14,23 @@ log = "0.4.8"
|
||||
rayon = "1.3.0"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.4.0"
|
||||
serial_test_derive = "0.4.0"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.19" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -7,7 +7,7 @@ source multinode-demo/common.sh
|
||||
|
||||
rm -rf config/run/init-completed config/ledger config/snapshot-ledger
|
||||
|
||||
timeout 15 ./run.sh &
|
||||
timeout 120 ./run.sh &
|
||||
pid=$!
|
||||
|
||||
attempts=20
|
||||
|
@@ -27,5 +27,5 @@ Alternatively, you can source it from within a script:
|
||||
local PATCH=0
|
||||
local SPECIAL=""
|
||||
|
||||
semverParseInto "1.2.19" MAJOR MINOR PATCH SPECIAL
|
||||
semverParseInto "1.2.20" MAJOR MINOR PATCH SPECIAL
|
||||
semverParseInto "3.2.1" MAJOR MINOR PATCH SPECIAL
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana utilities for the clap"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -11,8 +11,8 @@ edition = "2018"
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
rpassword = "4.0"
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
thiserror = "1.0.11"
|
||||
tiny-bip39 = "0.7.0"
|
||||
url = "2.1.0"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli-config"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -27,29 +27,29 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.53"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.19" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.20" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.20" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.20" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.20" }
|
||||
thiserror = "1.0.19"
|
||||
url = "2.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.20" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -256,9 +256,8 @@ impl ClusterQuerySubCommands for App<'_, '_> {
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("transaction-history")
|
||||
.about("Show historical transactions affecting the given address, \
|
||||
ordered based on the slot in which they were confirmed in \
|
||||
from lowest to highest slot")
|
||||
.about("Show historical transactions affecting the given address \
|
||||
from newest to oldest")
|
||||
.arg(
|
||||
pubkey!(Arg::with_name("address")
|
||||
.index(1)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,11 +19,11 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.53"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
tungstenite = "0.10.1"
|
||||
url = "2.1.1"
|
||||
@@ -32,7 +32,7 @@ url = "2.1.1"
|
||||
assert_matches = "1.3.0"
|
||||
jsonrpc-core = "14.1.0"
|
||||
jsonrpc-http-server = "14.1.0"
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-core"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "../README.md"
|
||||
@@ -42,37 +42,38 @@ regex = "1.3.7"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.53"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.19" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.19" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.20" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.20" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.20" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.20" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-perf = { path = "../perf", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.2.20" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.20" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.20" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.20" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.20" }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
tokio = "0.1"
|
||||
tokio-codec = "0.1"
|
||||
tokio-fs = "0.1"
|
||||
tokio-io = "0.1"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
tokio = { version = "0.2.22", features = ["full"] }
|
||||
tokio_01 = { version = "0.1", package = "tokio" }
|
||||
tokio_fs_01 = { version = "0.1", package = "tokio-fs" }
|
||||
tokio_io_01 = { version = "0.1", package = "tokio-io" }
|
||||
trees = "0.2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
144
core/src/rpc.rs
144
core/src/rpc.rs
@@ -64,6 +64,7 @@ use std::{
|
||||
str::FromStr,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use tokio::runtime;
|
||||
|
||||
fn new_response<T>(bank: &Bank, value: T) -> Result<RpcResponse<T>> {
|
||||
let context = RpcResponseContext { slot: bank.slot() };
|
||||
@@ -78,6 +79,7 @@ pub struct JsonRpcConfig {
|
||||
pub identity_pubkey: Pubkey,
|
||||
pub faucet_addr: Option<SocketAddr>,
|
||||
pub health_check_slot_distance: u64,
|
||||
pub enable_bigtable_ledger_storage: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -91,6 +93,8 @@ pub struct JsonRpcRequestProcessor {
|
||||
cluster_info: Arc<ClusterInfo>,
|
||||
genesis_hash: Hash,
|
||||
send_transaction_service: Arc<SendTransactionService>,
|
||||
runtime_handle: runtime::Handle,
|
||||
bigtable_ledger_storage: Option<solana_storage_bigtable::LedgerStorage>,
|
||||
}
|
||||
impl Metadata for JsonRpcRequestProcessor {}
|
||||
|
||||
@@ -145,6 +149,7 @@ impl JsonRpcRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
config: JsonRpcConfig,
|
||||
bank_forks: Arc<RwLock<BankForks>>,
|
||||
@@ -155,6 +160,8 @@ impl JsonRpcRequestProcessor {
|
||||
cluster_info: Arc<ClusterInfo>,
|
||||
genesis_hash: Hash,
|
||||
send_transaction_service: Arc<SendTransactionService>,
|
||||
runtime: &runtime::Runtime,
|
||||
bigtable_ledger_storage: Option<solana_storage_bigtable::LedgerStorage>,
|
||||
) -> Self {
|
||||
Self {
|
||||
config,
|
||||
@@ -166,6 +173,8 @@ impl JsonRpcRequestProcessor {
|
||||
cluster_info,
|
||||
genesis_hash,
|
||||
send_transaction_service,
|
||||
runtime_handle: runtime.handle().clone(),
|
||||
bigtable_ledger_storage,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,6 +516,7 @@ impl JsonRpcRequestProcessor {
|
||||
slot: Slot,
|
||||
encoding: Option<UiTransactionEncoding>,
|
||||
) -> Result<Option<ConfirmedBlock>> {
|
||||
let encoding = encoding.unwrap_or(UiTransactionEncoding::Json);
|
||||
if self.config.enable_rpc_transaction_history
|
||||
&& slot
|
||||
<= self
|
||||
@@ -515,7 +525,15 @@ impl JsonRpcRequestProcessor {
|
||||
.unwrap()
|
||||
.largest_confirmed_root()
|
||||
{
|
||||
let result = self.blockstore.get_confirmed_block(slot, encoding);
|
||||
let result = self.blockstore.get_confirmed_block(slot, Some(encoding));
|
||||
if result.is_err() {
|
||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||
return Ok(self
|
||||
.runtime_handle
|
||||
.block_on(bigtable_ledger_storage.get_confirmed_block(slot, encoding))
|
||||
.ok());
|
||||
}
|
||||
}
|
||||
self.check_slot_cleaned_up(&result, slot)?;
|
||||
Ok(result.ok())
|
||||
} else {
|
||||
@@ -544,9 +562,25 @@ impl JsonRpcRequestProcessor {
|
||||
MAX_GET_CONFIRMED_BLOCKS_RANGE
|
||||
)));
|
||||
}
|
||||
|
||||
let lowest_slot = self.blockstore.lowest_slot();
|
||||
if start_slot < lowest_slot {
|
||||
// If the starting slot is lower than what's available in blockstore assume the entire
|
||||
// [start_slot..end_slot] can be fetched from BigTable.
|
||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||
return Ok(self
|
||||
.runtime_handle
|
||||
.block_on(
|
||||
bigtable_ledger_storage
|
||||
.get_confirmed_blocks(start_slot, (end_slot - start_slot) as usize),
|
||||
)
|
||||
.unwrap_or_else(|_| vec![]));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self
|
||||
.blockstore
|
||||
.rooted_slot_iterator(max(start_slot, self.blockstore.lowest_slot()))
|
||||
.rooted_slot_iterator(max(start_slot, lowest_slot))
|
||||
.map_err(|_| Error::internal_error())?
|
||||
.filter(|&slot| slot <= end_slot)
|
||||
.collect())
|
||||
@@ -640,6 +674,16 @@ impl JsonRpcRequestProcessor {
|
||||
err,
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||
self.runtime_handle
|
||||
.block_on(bigtable_ledger_storage.get_signature_status(&signature))
|
||||
.map(Some)
|
||||
.unwrap_or(None)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -681,23 +725,39 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
signature: Signature,
|
||||
encoding: Option<UiTransactionEncoding>,
|
||||
) -> Result<Option<ConfirmedTransaction>> {
|
||||
) -> Option<ConfirmedTransaction> {
|
||||
let encoding = encoding.unwrap_or(UiTransactionEncoding::Json);
|
||||
if self.config.enable_rpc_transaction_history {
|
||||
Ok(self
|
||||
match self
|
||||
.blockstore
|
||||
.get_confirmed_transaction(signature, encoding)
|
||||
.get_confirmed_transaction(signature, Some(encoding))
|
||||
.unwrap_or(None)
|
||||
.filter(|confirmed_transaction| {
|
||||
confirmed_transaction.slot
|
||||
{
|
||||
Some(confirmed_transaction) => {
|
||||
if confirmed_transaction.slot
|
||||
<= self
|
||||
.block_commitment_cache
|
||||
.read()
|
||||
.unwrap()
|
||||
.largest_confirmed_root()
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
.highest_confirmed_slot()
|
||||
{
|
||||
return Some(confirmed_transaction);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||
return self
|
||||
.runtime_handle
|
||||
.block_on(
|
||||
bigtable_ledger_storage
|
||||
.get_confirmed_transaction(&signature, encoding),
|
||||
)
|
||||
.unwrap_or(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_confirmed_signatures_for_address(
|
||||
@@ -707,6 +767,8 @@ impl JsonRpcRequestProcessor {
|
||||
end_slot: Slot,
|
||||
) -> Result<Vec<Signature>> {
|
||||
if self.config.enable_rpc_transaction_history {
|
||||
// TODO: Add bigtable_ledger_storage support as a part of
|
||||
// https://github.com/solana-labs/solana/pull/10928
|
||||
let end_slot = min(
|
||||
end_slot,
|
||||
self.block_commitment_cache
|
||||
@@ -724,17 +786,30 @@ impl JsonRpcRequestProcessor {
|
||||
}
|
||||
|
||||
pub fn get_first_available_block(&self) -> Result<Slot> {
|
||||
Ok(self
|
||||
let slot = self
|
||||
.blockstore
|
||||
.get_first_available_block()
|
||||
.unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||
let bigtable_slot = self
|
||||
.runtime_handle
|
||||
.block_on(bigtable_ledger_storage.get_first_available_block())
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(slot);
|
||||
|
||||
if bigtable_slot < slot {
|
||||
return Ok(bigtable_slot);
|
||||
}
|
||||
}
|
||||
Ok(slot)
|
||||
}
|
||||
|
||||
pub fn get_confirmed_signatures_for_address2(
|
||||
&self,
|
||||
address: Pubkey,
|
||||
before: Option<Signature>,
|
||||
limit: usize,
|
||||
mut before: Option<Signature>,
|
||||
mut limit: usize,
|
||||
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>> {
|
||||
if self.config.enable_rpc_transaction_history {
|
||||
let highest_confirmed_root = self
|
||||
@@ -743,7 +818,7 @@ impl JsonRpcRequestProcessor {
|
||||
.unwrap()
|
||||
.highest_confirmed_slot();
|
||||
|
||||
let results = self
|
||||
let mut results = self
|
||||
.blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address,
|
||||
@@ -753,6 +828,27 @@ impl JsonRpcRequestProcessor {
|
||||
)
|
||||
.map_err(|err| Error::invalid_params(format!("{}", err)))?;
|
||||
|
||||
if results.len() < limit {
|
||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||
if !results.is_empty() {
|
||||
limit -= results.len();
|
||||
before = results.last().map(|x| x.signature);
|
||||
}
|
||||
|
||||
let mut bigtable_results = self
|
||||
.runtime_handle
|
||||
.block_on(
|
||||
bigtable_ledger_storage.get_confirmed_signatures_for_address(
|
||||
&address,
|
||||
before.as_ref(),
|
||||
limit,
|
||||
),
|
||||
)
|
||||
.map_err(|err| Error::invalid_params(format!("{}", err)))?;
|
||||
results.append(&mut bigtable_results)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(results.into_iter().map(|x| x.into()).collect())
|
||||
} else {
|
||||
Ok(vec![])
|
||||
@@ -2008,7 +2104,7 @@ impl RpcSol for RpcSolImpl {
|
||||
signature_str
|
||||
);
|
||||
let signature = verify_signature(&signature_str)?;
|
||||
meta.get_confirmed_transaction(signature, encoding)
|
||||
Ok(meta.get_confirmed_transaction(signature, encoding))
|
||||
}
|
||||
|
||||
fn get_confirmed_signatures_for_address(
|
||||
@@ -2379,6 +2475,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
|
||||
cluster_info.insert_info(ContactInfo::new_with_pubkey_socketaddr(
|
||||
@@ -2430,6 +2528,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
thread::spawn(move || {
|
||||
let blockhash = bank.confirmed_last_blockhash().0;
|
||||
@@ -3526,6 +3626,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
|
||||
let req = r#"{"jsonrpc":"2.0","id":1,"method":"sendTransaction","params":["37u9WtQpcm6ULa3Vmu7ySnANv"]}"#;
|
||||
@@ -3570,6 +3672,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
|
||||
let mut bad_transaction =
|
||||
@@ -3764,6 +3868,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(request_processor.validator_exit(), Ok(false));
|
||||
assert_eq!(exit.load(Ordering::Relaxed), false);
|
||||
@@ -3796,6 +3902,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(request_processor.validator_exit(), Ok(true));
|
||||
assert_eq!(exit.load(Ordering::Relaxed), true);
|
||||
@@ -3887,6 +3995,8 @@ pub mod tests {
|
||||
&bank_forks,
|
||||
&exit,
|
||||
)),
|
||||
&runtime::Runtime::new().unwrap(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(
|
||||
request_processor.get_block_commitment(0),
|
||||
|
@@ -24,7 +24,7 @@ use std::{
|
||||
sync::{mpsc::channel, Arc, RwLock},
|
||||
thread::{self, Builder, JoinHandle},
|
||||
};
|
||||
use tokio::prelude::Future;
|
||||
use tokio::runtime;
|
||||
|
||||
pub struct JsonRpcService {
|
||||
thread_hdl: JoinHandle<()>,
|
||||
@@ -33,6 +33,7 @@ pub struct JsonRpcService {
|
||||
pub request_processor: JsonRpcRequestProcessor, // Used only by test_rpc_new()...
|
||||
|
||||
close_handle: Option<CloseHandle>,
|
||||
runtime: runtime::Runtime,
|
||||
}
|
||||
|
||||
struct RpcRequestMiddleware {
|
||||
@@ -98,6 +99,9 @@ impl RpcRequestMiddleware {
|
||||
}
|
||||
|
||||
fn process_file_get(&self, path: &str) -> RequestMiddlewareAction {
|
||||
// Stuck on tokio 0.1 until the jsonrpc-http-server crate upgrades to tokio 0.2
|
||||
use tokio_01::prelude::*;
|
||||
|
||||
let stem = path.split_at(1).1; // Drop leading '/' from path
|
||||
let filename = {
|
||||
match path {
|
||||
@@ -116,10 +120,10 @@ impl RpcRequestMiddleware {
|
||||
RequestMiddlewareAction::Respond {
|
||||
should_validate_hosts: true,
|
||||
response: Box::new(
|
||||
tokio_fs::file::File::open(filename)
|
||||
tokio_fs_01::file::File::open(filename)
|
||||
.and_then(|file| {
|
||||
let buf: Vec<u8> = Vec::new();
|
||||
tokio_io::io::read_to_end(file, buf)
|
||||
tokio_io_01::io::read_to_end(file, buf)
|
||||
.and_then(|item| Ok(hyper::Response::new(item.1.into())))
|
||||
.or_else(|_| Ok(RpcRequestMiddleware::internal_server_error()))
|
||||
})
|
||||
@@ -256,6 +260,27 @@ impl JsonRpcService {
|
||||
&exit_send_transaction_service,
|
||||
));
|
||||
|
||||
let mut runtime = runtime::Builder::new()
|
||||
.threaded_scheduler()
|
||||
.thread_name("rpc-runtime")
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("Runtime");
|
||||
|
||||
let bigtable_ledger_storage = if config.enable_bigtable_ledger_storage {
|
||||
runtime
|
||||
.block_on(solana_storage_bigtable::LedgerStorage::new(false))
|
||||
.map(|x| {
|
||||
info!("BigTable ledger storage initialized");
|
||||
Some(x)
|
||||
})
|
||||
.unwrap_or_else(|err| {
|
||||
error!("Failed to initialize BigTable ledger storage: {:?}", err);
|
||||
None
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let request_processor = JsonRpcRequestProcessor::new(
|
||||
config,
|
||||
bank_forks.clone(),
|
||||
@@ -266,6 +291,8 @@ impl JsonRpcService {
|
||||
cluster_info,
|
||||
genesis_hash,
|
||||
send_transaction_service,
|
||||
&runtime,
|
||||
bigtable_ledger_storage,
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -325,6 +352,7 @@ impl JsonRpcService {
|
||||
.register_exit(Box::new(move || close_handle_.close()));
|
||||
Self {
|
||||
thread_hdl,
|
||||
runtime,
|
||||
#[cfg(test)]
|
||||
request_processor: test_request_processor,
|
||||
close_handle: Some(close_handle),
|
||||
@@ -338,6 +366,7 @@ impl JsonRpcService {
|
||||
}
|
||||
|
||||
pub fn join(self) -> thread::Result<()> {
|
||||
self.runtime.shutdown_background();
|
||||
self.thread_hdl.join()
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,9 @@ use std::{
|
||||
iter,
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
};
|
||||
use tokio::runtime::{Builder as RuntimeBuilder, Runtime, TaskExecutor};
|
||||
|
||||
// Stuck on tokio 0.1 until the jsonrpc-pubsub crate upgrades to tokio 0.2
|
||||
use tokio_01::runtime::{Builder as RuntimeBuilder, Runtime, TaskExecutor};
|
||||
|
||||
const RECEIVE_DELAY_MILLIS: u64 = 100;
|
||||
|
||||
@@ -965,7 +967,7 @@ pub(crate) mod tests {
|
||||
system_transaction,
|
||||
};
|
||||
use std::{fmt::Debug, sync::mpsc::channel, time::Instant};
|
||||
use tokio::{prelude::FutureExt, runtime::Runtime, timer::Delay};
|
||||
use tokio_01::{prelude::FutureExt, runtime::Runtime, timer::Delay};
|
||||
|
||||
pub(crate) fn robust_poll_or_panic<T: Debug + Send + 'static>(
|
||||
receiver: futures::sync::mpsc::Receiver<T>,
|
||||
|
@@ -26,7 +26,7 @@ use std::{
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio_01::runtime::Runtime;
|
||||
|
||||
macro_rules! json_req {
|
||||
($method: expr, $params: expr) => {{
|
||||
@@ -189,7 +189,7 @@ fn test_rpc_subscriptions() {
|
||||
.and_then(move |client| {
|
||||
for sig in signature_set {
|
||||
let status_sender = status_sender.clone();
|
||||
tokio::spawn(
|
||||
tokio_01::spawn(
|
||||
client
|
||||
.signature_subscribe(sig.clone(), None)
|
||||
.and_then(move |sig_stream| {
|
||||
@@ -203,7 +203,7 @@ fn test_rpc_subscriptions() {
|
||||
}),
|
||||
);
|
||||
}
|
||||
tokio::spawn(
|
||||
tokio_01::spawn(
|
||||
client
|
||||
.slot_subscribe()
|
||||
.and_then(move |slot_stream| {
|
||||
@@ -218,7 +218,7 @@ fn test_rpc_subscriptions() {
|
||||
);
|
||||
for pubkey in account_set {
|
||||
let account_sender = account_sender.clone();
|
||||
tokio::spawn(
|
||||
tokio_01::spawn(
|
||||
client
|
||||
.account_subscribe(pubkey, None)
|
||||
.and_then(move |account_stream| {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-crate-features"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Crate Features"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -46,10 +46,6 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
||||
- [getSlotLeader](jsonrpc-api.md#getslotleader)
|
||||
- [getStakeActivation](jsonrpc-api.md#getstakeactivation)
|
||||
- [getSupply](jsonrpc-api.md#getsupply)
|
||||
- [getTokenAccountBalance](jsonrpc-api.md#gettokenaccountbalance)
|
||||
- [getTokenAccountsByDelegate](jsonrpc-api.md#gettokenaccountsbydelegate)
|
||||
- [getTokenAccountsByOwner](jsonrpc-api.md#gettokenaccountsbyowner)
|
||||
- [getTokenSupply](jsonrpc-api.md#gettokensupply)
|
||||
- [getTransactionCount](jsonrpc-api.md#gettransactioncount)
|
||||
- [getVersion](jsonrpc-api.md#getversion)
|
||||
- [getVoteAccounts](jsonrpc-api.md#getvoteaccounts)
|
||||
@@ -69,6 +65,15 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
||||
- [slotSubscribe](jsonrpc-api.md#slotsubscribe)
|
||||
- [slotUnsubscribe](jsonrpc-api.md#slotunsubscribe)
|
||||
|
||||
## Unstable Methods
|
||||
|
||||
Unstable methods may see breaking changes in patch releases and may not be supported in perpetuity.
|
||||
|
||||
- [getTokenAccountBalance](jsonrpc-api.md#gettokenaccountbalance)
|
||||
- [getTokenAccountsByDelegate](jsonrpc-api.md#gettokenaccountsbydelegate)
|
||||
- [getTokenAccountsByOwner](jsonrpc-api.md#gettokenaccountsbyowner)
|
||||
- [getTokenSupply](jsonrpc-api.md#gettokensupply)
|
||||
|
||||
## Request Formatting
|
||||
|
||||
To make a JSON-RPC request, send an HTTP POST request with a `Content-Type: application/json` header. The JSON request data should contain 4 fields:
|
||||
@@ -152,7 +157,7 @@ Returns all information associated with the account of provided Pubkey
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -300,7 +305,7 @@ Returns identity and transaction information about a confirmed block in the ledg
|
||||
#### Parameters:
|
||||
|
||||
- `<u64>` - slot, as u64 integer
|
||||
- `<string>` - (optional) encoding for each returned Transaction, either "json", "jsonParsed", or "binary". If parameter not provided, the default encoding is JSON.
|
||||
- `<string>` - (optional) encoding for each returned Transaction, either "json", "jsonParsed", or "binary". If parameter not provided, the default encoding is JSON. **jsonParsed encoding is UNSTABLE**
|
||||
Parsed-JSON encoding attempts to use program-specific instruction parsers to return more human-readable and explicit data in the `transaction.message.instructions` list. If parsed-JSON is requested but a parser cannot be found, the instruction falls back to regular JSON encoding (`accounts`, `data`, and `programIdIndex` fields).
|
||||
|
||||
#### Results:
|
||||
@@ -458,7 +463,7 @@ Returns transaction details for a confirmed transaction
|
||||
|
||||
- `<string>` - transaction signature as base-58 encoded string
|
||||
N encoding attempts to use program-specific instruction parsers to return more human-readable and explicit data in the `transaction.message.instructions` list. If parsed-JSON is requested but a parser cannot be found, the instruction falls back to regular JSON encoding (`accounts`, `data`, and `programIdIndex` fields).
|
||||
- `<string>` - (optional) encoding for the returned Transaction, either "json", "jsonParsed", or "binary".
|
||||
- `<string>` - (optional) encoding for the returned Transaction, either "json", "jsonParsed", or "binary". **jsonParsed encoding is UNSTABLE**
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -839,7 +844,7 @@ Returns all accounts owned by the provided program Pubkey
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
|
||||
- (optional) `filters: <array>` - filter results using various [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results
|
||||
|
||||
##### Filters:
|
||||
@@ -1056,7 +1061,7 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
|
||||
|
||||
### getTokenAccountBalance
|
||||
|
||||
Returns the token balance of an SPL Token account.
|
||||
Returns the token balance of an SPL Token account. **UNSTABLE**
|
||||
|
||||
#### Parameters:
|
||||
|
||||
@@ -1082,7 +1087,7 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
|
||||
|
||||
### getTokenAccountsByDelegate
|
||||
|
||||
Returns all SPL Token accounts by approved Delegate.
|
||||
Returns all SPL Token accounts by approved Delegate. **UNSTABLE**
|
||||
|
||||
#### Parameters:
|
||||
|
||||
@@ -1093,7 +1098,7 @@ Returns all SPL Token accounts by approved Delegate.
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -1118,7 +1123,7 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
|
||||
|
||||
### getTokenAccountsByOwner
|
||||
|
||||
Returns all SPL Token accounts by token owner.
|
||||
Returns all SPL Token accounts by token owner. **UNSTABLE**
|
||||
|
||||
#### Parameters:
|
||||
|
||||
@@ -1129,7 +1134,7 @@ Returns all SPL Token accounts by token owner.
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -1154,7 +1159,7 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
|
||||
|
||||
### getTokenSupply
|
||||
|
||||
Returns the total supply of an SPL Token type.
|
||||
Returns the total supply of an SPL Token type. **UNSTABLE**
|
||||
|
||||
#### Parameters:
|
||||
|
||||
@@ -1220,7 +1225,7 @@ The result field will be a JSON object with the following fields:
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.2.19"},"id":1}
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.2.20"},"id":1}
|
||||
```
|
||||
|
||||
### getVoteAccounts
|
||||
@@ -1421,7 +1426,7 @@ Subscribe to an account to receive notifications when the lamports or data for a
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -1529,7 +1534,7 @@ Subscribe to a program to receive notifications when the lamports or data for a
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
|
||||
- (optional) `filters: <array>` - filter results using various [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results
|
||||
|
||||
#### Results:
|
||||
|
106
docs/src/implemented-proposals/rpc-transaction-history.md
Normal file
106
docs/src/implemented-proposals/rpc-transaction-history.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Long term RPC Transaction History
|
||||
There's a need for RPC to serve at least 6 months of transaction history. The
|
||||
current history, on the order of days, is insufficient for downstream users.
|
||||
|
||||
6 months of transaction data cannot be stored practically in a validator's
|
||||
rocksdb ledger so an external data store is necessary. The validator's
|
||||
rocksdb ledger will continue to serve as the primary data source, and then will
|
||||
fall back to the external data store.
|
||||
|
||||
The affected RPC endpoints are:
|
||||
* [getFirstAvailableBlock](https://docs.solana.com/apps/jsonrpc-api#getfirstavailableblock)
|
||||
* [getConfirmedBlock](https://docs.solana.com/apps/jsonrpc-api#getconfirmedblock)
|
||||
* [getConfirmedBlocks](https://docs.solana.com/apps/jsonrpc-api#getconfirmedblocks)
|
||||
* [getConfirmedSignaturesForAddress](https://docs.solana.com/apps/jsonrpc-api#getconfirmedsignaturesforaddress)
|
||||
* [getConfirmedTransaction](https://docs.solana.com/apps/jsonrpc-api#getconfirmedtransaction)
|
||||
* [getSignatureStatuses](https://docs.solana.com/apps/jsonrpc-api#getsignaturestatuses)
|
||||
|
||||
Note that [getBlockTime](https://docs.solana.com/apps/jsonrpc-api#getblocktime)
|
||||
is not supported, as once https://github.com/solana-labs/solana/issues/10089 is
|
||||
fixed then `getBlockTime` can be removed.
|
||||
|
||||
Some system design constraints:
|
||||
* The volume of data to store and search can quickly jump into the terabytes,
|
||||
and is immutable.
|
||||
* The system should be as light as possible for SREs. For example an SQL
|
||||
database cluster that requires an SRE to continually monitor and rebalance
|
||||
nodes is undesirable.
|
||||
* Data must be searchable in real time - batched queries that take minutes or
|
||||
hours to run are unacceptable.
|
||||
* Easy to replicate the data worldwide to co-locate it with the RPC endpoints
|
||||
that will utilize it.
|
||||
* Interfacing with the external data store should be easy and not require
|
||||
depending on risky lightly-used community-supported code libraries
|
||||
|
||||
Based on these constraints, Google's BigTable product is selected as the data
|
||||
store.
|
||||
|
||||
## Table Schema
|
||||
A BigTable instance is used to hold all transaction data, broken up into
|
||||
different tables for quick searching.
|
||||
|
||||
New data may be copied into the instance at anytime without affecting the existing
|
||||
data, and all data is immutable. Generally the expectation is that new data
|
||||
will be uploaded once an current epoch completes but there is no limitation on
|
||||
the frequency of data dumps.
|
||||
|
||||
Cleanup of old data is automatic by configuring the data retention policy of the
|
||||
instance tables appropriately, it just disappears. Therefore the order of when data is
|
||||
added becomes important. For example if data from epoch N-1 is added after data
|
||||
from epoch N, the older epoch data will outlive the newer data. However beyond
|
||||
producing _holes_ in query results, this kind of unordered deletion will
|
||||
have no ill effect. Note that this method of cleanup effectively allows for an
|
||||
unlimited amount of transaction data to be stored, restricted only by the
|
||||
monetary costs of doing so.
|
||||
|
||||
The table layout s supports the existing RPC endpoints only. New RPC endpoints
|
||||
in the future may require additions to the schema and potentially iterating over
|
||||
all transactions to build up the necessary metadata.
|
||||
|
||||
## Accessing BigTable
|
||||
BigTable has a gRPC endpoint that can be accessed using the
|
||||
[tonic](https://crates.io/crates/crate)] and the raw protobuf API, as currently no
|
||||
higher-level Rust crate for BigTable exists. Practically this makes parsing the
|
||||
results of BigTable queries more complicated but is not a significant issue.
|
||||
|
||||
## Data Population
|
||||
The ongoing population of instance data will occur on an epoch cadence through the
|
||||
use of a new `solana-ledger-tool` command that will convert rocksdb data for a
|
||||
given slot range into the instance schema.
|
||||
|
||||
The same process will be run once, manually, to backfill the existing ledger
|
||||
data.
|
||||
|
||||
### Block Table: `block`
|
||||
|
||||
This table contains the compressed block data for a given slot.
|
||||
|
||||
The row key is generated by taking the 16 digit lower case hexadecimal
|
||||
representation of the slot, to ensure that the oldest slot with a confirmed
|
||||
block will always be first when the rows are listed. eg, The row key for slot
|
||||
42 would be 000000000000002a.
|
||||
|
||||
The row data is a compressed `StoredConfirmedBlock` struct.
|
||||
|
||||
|
||||
### Account Address Transaction Signature Lookup Table: `tx-by-addr`
|
||||
|
||||
This table contains the transactions that affect a given address.
|
||||
|
||||
The row key is `<base58
|
||||
address>/<slot-id-one's-compliment-hex-slot-0-prefixed-to-16-digits>`. The row
|
||||
data is a compressed `TransactionByAddrInfo` struct.
|
||||
|
||||
Taking the one's compliment of the slot allows for listing of slots ensures that
|
||||
the newest slot with transactions that affect an address will always
|
||||
be listed first.
|
||||
|
||||
Sysvar addresses are not indexed. However frequently used programs such as
|
||||
Vote or System are, and will likely have a row for every confirmed slot.
|
||||
|
||||
### Transaction Signature Lookup Table: `tx`
|
||||
|
||||
This table maps a transaction signature to its confirmed block, and index within that block.
|
||||
|
||||
The row key is the base58-encoded transaction signature.
|
||||
The row data is a compressed `TransactionInfo` struct.
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-dos"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,14 +13,14 @@ clap = "2.33.1"
|
||||
log = "0.4.8"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-download-utils"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Download Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,8 +14,8 @@ console = "0.10.1"
|
||||
indicatif = "0.14.0"
|
||||
log = "0.4.8"
|
||||
reqwest = { version = "0.10.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
tar = "0.4.28"
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-faucet"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Faucet"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,11 +16,11 @@ clap = "2.33"
|
||||
log = "0.4.8"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
tokio = "0.1"
|
||||
tokio-codec = "0.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-genesis-programs"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana genesis programs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,12 +10,12 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = { version = "0.4.8" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.19" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.20" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.20" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -105,7 +105,11 @@ pub fn get_entered_epoch_callback(operating_mode: OperatingMode) -> EnteredEpoch
|
||||
bank.add_native_program(name, program_id);
|
||||
}
|
||||
}
|
||||
bank.set_cross_program_support(OperatingMode::Stable != operating_mode);
|
||||
if OperatingMode::Stable == operating_mode {
|
||||
bank.set_cross_program_support(bank.epoch() >= 63);
|
||||
} else {
|
||||
bank.set_cross_program_support(true);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-genesis"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,14 +15,14 @@ chrono = "0.4"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,20 +3,20 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-gossip"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-install"
|
||||
description = "The solana cluster software installer"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -24,12 +24,12 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
semver = "0.9.0"
|
||||
tar = "0.4.28"
|
||||
tempdir = "0.3.7"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-keygen"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana key generation utility"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,11 +13,11 @@ bs58 = "0.3.1"
|
||||
clap = "2.33"
|
||||
dirs = "2.0.2"
|
||||
num_cpus = "1.13.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.20" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
tiny-bip39 = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-ledger-tool"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -12,22 +12,27 @@ homepage = "https://solana.com/"
|
||||
bs58 = "0.3.1"
|
||||
bytecount = "0.6.0"
|
||||
clap = "2.33.1"
|
||||
futures = "0.3.5"
|
||||
futures-util = "0.3.5"
|
||||
histogram = "*"
|
||||
log = { version = "0.4.8" }
|
||||
regex = "1"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli = { path = "../cli", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-cli = { path = "../cli", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.2.20" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
tempfile = "3.1.0"
|
||||
regex = "1"
|
||||
tokio = { version = "0.2.22", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "1.0"
|
||||
|
551
ledger-tool/src/bigtable.rs
Normal file
551
ledger-tool/src/bigtable.rs
Normal file
@@ -0,0 +1,551 @@
|
||||
/// The `bigtable` subcommand
|
||||
use clap::{value_t, value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||
use log::*;
|
||||
use solana_clap_utils::{
|
||||
input_parsers::pubkey_of,
|
||||
input_validators::{is_slot, is_valid_pubkey},
|
||||
};
|
||||
use solana_cli::display::println_transaction;
|
||||
use solana_ledger::{blockstore::Blockstore, blockstore_db::AccessType};
|
||||
use solana_measure::measure::Measure;
|
||||
use solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature};
|
||||
use solana_transaction_status::UiTransactionEncoding;
|
||||
use std::{collections::HashSet, path::Path, process::exit, result::Result, time::Duration};
|
||||
use tokio::time::delay_for;
|
||||
|
||||
// Attempt to upload this many blocks in parallel
|
||||
const NUM_BLOCKS_TO_UPLOAD_IN_PARALLEL: usize = 32;
|
||||
|
||||
// Read up to this many blocks from blockstore before blocking on the upload process
|
||||
const BLOCK_READ_AHEAD_DEPTH: usize = NUM_BLOCKS_TO_UPLOAD_IN_PARALLEL * 2;
|
||||
|
||||
async fn upload(
|
||||
blockstore: Blockstore,
|
||||
starting_slot: Slot,
|
||||
ending_slot: Option<Slot>,
|
||||
allow_missing_metadata: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut measure = Measure::start("entire upload");
|
||||
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
info!("Loading ledger slots...");
|
||||
let blockstore_slots: Vec<_> = blockstore
|
||||
.slot_meta_iterator(starting_slot)
|
||||
.map_err(|err| {
|
||||
format!(
|
||||
"Failed to load entries starting from slot {}: {:?}",
|
||||
starting_slot, err
|
||||
)
|
||||
})?
|
||||
.filter_map(|(slot, _slot_meta)| {
|
||||
if let Some(ending_slot) = &ending_slot {
|
||||
if slot > *ending_slot {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(slot)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if blockstore_slots.is_empty() {
|
||||
info!("Ledger has no slots in the specified range");
|
||||
return Ok(());
|
||||
}
|
||||
info!(
|
||||
"Found {} slots in the range ({}, {})",
|
||||
blockstore_slots.len(),
|
||||
blockstore_slots.first().unwrap(),
|
||||
blockstore_slots.last().unwrap()
|
||||
);
|
||||
|
||||
let mut blockstore_slots_with_no_confirmed_block = HashSet::new();
|
||||
|
||||
// Gather the blocks that are already present in bigtable, by slot
|
||||
let bigtable_slots = {
|
||||
let mut bigtable_slots = vec![];
|
||||
let first_blockstore_slot = *blockstore_slots.first().unwrap();
|
||||
let last_blockstore_slot = *blockstore_slots.last().unwrap();
|
||||
info!(
|
||||
"Loading list of bigtable blocks between slots {} and {}...",
|
||||
first_blockstore_slot, last_blockstore_slot
|
||||
);
|
||||
|
||||
let mut start_slot = *blockstore_slots.first().unwrap();
|
||||
while start_slot <= last_blockstore_slot {
|
||||
let mut next_bigtable_slots = loop {
|
||||
match bigtable.get_confirmed_blocks(start_slot, 1000).await {
|
||||
Ok(slots) => break slots,
|
||||
Err(err) => {
|
||||
error!("get_confirmed_blocks for {} failed: {:?}", start_slot, err);
|
||||
// Consider exponential backoff...
|
||||
delay_for(Duration::from_secs(2)).await;
|
||||
}
|
||||
}
|
||||
};
|
||||
if next_bigtable_slots.is_empty() {
|
||||
break;
|
||||
}
|
||||
bigtable_slots.append(&mut next_bigtable_slots);
|
||||
start_slot = bigtable_slots.last().unwrap() + 1;
|
||||
}
|
||||
bigtable_slots
|
||||
.into_iter()
|
||||
.filter(|slot| *slot <= last_blockstore_slot)
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
// The blocks that still need to be uploaded is the difference between what's already in the
|
||||
// bigtable and what's in blockstore...
|
||||
let blocks_to_upload = {
|
||||
let blockstore_slots = blockstore_slots.iter().cloned().collect::<HashSet<_>>();
|
||||
let bigtable_slots = bigtable_slots.into_iter().collect::<HashSet<_>>();
|
||||
|
||||
let mut blocks_to_upload = blockstore_slots
|
||||
.difference(&blockstore_slots_with_no_confirmed_block)
|
||||
.cloned()
|
||||
.collect::<HashSet<_>>()
|
||||
.difference(&bigtable_slots)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
blocks_to_upload.sort();
|
||||
blocks_to_upload
|
||||
};
|
||||
|
||||
if blocks_to_upload.is_empty() {
|
||||
info!("No blocks need to be uploaded to bigtable");
|
||||
return Ok(());
|
||||
}
|
||||
info!(
|
||||
"{} blocks to be uploaded to the bucket in the range ({}, {})",
|
||||
blocks_to_upload.len(),
|
||||
blocks_to_upload.first().unwrap(),
|
||||
blocks_to_upload.last().unwrap()
|
||||
);
|
||||
|
||||
// Load the blocks out of blockstore in a separate thread to allow for concurrent block uploading
|
||||
let (_loader_thread, receiver) = {
|
||||
let (sender, receiver) = std::sync::mpsc::sync_channel(BLOCK_READ_AHEAD_DEPTH);
|
||||
(
|
||||
std::thread::spawn(move || {
|
||||
let mut measure = Measure::start("block loader thread");
|
||||
for (i, slot) in blocks_to_upload.iter().enumerate() {
|
||||
let _ = match blockstore.get_confirmed_block(
|
||||
*slot,
|
||||
Some(solana_transaction_status::UiTransactionEncoding::Binary),
|
||||
) {
|
||||
Ok(confirmed_block) => sender.send((*slot, Some(confirmed_block))),
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"Failed to get load confirmed block from slot {}: {:?}",
|
||||
slot, err
|
||||
);
|
||||
sender.send((*slot, None))
|
||||
}
|
||||
};
|
||||
|
||||
if i % NUM_BLOCKS_TO_UPLOAD_IN_PARALLEL == 0 {
|
||||
info!(
|
||||
"{}% of blocks processed ({}/{})",
|
||||
i * 100 / blocks_to_upload.len(),
|
||||
i,
|
||||
blocks_to_upload.len()
|
||||
);
|
||||
}
|
||||
}
|
||||
measure.stop();
|
||||
info!("{} to load {} blocks", measure, blocks_to_upload.len());
|
||||
}),
|
||||
receiver,
|
||||
)
|
||||
};
|
||||
|
||||
let mut failures = 0;
|
||||
use futures::stream::StreamExt;
|
||||
|
||||
let mut stream =
|
||||
tokio::stream::iter(receiver.into_iter()).chunks(NUM_BLOCKS_TO_UPLOAD_IN_PARALLEL);
|
||||
|
||||
while let Some(blocks) = stream.next().await {
|
||||
let mut measure_upload = Measure::start("Upload");
|
||||
let mut num_blocks = blocks.len();
|
||||
info!("Preparing the next {} blocks for upload", num_blocks);
|
||||
|
||||
let uploads = blocks.into_iter().filter_map(|(slot, block)| match block {
|
||||
None => {
|
||||
blockstore_slots_with_no_confirmed_block.insert(slot);
|
||||
num_blocks -= 1;
|
||||
None
|
||||
}
|
||||
Some(confirmed_block) => {
|
||||
if confirmed_block
|
||||
.transactions
|
||||
.iter()
|
||||
.any(|transaction| transaction.meta.is_none())
|
||||
{
|
||||
if allow_missing_metadata {
|
||||
info!("Transaction metadata missing from slot {}", slot);
|
||||
} else {
|
||||
panic!("Transaction metadata missing from slot {}", slot);
|
||||
}
|
||||
}
|
||||
Some(bigtable.upload_confirmed_block(slot, confirmed_block))
|
||||
}
|
||||
});
|
||||
|
||||
for result in futures::future::join_all(uploads).await {
|
||||
if result.is_err() {
|
||||
error!("upload_confirmed_block() failed: {:?}", result.err());
|
||||
failures += 1;
|
||||
}
|
||||
}
|
||||
|
||||
measure_upload.stop();
|
||||
info!("{} for {} blocks", measure_upload, num_blocks);
|
||||
}
|
||||
|
||||
measure.stop();
|
||||
info!("{}", measure);
|
||||
if failures > 0 {
|
||||
Err(format!("Incomplete upload, {} operations failed", failures).into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn first_available_block() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(true).await?;
|
||||
match bigtable.get_first_available_block().await? {
|
||||
Some(block) => println!("{}", block),
|
||||
None => println!("No blocks available"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn block(slot: Slot) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
let block = bigtable
|
||||
.get_confirmed_block(slot, UiTransactionEncoding::Binary)
|
||||
.await?;
|
||||
|
||||
println!("Slot: {}", slot);
|
||||
println!("Parent Slot: {}", block.parent_slot);
|
||||
println!("Blockhash: {}", block.blockhash);
|
||||
println!("Previous Blockhash: {}", block.previous_blockhash);
|
||||
if block.block_time.is_some() {
|
||||
println!("Block Time: {:?}", block.block_time);
|
||||
}
|
||||
if !block.rewards.is_empty() {
|
||||
println!("Rewards: {:?}", block.rewards);
|
||||
}
|
||||
for (index, transaction_with_meta) in block.transactions.iter().enumerate() {
|
||||
println!("Transaction {}:", index);
|
||||
println_transaction(
|
||||
&transaction_with_meta.transaction.decode().unwrap(),
|
||||
&transaction_with_meta.meta,
|
||||
" ",
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn blocks(starting_slot: Slot, limit: usize) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
let slots = bigtable.get_confirmed_blocks(starting_slot, limit).await?;
|
||||
println!("{:?}", slots);
|
||||
println!("{} blocks found", slots.len());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn confirm(signature: &Signature, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
let transaction_status = bigtable.get_signature_status(signature).await?;
|
||||
|
||||
if verbose {
|
||||
match bigtable
|
||||
.get_confirmed_transaction(signature, UiTransactionEncoding::Binary)
|
||||
.await
|
||||
{
|
||||
Ok(Some(confirmed_transaction)) => {
|
||||
println!(
|
||||
"\nTransaction executed in slot {}:",
|
||||
confirmed_transaction.slot
|
||||
);
|
||||
println_transaction(
|
||||
&confirmed_transaction
|
||||
.transaction
|
||||
.transaction
|
||||
.decode()
|
||||
.expect("Successful decode"),
|
||||
&confirmed_transaction.transaction.meta,
|
||||
" ",
|
||||
);
|
||||
}
|
||||
Ok(None) => println!("Confirmed transaction details not available"),
|
||||
Err(err) => println!("Unable to get confirmed transaction details: {}", err),
|
||||
}
|
||||
println!();
|
||||
}
|
||||
match transaction_status.status {
|
||||
Ok(_) => println!("Confirmed"),
|
||||
Err(err) => println!("Transaction failed: {}", err),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn transaction_history(
|
||||
address: &Pubkey,
|
||||
mut limit: usize,
|
||||
mut before: Option<Signature>,
|
||||
verbose: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(true).await?;
|
||||
|
||||
while limit > 0 {
|
||||
let results = bigtable
|
||||
.get_confirmed_signatures_for_address(address, before.as_ref(), limit.min(1000))
|
||||
.await?;
|
||||
|
||||
if results.is_empty() {
|
||||
break;
|
||||
}
|
||||
before = Some(results.last().unwrap().signature);
|
||||
assert!(limit >= results.len());
|
||||
limit = limit.saturating_sub(results.len());
|
||||
|
||||
for result in results {
|
||||
if verbose {
|
||||
println!(
|
||||
"{}, slot={}, memo=\"{}\", status={}",
|
||||
result.signature,
|
||||
result.slot,
|
||||
result.memo.unwrap_or_else(|| "".to_string()),
|
||||
match result.err {
|
||||
None => "Confirmed".to_string(),
|
||||
Some(err) => format!("Failed: {:?}", err),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
println!("{}", result.signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub trait BigTableSubCommand {
|
||||
fn bigtable_subcommand(self) -> Self;
|
||||
}
|
||||
|
||||
impl BigTableSubCommand for App<'_, '_> {
|
||||
fn bigtable_subcommand(self) -> Self {
|
||||
self.subcommand(
|
||||
SubCommand::with_name("bigtable")
|
||||
.about("Ledger data on a BigTable instance")
|
||||
.setting(AppSettings::ArgRequiredElseHelp)
|
||||
.subcommand(
|
||||
SubCommand::with_name("upload")
|
||||
.about("Upload the ledger to BigTable")
|
||||
.arg(
|
||||
Arg::with_name("starting_slot")
|
||||
.long("starting-slot")
|
||||
.validator(is_slot)
|
||||
.value_name("SLOT")
|
||||
.takes_value(true)
|
||||
.index(1)
|
||||
.help(
|
||||
"Start uploading at this slot [default: first available slot]",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("ending_slot")
|
||||
.long("ending-slot")
|
||||
.validator(is_slot)
|
||||
.value_name("SLOT")
|
||||
.takes_value(true)
|
||||
.index(2)
|
||||
.help("Stop uploading at this slot [default: last available slot]"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("allow_missing_metadata")
|
||||
.long("allow-missing-metadata")
|
||||
.takes_value(false)
|
||||
.help("Don't panic if transaction metadata is missing"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("first-available-block")
|
||||
.about("Get the first available block in the storage"),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("blocks")
|
||||
.about("Get a list of slots with confirmed blocks for the given range")
|
||||
.arg(
|
||||
Arg::with_name("starting_slot")
|
||||
.long("starting-slot")
|
||||
.validator(is_slot)
|
||||
.value_name("SLOT")
|
||||
.takes_value(true)
|
||||
.index(1)
|
||||
.required(true)
|
||||
.default_value("0")
|
||||
.help("Start listing at this slot"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("limit")
|
||||
.long("limit")
|
||||
.validator(is_slot)
|
||||
.value_name("LIMIT")
|
||||
.takes_value(true)
|
||||
.index(2)
|
||||
.required(true)
|
||||
.default_value("1000")
|
||||
.help("Maximum number of slots to return"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("block")
|
||||
.about("Get a confirmed block")
|
||||
.arg(
|
||||
Arg::with_name("slot")
|
||||
.long("slot")
|
||||
.validator(is_slot)
|
||||
.value_name("SLOT")
|
||||
.takes_value(true)
|
||||
.index(1)
|
||||
.required(true),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("confirm")
|
||||
.about("Confirm transaction by signature")
|
||||
.arg(
|
||||
Arg::with_name("signature")
|
||||
.long("signature")
|
||||
.value_name("TRANSACTION_SIGNATURE")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.index(1)
|
||||
.help("The transaction signature to confirm"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("verbose")
|
||||
.short("v")
|
||||
.long("verbose")
|
||||
.takes_value(false)
|
||||
.help("Show additional information"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("transaction-history")
|
||||
.about(
|
||||
"Show historical transactions affecting the given address \
|
||||
from newest to oldest",
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("address")
|
||||
.index(1)
|
||||
.value_name("ADDRESS")
|
||||
.required(true)
|
||||
.validator(is_valid_pubkey)
|
||||
.help("Account address"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("limit")
|
||||
.long("limit")
|
||||
.takes_value(true)
|
||||
.value_name("LIMIT")
|
||||
.validator(is_slot)
|
||||
.index(2)
|
||||
.default_value("18446744073709551615")
|
||||
.help("Maximum number of transaction signatures to return"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("before")
|
||||
.long("before")
|
||||
.value_name("TRANSACTION_SIGNATURE")
|
||||
.takes_value(true)
|
||||
.help("Start with the first signature older than this one"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("verbose")
|
||||
.short("v")
|
||||
.long("verbose")
|
||||
.takes_value(false)
|
||||
.help("Show additional information"),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
||||
let mut runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
let future = match matches.subcommand() {
|
||||
("upload", Some(arg_matches)) => {
|
||||
let starting_slot = value_t!(arg_matches, "starting_slot", Slot).unwrap_or(0);
|
||||
let ending_slot = value_t!(arg_matches, "ending_slot", Slot).ok();
|
||||
let allow_missing_metadata = arg_matches.is_present("allow_missing_metadata");
|
||||
let blockstore =
|
||||
crate::open_blockstore(&ledger_path, AccessType::TryPrimaryThenSecondary);
|
||||
|
||||
runtime.block_on(upload(
|
||||
blockstore,
|
||||
starting_slot,
|
||||
ending_slot,
|
||||
allow_missing_metadata,
|
||||
))
|
||||
}
|
||||
("first-available-block", Some(_arg_matches)) => runtime.block_on(first_available_block()),
|
||||
("block", Some(arg_matches)) => {
|
||||
let slot = value_t_or_exit!(arg_matches, "slot", Slot);
|
||||
runtime.block_on(block(slot))
|
||||
}
|
||||
("blocks", Some(arg_matches)) => {
|
||||
let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot);
|
||||
let limit = value_t_or_exit!(arg_matches, "limit", usize);
|
||||
|
||||
runtime.block_on(blocks(starting_slot, limit))
|
||||
}
|
||||
("confirm", Some(arg_matches)) => {
|
||||
let signature = arg_matches
|
||||
.value_of("signature")
|
||||
.unwrap()
|
||||
.parse()
|
||||
.expect("Invalid signature");
|
||||
let verbose = arg_matches.is_present("verbose");
|
||||
|
||||
runtime.block_on(confirm(&signature, verbose))
|
||||
}
|
||||
("transaction-history", Some(arg_matches)) => {
|
||||
let address = pubkey_of(arg_matches, "address").unwrap();
|
||||
let limit = value_t_or_exit!(arg_matches, "limit", usize);
|
||||
let before = arg_matches
|
||||
.value_of("before")
|
||||
.map(|signature| signature.parse().expect("Invalid signature"));
|
||||
let verbose = arg_matches.is_present("verbose");
|
||||
|
||||
runtime.block_on(transaction_history(&address, limit, before, verbose))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
future.unwrap_or_else(|err| {
|
||||
eprintln!("{:?}", err);
|
||||
exit(1);
|
||||
});
|
||||
}
|
@@ -2,6 +2,7 @@ use clap::{
|
||||
crate_description, crate_name, value_t, value_t_or_exit, values_t_or_exit, App, Arg,
|
||||
ArgMatches, SubCommand,
|
||||
};
|
||||
use log::*;
|
||||
use regex::Regex;
|
||||
use serde_json::json;
|
||||
use solana_clap_utils::input_validators::{is_parsable, is_slot};
|
||||
@@ -40,7 +41,8 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use log::*;
|
||||
mod bigtable;
|
||||
use bigtable::*;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum LedgerOutputMethod {
|
||||
@@ -704,6 +706,7 @@ fn main() {
|
||||
.global(true)
|
||||
.help("Use DIR for ledger location"),
|
||||
)
|
||||
.bigtable_subcommand()
|
||||
.subcommand(
|
||||
SubCommand::with_name("print")
|
||||
.about("Print the ledger")
|
||||
@@ -975,6 +978,7 @@ fn main() {
|
||||
});
|
||||
|
||||
match matches.subcommand() {
|
||||
("bigtable", Some(arg_matches)) => bigtable_process_command(&ledger_path, arg_matches),
|
||||
("print", Some(arg_matches)) => {
|
||||
let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot);
|
||||
let allow_dead_slots = arg_matches.is_present("allow_dead_slots");
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ledger"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana ledger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -32,19 +32,19 @@ reed-solomon-erasure = { version = "4.0.2", features = ["simd-accel"] }
|
||||
regex = "1.3.7"
|
||||
serde = "1.0.110"
|
||||
serde_bytes = "0.11.4"
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-perf = { path = "../perf", version = "1.2.20" }
|
||||
ed25519-dalek = "1.0.0-pre.3"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
symlink = "0.1.0"
|
||||
tar = "0.4.28"
|
||||
thiserror = "1.0"
|
||||
@@ -62,7 +62,7 @@ features = ["lz4"]
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
matches = "0.1.6"
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1652,7 +1652,7 @@ impl Blockstore {
|
||||
iterator
|
||||
.map(|transaction| {
|
||||
let signature = transaction.signatures[0];
|
||||
let encoded_transaction = EncodedTransaction::encode(transaction, encoding.clone());
|
||||
let encoded_transaction = EncodedTransaction::encode(transaction, encoding);
|
||||
TransactionWithStatusMeta {
|
||||
transaction: encoded_transaction,
|
||||
meta: self
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-local-cluster"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -12,22 +12,22 @@ homepage = "https://solana.com/"
|
||||
itertools = "0.9.0"
|
||||
log = "0.4.8"
|
||||
rand = "0.7.0"
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-download-utils = { path = "../download-utils", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.20" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-download-utils = { path = "../download-utils", version = "1.2.20" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.20" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.20" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.20" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
tempfile = "3.1.0"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-log-analyzer"
|
||||
description = "The solana cluster network analysis tool"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,9 +14,9 @@ byte-unit = "3.1.1"
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[[bin]]
|
||||
name = "solana-log-analyzer"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-logger"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Logger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-measure"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "../README.md"
|
||||
@@ -12,8 +12,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.8"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
jemallocator = "0.3.2"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-merkle-tree"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Merkle Tree"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
fast-math = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-metrics"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Metrics"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,7 +14,7 @@ gethostname = "0.2.1"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.8"
|
||||
reqwest = { version = "0.10.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.0"
|
||||
|
@@ -48,6 +48,9 @@ while [[ -n $1 ]]; do
|
||||
elif [[ $1 = --enable-rpc-transaction-history ]]; then
|
||||
args+=("$1")
|
||||
shift
|
||||
elif [[ $1 = --enable-rpc-bigtable-ledger-storage ]]; then
|
||||
args+=("$1")
|
||||
shift
|
||||
elif [[ $1 = --skip-poh-verify ]]; then
|
||||
args+=("$1")
|
||||
shift
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-net-shaper"
|
||||
description = "The solana cluster network shaping tool"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,8 +13,8 @@ publish = false
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
rand = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-net-utils"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Network Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,9 +18,9 @@ rand = "0.7.0"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
socket2 = "0.3.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
tokio = "0.1"
|
||||
tokio-codec = "0.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-notifier"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Notifier"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-perf"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Performance APIs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -17,11 +17,11 @@ serde = "1.0.110"
|
||||
dlopen_derive = "0.1.4"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.8"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.20" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
curve25519-dalek = { version = "2" }
|
||||
|
||||
[lib]
|
||||
|
1899
programs/bpf/Cargo.lock
generated
1899
programs/bpf/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-bpf-programs"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "README.md"
|
||||
@@ -22,10 +22,10 @@ walkdir = "2"
|
||||
bincode = "1.1.4"
|
||||
byteorder = "1.3.2"
|
||||
elf = "0.0.10"
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.2.20" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.20" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
solana_rbpf = "=0.1.28"
|
||||
|
||||
[[bench]]
|
||||
|
@@ -30,6 +30,10 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
uint8_t nonce1 = params.data[1];
|
||||
uint8_t nonce2 = params.data[2];
|
||||
uint8_t nonce3 = params.data[3];
|
||||
|
||||
switch (params.data[0]) {
|
||||
case TEST_SUCCESS: {
|
||||
sol_log("Call system program");
|
||||
@@ -81,6 +85,18 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
}
|
||||
|
||||
sol_log("Test create_program_address");
|
||||
{
|
||||
uint8_t seed1[] = {'Y', 'o', 'u', ' ', 'p', 'a', 's', 's',
|
||||
' ', 'b', 'u', 't', 't', 'e', 'r'};
|
||||
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
|
||||
{&nonce1, 1}};
|
||||
SolPubkey address;
|
||||
sol_assert(SUCCESS == sol_create_program_address(seeds1, SOL_ARRAY_SIZE(seeds1),
|
||||
params.program_id, &address));
|
||||
sol_assert(SolPubkey_same(&address, accounts[DERIVED_KEY1_INDEX].key));
|
||||
}
|
||||
|
||||
sol_log("Test derived signers");
|
||||
{
|
||||
sol_assert(!accounts[DERIVED_KEY1_INDEX].is_signer);
|
||||
@@ -92,19 +108,15 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
{accounts[DERIVED_KEY1_INDEX].key, true, true},
|
||||
{accounts[DERIVED_KEY2_INDEX].key, true, false},
|
||||
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
|
||||
uint8_t data[] = {TEST_DERIVED_SIGNERS};
|
||||
uint8_t data[] = {TEST_DERIVED_SIGNERS, nonce2, nonce3};
|
||||
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
uint8_t seed1[] = {'Y', 'o', 'u', ' ', 'p', 'a', 's', 's',
|
||||
' ', 'b', 'u', 't', 't', 'e', 'r'};
|
||||
uint8_t seed2[] = {'L', 'i', 'l', '\''};
|
||||
uint8_t seed3[] = {'B', 'i', 't', 's'};
|
||||
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)}};
|
||||
const SolSignerSeed seeds2[] = {{seed2, SOL_ARRAY_SIZE(seed2)},
|
||||
{seed3, SOL_ARRAY_SIZE(seed3)}};
|
||||
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
|
||||
{seeds2, SOL_ARRAY_SIZE(seeds2)}};
|
||||
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
|
||||
{&nonce1, 1}};
|
||||
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)}};
|
||||
sol_assert(SUCCESS == sol_invoke_signed(&instruction, accounts,
|
||||
SOL_ARRAY_SIZE(accounts),
|
||||
signers_seeds,
|
||||
|
@@ -92,6 +92,9 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
|
||||
uint8_t nonce2 = params.data[1];
|
||||
uint8_t nonce3 = params.data[2];
|
||||
|
||||
SolAccountMeta arguments[] = {
|
||||
{accounts[DERIVED_KEY1_INDEX].key, true, false},
|
||||
{accounts[DERIVED_KEY2_INDEX].key, true, true},
|
||||
@@ -103,9 +106,11 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
uint8_t seed1[] = {'L', 'i', 'l', '\''};
|
||||
uint8_t seed2[] = {'B', 'i', 't', 's'};
|
||||
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
|
||||
{seed2, SOL_ARRAY_SIZE(seed2)}};
|
||||
{seed2, SOL_ARRAY_SIZE(seed2)},
|
||||
{&nonce2, 1}};
|
||||
const SolSignerSeed seeds2[] = {
|
||||
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY}};
|
||||
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY},
|
||||
{&nonce3, 1}};
|
||||
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
|
||||
{seeds2, SOL_ARRAY_SIZE(seeds2)}};
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.2.20" }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit-dep"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-alloc"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-dep-crate"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,7 +13,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = { version = "1", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-dup-accounts"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-error-handling"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,7 +14,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
num-derive = "0.2"
|
||||
num-traits = "0.2"
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
thiserror = "1.0"
|
||||
|
||||
[features]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-external-spend"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-invoke"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,7 +13,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-bpf-rust-invoked = { path = "../invoked"}
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -10,7 +10,7 @@ use solana_sdk::{
|
||||
entrypoint,
|
||||
entrypoint::ProgramResult,
|
||||
info,
|
||||
program::{invoke, invoke_signed},
|
||||
program::{create_program_address, invoke, invoke_signed},
|
||||
program_error::ProgramError,
|
||||
pubkey::Pubkey,
|
||||
system_instruction,
|
||||
@@ -34,12 +34,16 @@ const FROM_INDEX: usize = 10;
|
||||
|
||||
entrypoint!(process_instruction);
|
||||
fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
instruction_data: &[u8],
|
||||
) -> ProgramResult {
|
||||
info!("invoke Rust program");
|
||||
|
||||
let nonce1 = instruction_data[1];
|
||||
let nonce2 = instruction_data[2];
|
||||
let nonce3 = instruction_data[3];
|
||||
|
||||
match instruction_data[0] {
|
||||
TEST_SUCCESS => {
|
||||
info!("Call system program");
|
||||
@@ -91,6 +95,12 @@ fn process_instruction(
|
||||
);
|
||||
}
|
||||
|
||||
info!("Test create_program_address");
|
||||
{
|
||||
let address = create_program_address(&[b"You pass butter", &[nonce1]], program_id)?;
|
||||
assert_eq!(&address, accounts[DERIVED_KEY1_INDEX].key);
|
||||
}
|
||||
|
||||
info!("Test derived signers");
|
||||
{
|
||||
assert!(!accounts[DERIVED_KEY1_INDEX].is_signer);
|
||||
@@ -105,12 +115,12 @@ fn process_instruction(
|
||||
(accounts[DERIVED_KEY2_INDEX].key, true, false),
|
||||
(accounts[DERIVED_KEY3_INDEX].key, false, false),
|
||||
],
|
||||
vec![TEST_DERIVED_SIGNERS],
|
||||
vec![TEST_DERIVED_SIGNERS, nonce2, nonce3],
|
||||
);
|
||||
invoke_signed(
|
||||
&invoked_instruction,
|
||||
accounts,
|
||||
&[&[b"You pass butter"], &[b"Lil'", b"Bits"]],
|
||||
&[&[b"You pass butter", &[nonce1]]],
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-invoked"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -120,6 +120,8 @@ fn process_instruction(
|
||||
assert!(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
assert!(!accounts[DERIVED_KEY3_INDEX].is_signer);
|
||||
|
||||
let nonce2 = instruction_data[1];
|
||||
let nonce3 = instruction_data[2];
|
||||
let invoked_instruction = create_instruction(
|
||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
&[
|
||||
@@ -133,8 +135,8 @@ fn process_instruction(
|
||||
&invoked_instruction,
|
||||
accounts,
|
||||
&[
|
||||
&[b"Lil'", b"Bits"],
|
||||
&[accounts[DERIVED_KEY2_INDEX].key.as_ref()],
|
||||
&[b"Lil'", b"Bits", &[nonce2]],
|
||||
&[accounts[DERIVED_KEY2_INDEX].key.as_ref(), &[nonce3]],
|
||||
],
|
||||
)?;
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-iter"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-many-args"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.2.20" }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-many-args-dep"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-noop"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-panic"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-param-passing"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.2.20" }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-param-passing-dep"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-sysval"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.20", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -351,13 +351,12 @@ mod bpf {
|
||||
let account = Account::new(43, 0, &solana_sdk::system_program::id());
|
||||
bank.store_account(&from_keypair.pubkey(), &account);
|
||||
|
||||
let derived_key1 =
|
||||
Pubkey::create_program_address(&[b"You pass butter"], &invoke_program_id).unwrap();
|
||||
let derived_key2 =
|
||||
Pubkey::create_program_address(&[b"Lil'", b"Bits"], &invoked_program_id).unwrap();
|
||||
let derived_key3 =
|
||||
Pubkey::create_program_address(&[derived_key2.as_ref()], &invoked_program_id)
|
||||
.unwrap();
|
||||
let (derived_key1, nonce1) =
|
||||
Pubkey::find_program_address(&[b"You pass butter"], &invoke_program_id);
|
||||
let (derived_key2, nonce2) =
|
||||
Pubkey::find_program_address(&[b"Lil'", b"Bits"], &invoked_program_id);
|
||||
let (derived_key3, nonce3) =
|
||||
Pubkey::find_program_address(&[derived_key2.as_ref()], &invoked_program_id);
|
||||
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let account_metas = vec![
|
||||
@@ -376,8 +375,11 @@ mod bpf {
|
||||
|
||||
// success cases
|
||||
|
||||
let instruction =
|
||||
Instruction::new(invoke_program_id, &TEST_SUCCESS, account_metas.clone());
|
||||
let instruction = Instruction::new(
|
||||
invoke_program_id,
|
||||
&[TEST_SUCCESS, nonce1, nonce2, nonce3],
|
||||
account_metas.clone(),
|
||||
);
|
||||
let message = Message::new(&[instruction], Some(&mint_pubkey));
|
||||
assert!(bank_client
|
||||
.send_and_confirm_message(
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-loader-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana BPF loader"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,9 +15,9 @@ jemalloc-sys = { version = "0.3.2", features = ["disable_initial_exec_tls"] }
|
||||
log = "0.4.8"
|
||||
num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.20" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
solana_rbpf = "=0.1.28"
|
||||
thiserror = "1.0"
|
||||
|
||||
|
@@ -77,6 +77,9 @@ pub fn register_syscalls<'a>(
|
||||
) -> Result<MemoryRegion, EbpfError<BPFError>> {
|
||||
// Syscall function common across languages
|
||||
vm.register_syscall_ex("abort", syscall_abort)?;
|
||||
if invoke_context.is_cross_program_supported() {
|
||||
vm.register_syscall_ex("sol_create_program_address", syscall_create_program_address)?;
|
||||
}
|
||||
|
||||
{
|
||||
let invoke_context = Rc::new(RefCell::new(invoke_context));
|
||||
@@ -362,6 +365,36 @@ impl SyscallObject<BPFError> for SyscallSolAllocFree {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a program address
|
||||
pub fn syscall_create_program_address(
|
||||
seeds_addr: u64,
|
||||
seeds_len: u64,
|
||||
program_id_addr: u64,
|
||||
address_addr: u64,
|
||||
_arg5: u64,
|
||||
ro_regions: &[MemoryRegion],
|
||||
rw_regions: &[MemoryRegion],
|
||||
) -> Result<u64, EbpfError<BPFError>> {
|
||||
let untranslated_seeds = translate_slice!(&[&str], seeds_addr, seeds_len, ro_regions)?;
|
||||
let seeds = untranslated_seeds
|
||||
.iter()
|
||||
.map(|untranslated_seed| {
|
||||
translate_slice!(
|
||||
u8,
|
||||
untranslated_seed.as_ptr(),
|
||||
untranslated_seed.len(),
|
||||
ro_regions
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, EbpfError<BPFError>>>()?;
|
||||
let program_id = translate_type!(Pubkey, program_id_addr, rw_regions)?;
|
||||
let new_address =
|
||||
Pubkey::create_program_address(&seeds, program_id).map_err(SyscallError::BadSeeds)?;
|
||||
let address = translate_slice_mut!(u8, address_addr, 32, ro_regions)?;
|
||||
address.copy_from_slice(new_address.as_ref());
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
// Cross-program invocation syscalls
|
||||
|
||||
pub type TranslatedAccounts<'a> = (Vec<Rc<RefCell<Account>>>, Vec<(&'a mut u64, &'a mut [u8])>);
|
||||
@@ -846,6 +879,12 @@ fn call<'a>(
|
||||
let account = account.borrow();
|
||||
if message.is_writable(i) && !account.executable {
|
||||
*lamport_ref = account.lamports;
|
||||
if data.len() != account.data.len() {
|
||||
return Err(SyscallError::InstructionError(
|
||||
InstructionError::AccountDataSizeChanged,
|
||||
)
|
||||
.into());
|
||||
}
|
||||
data.clone_from_slice(&account.data);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-btc-spv-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Bitcoin spv parsing program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,7 +15,7 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19"}
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20"}
|
||||
hex = "0.4.2"
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "btc_spv_bin"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Bitcoin spv parsing program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-budget-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Budget program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,11 +16,11 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-config-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Config program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,10 +14,10 @@ chrono = { version = "0.4.11", features = ["serde"] }
|
||||
log = "0.4.8"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-exchange-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Exchange program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,13 +15,13 @@ num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.20" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-failure-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana failure program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -9,10 +9,10 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-noop-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Noop program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,8 +10,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.8"
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.20" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ownable"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "ownable program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,13 +10,13 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.2.1"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-stake-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Stake program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,14 +15,14 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../vote", version = "1.2.19" }
|
||||
solana-config-program = { path = "../config", version = "1.2.19" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.20" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../vote", version = "1.2.20" }
|
||||
solana-config-program = { path = "../config", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-vest-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Vest program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,12 +15,12 @@ num-derive = "0.2"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-config-program = { path = "../config", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
solana-config-program = { path = "../config", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.20" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-vote-program"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana Vote program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,8 +15,8 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.20" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[lib]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-ramp-tps"
|
||||
description = "Solana Tour de SOL - TPS ramp up"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/tour-de-sol"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -16,12 +16,12 @@ reqwest = { version = "0.10.4", default-features = false }
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.20" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
tar = "0.4.28"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "solana-rayon-threadlimit"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "../README.md"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-remote-wallet"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -18,7 +18,7 @@ num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
parking_lot = "0.10"
|
||||
semver = "0.9"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
thiserror = "1.0"
|
||||
url = "2.1.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-runtime"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana runtime"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -27,14 +27,14 @@ rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
serde = { version = "1.0.110", features = ["rc"] }
|
||||
serde_derive = "1.0.103"
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-measure = { path = "../measure", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.20" }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -44,7 +44,7 @@ name = "solana_runtime"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
solana-noop-program = { path = "../programs/noop", version = "1.2.19" }
|
||||
solana-noop-program = { path = "../programs/noop", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-scripts"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-sdk"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana SDK"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,6 +18,7 @@ default = [
|
||||
"assert_matches",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"curve25519-dalek",
|
||||
"generic-array",
|
||||
"memmap",
|
||||
"rand",
|
||||
@@ -35,7 +36,8 @@ bs58 = "0.3.1"
|
||||
bv = { version = "0.11.1", features = ["serde"] }
|
||||
byteorder = { version = "1.3.4", optional = true }
|
||||
chrono = { version = "0.4", optional = true }
|
||||
generic-array = { version = "0.14.1", default-features = false, features = ["serde", "more_lengths"], optional = true }
|
||||
curve25519-dalek = { version = "2.1.0", optional = true }
|
||||
generic-array = { version = "0.14.3", default-features = false, features = ["serde", "more_lengths"], optional = true }
|
||||
hex = "0.4.2"
|
||||
hmac = "0.7.0"
|
||||
itertools = { version = "0.9.0" }
|
||||
@@ -53,9 +55,9 @@ serde_json = { version = "1.0.53", optional = true }
|
||||
sha2 = "0.8.2"
|
||||
thiserror = "1.0"
|
||||
ed25519-dalek = { version = "=1.0.0-pre.4", optional = true }
|
||||
solana-crate-features = { path = "../crate-features", version = "1.2.19", optional = true }
|
||||
solana-logger = { path = "../logger", version = "1.2.19", optional = true }
|
||||
solana-sdk-macro = { path = "macro", version = "1.2.19" }
|
||||
solana-crate-features = { path = "../crate-features", version = "1.2.20", optional = true }
|
||||
solana-logger = { path = "../logger", version = "1.2.20", optional = true }
|
||||
solana-sdk-macro = { path = "macro", version = "1.2.20" }
|
||||
rustversion = "1.0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -109,6 +109,10 @@ static_assert(sizeof(uint64_t) == 8);
|
||||
#define ERROR_NOT_ENOUGH_ACCOUNT_KEYS TO_BUILTIN(11)
|
||||
/** Note: Not applicable to program written in C */
|
||||
#define ERROR_ACCOUNT_BORROW_FAILED TO_BUILTIN(12)
|
||||
/** The length of the seed is too long for address generation */
|
||||
#define MAX_SEED_LENGTH_EXCEEDED TO_BUILTIN(13)
|
||||
/** Provided seeds do not result in a valid address */
|
||||
#define INVALID_SEEDS TO_BUILTIN(14)
|
||||
|
||||
/**
|
||||
* Boolean type
|
||||
@@ -389,12 +393,29 @@ typedef struct {
|
||||
uint64_t len; /** Number of seeds */
|
||||
} SolSignerSeeds;
|
||||
|
||||
/*
|
||||
* Create a program address
|
||||
*
|
||||
* @param seeds Seed strings used to sign program accounts
|
||||
* @param seeds_len Length of the seeds array
|
||||
* @param Progam id of the signer
|
||||
* @param Program address created, filled on return
|
||||
*/
|
||||
static uint64_t sol_create_program_address(
|
||||
const SolSignerSeed *seeds,
|
||||
int seeds_len,
|
||||
const SolPubkey *program_id,
|
||||
const SolPubkey *address
|
||||
);
|
||||
|
||||
/**
|
||||
* Cross-program invocation
|
||||
* * @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* Invoke another program and sign for some of the keys
|
||||
*
|
||||
* @param instruction Instruction to process
|
||||
* @param account_infos Accounts used by instruction
|
||||
* @param account_infos_len Length of account_infos array
|
||||
@@ -425,9 +446,11 @@ static uint64_t sol_invoke_signed(
|
||||
);
|
||||
}
|
||||
/*
|
||||
* @param instruction Instruction to process
|
||||
* @param account_infos Accounts used by instruction
|
||||
* @param account_infos_len Length of account_infos array
|
||||
* Invoke another program
|
||||
*
|
||||
* @param instruction Instruction to process
|
||||
* @param account_infos Accounts used by instruction
|
||||
* @param account_infos_len Length of account_infos array
|
||||
*/
|
||||
static uint64_t sol_invoke(
|
||||
const SolInstruction *instruction,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-sdk-macro"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
description = "Solana SDK Macro"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -151,6 +151,14 @@ pub enum InstructionError {
|
||||
/// Cross-program invocation reentrancy not allowed for this instruction
|
||||
#[error("Cross-program invocation reentrancy not allowed for this instruction")]
|
||||
ReentrancyNotAllowed,
|
||||
|
||||
/// Length of the seed is too long for address generation
|
||||
#[error("Length of the seed is too long for address generation")]
|
||||
MaxSeedLengthExceeded,
|
||||
|
||||
/// Provided seeds do not result in a valid address
|
||||
#[error("Provided seeds do not result in a valid address")]
|
||||
InvalidSeeds,
|
||||
}
|
||||
|
||||
impl InstructionError {
|
||||
|
@@ -2,9 +2,39 @@
|
||||
|
||||
use crate::{
|
||||
account_info::AccountInfo, entrypoint::ProgramResult, entrypoint::SUCCESS,
|
||||
instruction::Instruction,
|
||||
instruction::Instruction, program_error::ProgramError, pubkey::Pubkey,
|
||||
};
|
||||
|
||||
pub fn create_program_address(
|
||||
seeds: &[&[u8]],
|
||||
program_id: &Pubkey,
|
||||
) -> Result<Pubkey, ProgramError> {
|
||||
let bytes = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0,
|
||||
];
|
||||
let result = unsafe {
|
||||
sol_create_program_address(
|
||||
seeds as *const _ as *const u8,
|
||||
seeds.len() as u64,
|
||||
program_id as *const _ as *const u8,
|
||||
&bytes as *const _ as *const u8,
|
||||
)
|
||||
};
|
||||
match result {
|
||||
SUCCESS => Ok(Pubkey::new(&bytes)),
|
||||
_ => Err(result.into()),
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
fn sol_create_program_address(
|
||||
seeds_addr: *const u8,
|
||||
seeds_len: u64,
|
||||
program_id_addr: *const u8,
|
||||
address_bytes_addr: *const u8,
|
||||
) -> u64;
|
||||
}
|
||||
|
||||
/// Invoke a cross-program instruction
|
||||
pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
|
||||
invoke_signed(instruction, account_infos, &[])
|
||||
@@ -30,7 +60,6 @@ pub fn invoke_signed(
|
||||
_ => Err(result.into()),
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn sol_invoke_signed_rust(
|
||||
instruction_addr: *const u8,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use crate::{decode_error::DecodeError, instruction::InstructionError};
|
||||
use crate::{decode_error::DecodeError, instruction::InstructionError, pubkey::PubkeyError};
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use std::convert::TryFrom;
|
||||
use thiserror::Error;
|
||||
@@ -38,6 +38,10 @@ pub enum ProgramError {
|
||||
NotEnoughAccountKeys,
|
||||
#[error("Failed to borrow a reference to account data, already borrowed")]
|
||||
AccountBorrowFailed,
|
||||
#[error("Length of the seed is too long for address generation")]
|
||||
MaxSeedLengthExceeded,
|
||||
#[error("Provided seeds do not result in a valid address")]
|
||||
InvalidSeeds,
|
||||
}
|
||||
|
||||
pub trait PrintProgramError {
|
||||
@@ -70,6 +74,8 @@ impl PrintProgramError for ProgramError {
|
||||
Self::UninitializedAccount => info!("Error: UninitializedAccount"),
|
||||
Self::NotEnoughAccountKeys => info!("Error: NotEnoughAccountKeys"),
|
||||
Self::AccountBorrowFailed => info!("Error: AccountBorrowFailed"),
|
||||
Self::MaxSeedLengthExceeded => info!("Error: MaxSeedLengthExceeded"),
|
||||
Self::InvalidSeeds => info!("Error: InvalidSeeds"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +100,8 @@ const ACCOUNT_ALREADY_INITIALIZED: u64 = to_builtin!(9);
|
||||
const UNINITIALIZED_ACCOUNT: u64 = to_builtin!(10);
|
||||
const NOT_ENOUGH_ACCOUNT_KEYS: u64 = to_builtin!(11);
|
||||
const ACCOUNT_BORROW_FAILED: u64 = to_builtin!(12);
|
||||
const MAX_SEED_LENGTH_EXCEEDED: u64 = to_builtin!(13);
|
||||
const INVALID_SEEDS: u64 = to_builtin!(14);
|
||||
|
||||
impl From<ProgramError> for u64 {
|
||||
fn from(error: ProgramError) -> Self {
|
||||
@@ -109,6 +117,9 @@ impl From<ProgramError> for u64 {
|
||||
ProgramError::UninitializedAccount => UNINITIALIZED_ACCOUNT,
|
||||
ProgramError::NotEnoughAccountKeys => NOT_ENOUGH_ACCOUNT_KEYS,
|
||||
ProgramError::AccountBorrowFailed => ACCOUNT_BORROW_FAILED,
|
||||
ProgramError::MaxSeedLengthExceeded => MAX_SEED_LENGTH_EXCEEDED,
|
||||
ProgramError::InvalidSeeds => INVALID_SEEDS,
|
||||
|
||||
ProgramError::Custom(error) => {
|
||||
if error == 0 {
|
||||
CUSTOM_ZERO
|
||||
@@ -134,6 +145,8 @@ impl From<u64> for ProgramError {
|
||||
UNINITIALIZED_ACCOUNT => ProgramError::UninitializedAccount,
|
||||
NOT_ENOUGH_ACCOUNT_KEYS => ProgramError::NotEnoughAccountKeys,
|
||||
ACCOUNT_BORROW_FAILED => ProgramError::AccountBorrowFailed,
|
||||
MAX_SEED_LENGTH_EXCEEDED => ProgramError::MaxSeedLengthExceeded,
|
||||
INVALID_SEEDS => ProgramError::InvalidSeeds,
|
||||
CUSTOM_ZERO => ProgramError::Custom(0),
|
||||
_ => ProgramError::Custom(error as u32),
|
||||
}
|
||||
@@ -181,6 +194,8 @@ where
|
||||
UNINITIALIZED_ACCOUNT => InstructionError::UninitializedAccount,
|
||||
NOT_ENOUGH_ACCOUNT_KEYS => InstructionError::NotEnoughAccountKeys,
|
||||
ACCOUNT_BORROW_FAILED => InstructionError::AccountBorrowFailed,
|
||||
MAX_SEED_LENGTH_EXCEEDED => InstructionError::MaxSeedLengthExceeded,
|
||||
INVALID_SEEDS => InstructionError::InvalidSeeds,
|
||||
_ => {
|
||||
// A valid custom error has no bits set in the upper 32
|
||||
if error >> BUILTIN_BIT_SHIFT == 0 {
|
||||
@@ -192,3 +207,12 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PubkeyError> for ProgramError {
|
||||
fn from(error: PubkeyError) -> Self {
|
||||
match error {
|
||||
PubkeyError::MaxSeedLengthExceeded => ProgramError::MaxSeedLengthExceeded,
|
||||
PubkeyError::InvalidSeeds => ProgramError::InvalidSeeds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
use crate::{
|
||||
decode_error::DecodeError,
|
||||
hash::{hash, hashv, Hasher},
|
||||
};
|
||||
#[cfg(not(feature = "program"))]
|
||||
use crate::hash::Hasher;
|
||||
use crate::{decode_error::DecodeError, hash::hashv};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
#[cfg(not(feature = "program"))]
|
||||
use std::error;
|
||||
@@ -17,6 +16,8 @@ pub const MAX_SEED_LEN: usize = 32;
|
||||
pub enum PubkeyError {
|
||||
#[error("length of requested seed is too long")]
|
||||
MaxSeedLengthExceeded,
|
||||
#[error("Provided seeds do not result in a valid address")]
|
||||
InvalidSeeds,
|
||||
}
|
||||
impl<T> DecodeError<T> for PubkeyError {
|
||||
fn type_of() -> &'static str {
|
||||
@@ -84,6 +85,9 @@ impl Pubkey {
|
||||
))
|
||||
}
|
||||
|
||||
/// Create a program address, valid program address must not be on the
|
||||
/// ed25519 curve
|
||||
#[cfg(not(feature = "program"))]
|
||||
pub fn create_program_address(
|
||||
seeds: &[&[u8]],
|
||||
program_id: &Pubkey,
|
||||
@@ -96,8 +100,34 @@ impl Pubkey {
|
||||
hasher.hash(seed);
|
||||
}
|
||||
hasher.hashv(&[program_id.as_ref(), "ProgramDerivedAddress".as_ref()]);
|
||||
let hash = hasher.result();
|
||||
|
||||
Ok(Pubkey::new(hash(hasher.result().as_ref()).as_ref()))
|
||||
if curve25519_dalek::edwards::CompressedEdwardsY::from_slice(hash.as_ref())
|
||||
.decompress()
|
||||
.is_some()
|
||||
{
|
||||
return Err(PubkeyError::InvalidSeeds);
|
||||
}
|
||||
|
||||
Ok(Pubkey::new(hash.as_ref()))
|
||||
}
|
||||
|
||||
/// Find a valid program address and its corresponding nonce which must be passed
|
||||
/// as an additional seed when calling `create_program_address`
|
||||
#[cfg(not(feature = "program"))]
|
||||
pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8) {
|
||||
let mut nonce = [255];
|
||||
for _ in 0..std::u8::MAX {
|
||||
{
|
||||
let mut seeds_with_nonce = seeds.to_vec();
|
||||
seeds_with_nonce.push(&nonce);
|
||||
if let Ok(address) = Self::create_program_address(&seeds_with_nonce, program_id) {
|
||||
return (address, nonce[0]);
|
||||
}
|
||||
}
|
||||
nonce[0] -= 1;
|
||||
}
|
||||
panic!("Unable to find a viable program address nonce");
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "program"))]
|
||||
@@ -256,37 +286,73 @@ mod tests {
|
||||
Pubkey::create_program_address(&[b"short_seed", exceeded_seed], &program_id),
|
||||
Err(PubkeyError::MaxSeedLengthExceeded)
|
||||
);
|
||||
assert!(Pubkey::create_program_address(&[max_seed], &Pubkey::new_rand()).is_ok());
|
||||
assert!(Pubkey::create_program_address(&[max_seed], &program_id).is_ok());
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&[b""], &program_id),
|
||||
Ok("CsdSsqp6Upkh2qajhZMBM8xT4GAyDNSmcV37g4pN8rsc"
|
||||
Pubkey::create_program_address(&[b"", &[1]], &program_id),
|
||||
Ok("3gF2KMe9KiC6FNVBmfg9i267aMPvK37FewCip4eGBFcT"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&["☉".as_ref()], &program_id),
|
||||
Ok("A8mYnN8Pfx7Nn6f8RoQgsPNtAGAWmmKSBCDfyDvE6sXF"
|
||||
Ok("7ytmC1nT1xY4RfxCV2ZgyA7UakC93do5ZdyhdF3EtPj7"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&[b"Talking", b"Squirrels"], &program_id),
|
||||
Ok("CawYq8Rmj4JRR992wVnGEFUjMEkmtmcFgEL4iS1qPczu"
|
||||
Ok("HwRVBufQ4haG5XSgpspwKtNd3PC9GM9m1196uJW36vds"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&[public_key.as_ref()], &program_id),
|
||||
Ok("4ak7qJacCKMAGP8xJtDkg2VYZh5QKExa71ijMDjZGQyb"
|
||||
Ok("GUs5qLUfsEHkcMB9T38vjr18ypEhRuNWiePW2LoK4E3K"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_ne!(
|
||||
Pubkey::create_program_address(&[b"Talking", b"Squirrels"], &program_id),
|
||||
Pubkey::create_program_address(&[b"Talking"], &program_id),
|
||||
Pubkey::create_program_address(&[b"Talking", b"Squirrels"], &program_id).unwrap(),
|
||||
Pubkey::create_program_address(&[b"Talking"], &program_id).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pubkey_off_curve() {
|
||||
// try a bunch of random input, all successful generated program
|
||||
// addresses must land off the curve and be unique
|
||||
let mut addresses = vec![];
|
||||
for _ in 0..1_000 {
|
||||
let program_id = Pubkey::new_rand();
|
||||
let bytes1 = rand::random::<[u8; 10]>();
|
||||
let bytes2 = rand::random::<[u8; 32]>();
|
||||
if let Ok(program_address) =
|
||||
Pubkey::create_program_address(&[&bytes1, &bytes2], &program_id)
|
||||
{
|
||||
let is_on_curve = curve25519_dalek::edwards::CompressedEdwardsY::from_slice(
|
||||
&program_address.to_bytes(),
|
||||
)
|
||||
.decompress()
|
||||
.is_some();
|
||||
assert!(!is_on_curve);
|
||||
assert!(!addresses.contains(&program_address));
|
||||
addresses.push(program_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_program_address() {
|
||||
for _ in 0..1_000 {
|
||||
let program_id = Pubkey::new_rand();
|
||||
let (address, nonce) = Pubkey::find_program_address(&[b"Lil'", b"Bits"], &program_id);
|
||||
assert_eq!(
|
||||
address,
|
||||
Pubkey::create_program_address(&[b"Lil'", b"Bits", &[nonce]], &program_id).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_write_pubkey() -> Result<(), Box<dyn error::Error>> {
|
||||
let filename = "test_pubkey.json";
|
||||
|
@@ -3,22 +3,22 @@ name = "solana-stake-accounts"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-stake-monitor"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,21 +14,21 @@ console = "0.10.1"
|
||||
log = "0.4.8"
|
||||
serde = "1.0.110"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
solana-version = { path = "../version", version = "1.2.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.4.0"
|
||||
serial_test_derive = "0.4.0"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.20" }
|
||||
solana-core = { path = "../core", version = "1.2.20" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -6,21 +6,21 @@ homepage = "https://solana.com/"
|
||||
license = "Apache-2.0"
|
||||
name = "solana-stake-o-matic"
|
||||
repository = "https://github.com/solana-labs/stake-o-matic"
|
||||
version = "1.2.19"
|
||||
version = "1.2.20"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
log = "0.4.8"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.20" }
|
||||
solana-client = { path = "../client", version = "1.2.20" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.20" }
|
||||
solana-logger = { path = "../logger", version = "1.2.20" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.20" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.20" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.20" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.20" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.20" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user