Compare commits

...

10 Commits

Author SHA1 Message Date
mergify[bot]
55836d133e Realloc not supported (#11417)
(cherry picked from commit bc4c5c5a97)

Co-authored-by: Jack May <jack@solana.com>
2020-08-06 15:00:51 +00:00
Michael Vines
277e402d55 Update lib.rs
(cherry picked from commit 5a63c9d535)
2020-08-06 07:58:01 -07:00
Michael Vines
0ab8312b23 Enable cross program support in mainnet-beta epoch 63
(cherry picked from commit c9b1d08218)
2020-08-06 07:58:01 -07:00
Jack May
bc4c5c5a97 Realloc not supported 2020-08-06 07:57:23 -07:00
mergify[bot]
1a9aa78129 Force program address off the curve (bp #11323) (#11397)
* Force program address off the curve (#11323)

(cherry picked from commit 03263c850a)

* nudge

* trailing whitespace

Co-authored-by: Jack May <jack@solana.com>
Co-authored-by: Trent Nelson <trent@solana.com>
2020-08-06 09:46:35 +00:00
mergify[bot]
798a6db915 RPC: Plug getConfirmedSignaturesForAddress2 into bigtable storage (bp #11395) (#11405)
* Plug getConfirmedSignaturesForAddress2 into bigtable storage

(cherry picked from commit 4222932e08)

# Conflicts:
#	ledger-tool/src/bigtable.rs
#	storage-bigtable/src/lib.rs

* Upgrade help description

(cherry picked from commit 9abb7db5f8)

Co-authored-by: Michael Vines <mvines@gmail.com>
2020-08-06 07:49:30 +00:00
Michael Vines
0a4a3fd37e Cargo.lock 2020-08-05 23:15:28 -07:00
Michael Vines
66242eab41 Long-term ledger storage with BigTable (bp #11222) 2020-08-05 23:15:28 -07:00
Trent Nelson
7f0d4f0656 Bump version to 1.2.20 2020-08-05 22:06:02 -06:00
mergify[bot]
acba8d6026 Mark token-specific rpcs as unstable (#11401)
(cherry picked from commit 7430896c79)

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2020-08-06 03:59:28 +00:00
130 changed files with 8071 additions and 1696 deletions

1093
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,7 @@ members = [
"log-analyzer",
"merkle-tree",
"stake-o-matic",
"storage-bigtable",
"streamer",
"measure",
"metrics",

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

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

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-cli"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.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]]

View File

@@ -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)

View File

@@ -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"]

View File

@@ -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]

View File

@@ -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),

View File

@@ -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()
}
}

View File

@@ -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>,

View File

@@ -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| {

View File

@@ -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"

View File

@@ -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:

View 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.

View File

@@ -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"]

View File

@@ -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]

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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);
}
})
}

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-genesis"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.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]]

View File

@@ -3,20 +3,20 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-gossip"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.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"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-install"
description = "The solana cluster software installer"
version = "1.2.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"

View File

@@ -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]]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-ledger-tool"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.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
View 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);
});
}

View File

@@ -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");

View File

@@ -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"]

View File

@@ -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

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-local-cluster"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.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"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-log-analyzer"
description = "The solana cluster network analysis tool"
version = "1.2.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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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]

View File

@@ -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"

View File

@@ -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

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-net-shaper"
description = "The solana cluster network shaping tool"
version = "1.2.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]]

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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]]

View File

@@ -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,

View File

@@ -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)}};

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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]]],
)?;
}

View File

@@ -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"]

View File

@@ -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]],
],
)?;
}

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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(

View File

@@ -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"

View File

@@ -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);
}
}

View File

@@ -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]

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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]

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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/"

View File

@@ -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]

View File

@@ -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,

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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,
}
}
}

View File

@@ -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";

View File

@@ -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"]

View File

@@ -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]]

View File

@@ -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