Compare commits

..

31 Commits

Author SHA1 Message Date
mergify[bot]
8778ecaed5 Ledger cleanup fixes (#9131) (#9175)
automerge
2020-03-30 20:42:17 -07:00
Michael Vines
a02542ada3 Bump version to v1.0.12 2020-03-30 08:45:50 -07:00
Michael Vines
ea17c6883f Remove chatty 'setting snapshot root:' info log 2020-03-30 08:44:24 -07:00
Michael Vines
706306645b solana account now displays the account's rent epoch 2020-03-30 08:44:24 -07:00
sakridge
da9e930788 Calculate ref counts earlier to prevent bad clean (#9153) 2020-03-29 14:42:57 -07:00
mergify[bot]
8b8e066bbe Add RPC subscription api for rooted slots (#9118) (#9126)
automerge
2020-03-27 13:09:32 -07:00
mergify[bot]
3473350b62 fix links (#9125) (#9128)
automerge
2020-03-27 10:28:23 -07:00
mergify[bot]
59d7eb5216 Fix links in docs (#9119) (#9127)
automerge
2020-03-27 09:50:28 -07:00
mergify[bot]
55ba934137 Document transaction field in getConfirmedBlock responses (#9121) (#9124)
automerge
2020-03-27 09:45:30 -07:00
mergify[bot]
4c3dcb7f7e Exclude all executable accounts from rent collection (#9116) (#9120)
automerge
2020-03-27 09:27:07 -07:00
mergify[bot]
3a879db8af Fix broken gitbook links (#9107) (#9108)
automerge
2020-03-26 20:33:20 -07:00
mergify[bot]
d2107270ea Consolidate signature-status rpcs (bp #9069) (#9105)
automerge
2020-03-26 20:30:46 -07:00
mergify[bot]
007afe22d0 Add docs for app wallets (#9098) (#9103)
automerge
2020-03-26 18:26:23 -07:00
mergify[bot]
93a1d10e15 Revert setting the default toolchain (#9093) (#9097)
automerge
2020-03-26 15:59:26 -07:00
mergify[bot]
d57a7c8f21 Restructure wallet docs to prep for app wallet content (#9088) (#9095)
automerge
2020-03-26 14:39:32 -07:00
mergify[bot]
6db39829c8 Install xargo using CI dictated cargo version if available (#9068) (#9092)
automerge
2020-03-26 14:02:09 -07:00
mergify[bot]
ec76826493 Unflake rpc subscriptions test by reducing sub count (#9078) (#9082)
automerge
2020-03-25 22:56:52 -07:00
carllin
d4ddb6265b Convert Banks (#9033)
* Store and compute needed state in EpochStakes struct
Co-authored-by: Carl <carl@solana.com>
2020-03-25 20:43:48 -07:00
Michael Vines
7a8233d7ca Bump version to 1.0.11 2020-03-25 19:17:06 -07:00
mergify[bot]
95bc051129 Cargo update bumpalo (#9067) (#9077)
automerge
2020-03-25 18:51:38 -07:00
mergify[bot]
02bcf4f8e2 ledger-tool can now decode stake instructions (bp #9045) (#9076)
automerge
2020-03-25 18:02:31 -07:00
sakridge
4b0d4e9834 Remove accounts unwrap (#9063)
automerge
2020-03-25 10:59:52 -07:00
mergify[bot]
bf4cdc091a Fix xargo to version 0.3.19 to avoid unstable feature (#9065) (#9066)
automerge

(cherry picked from commit c558db2a48)

Co-authored-by: Justin Starry <justin@solana.com>
2020-03-25 08:48:22 -07:00
mergify[bot]
5f2cf2b44d Increase vmap count in sys-tuner (#8940) (#9064)
(cherry picked from commit a70008cc5c)

Co-authored-by: sakridge <sakridge@gmail.com>
2020-03-25 08:06:36 -07:00
mergify[bot]
03aae5eb5f Ignore RUSTSEC-2020-0006 for the moment (#9057) (#9059)
automerge
2020-03-24 21:06:15 -07:00
mergify[bot]
5f1ce81fbc ledger tool now outputs transaction status information if available (#9024) (#9026)
automerge
2020-03-24 12:23:25 -07:00
mergify[bot]
fc582aa57c Refactor how pubsub subscriptions are added (#9042) (#9049)
automerge
2020-03-24 11:05:33 -07:00
mergify[bot]
13676e9614 Fix timeout for subscriptions test (#9043) (#9044)
automerge
2020-03-24 02:57:25 -07:00
Michael Vines
7636a0521f solana-install-init: --pubkey is no longer required on platforms without a default update manifest 2020-03-23 22:40:53 -07:00
Michael Vines
ad06354a18 Remove , 2020-03-23 22:11:56 -07:00
Michael Vines
953cb93e44 Bump version to 1.0.10 2020-03-23 21:58:45 -07:00
143 changed files with 2724 additions and 1607 deletions

View File

@@ -7,6 +7,6 @@
"GITHUB_TOKEN": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:Vq2dkGTOzfEpRht0BAGHFp/hDogMvXJe:tFXHg1epVt2mq9hkuc5sRHe+KAnVREi/p8S+IZu67XRyzdiA/nGak1k860FXYuuzuaE0QWekaEc=]",
"INFLUX_DATABASE": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:5KI9WBkXx3R/W4m256mU5MJOE7N8aAT9:Cb8QFELZ9I60t5zhJ9h55Kcs]",
"INFLUX_PASSWORD": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:hQRMpLCrav+OYkNphkeM4hagdVoZv5Iw:AUO76rr6+gF1OLJA8ZLSG8wHKXgYCPNk6gRCV8rBhZBJ4KwDaxpvOhMl7bxxXG6jol7v4aRa/Lk=]",
"INFLUX_USERNAME": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:R7BNmQjfeqoGDAFTJu9bYTGHol2NgnYN:Q2tOT/EBcFvhFk+DKLKmVU7tLCpVC3Ui]",
"INFLUX_USERNAME": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:R7BNmQjfeqoGDAFTJu9bYTGHol2NgnYN:Q2tOT/EBcFvhFk+DKLKmVU7tLCpVC3Ui]"
}
}

862
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -49,6 +49,7 @@ members = [
"sdk-c",
"scripts",
"sys-tuner",
"transaction-status",
"upload-perf",
"net-utils",
"vote-signer",

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-archiver-lib"
version = "1.0.9"
version = "1.0.12"
description = "Solana Archiver Library"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,22 +15,22 @@ ed25519-dalek = "=1.0.0-pre.1"
log = "0.4.8"
rand = "0.6.5"
rand_chacha = "0.1.1"
solana-client = { path = "../client", version = "1.0.9" }
solana-storage-program = { path = "../programs/storage", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.12" }
solana-storage-program = { path = "../programs/storage", version = "1.0.12" }
thiserror = "1.0"
serde = "1.0.104"
serde_json = "1.0.46"
serde_derive = "1.0.103"
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-chacha = { path = "../chacha", version = "1.0.9" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-perf = { path = "../perf", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.9" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.9" }
solana-metrics = { path = "../metrics", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-chacha = { path = "../chacha", version = "1.0.12" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-perf = { path = "../perf", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-core = { path = "../core", version = "1.0.12" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.12" }
solana-metrics = { path = "../metrics", version = "1.0.12" }
[dev-dependencies]
hex = "0.4.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-archiver-utils"
version = "1.0.9"
version = "1.0.12"
description = "Solana Archiver Utils"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,12 +11,12 @@ edition = "2018"
[dependencies]
log = "0.4.8"
rand = "0.6.5"
solana-chacha = { path = "../chacha", version = "1.0.9" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-perf = { path = "../perf", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-chacha = { path = "../chacha", version = "1.0.12" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-perf = { path = "../perf", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
[dev-dependencies]
hex = "0.4.0"

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-archiver"
version = "1.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -10,11 +10,11 @@ homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
console = "0.9.2"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-metrics = { path = "../metrics", version = "1.0.9" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-core = { path = "../core", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-metrics = { path = "../metrics", version = "1.0.12" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.12" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-banking-bench"
version = "1.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -10,11 +10,11 @@ homepage = "https://solana.com/"
[dependencies]
log = "0.4.6"
rayon = "1.2.0"
solana-core = { path = "../core", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-measure = { path = "../measure", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-measure = { path = "../measure", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
rand = "0.6.5"
crossbeam-channel = "0.3"

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-exchange"
version = "1.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -18,17 +18,17 @@ rand = "0.6.5"
rayon = "1.2.0"
serde_json = "1.0.46"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.9" }
solana-genesis = { path = "../genesis", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.9" }
solana-faucet = { path = "../faucet", version = "1.0.9" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-metrics = { path = "../metrics", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-core = { path = "../core", version = "1.0.12" }
solana-genesis = { path = "../genesis", version = "1.0.12" }
solana-client = { path = "../client", version = "1.0.12" }
solana-faucet = { path = "../faucet", version = "1.0.12" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-metrics = { path = "../metrics", version = "1.0.12" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
[dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "1.0.9" }
solana-local-cluster = { path = "../local-cluster", version = "1.0.12" }

View File

@@ -2,14 +2,14 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-streamer"
version = "1.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-core = { path = "../core", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }

View File

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

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha-cuda"
version = "1.0.9"
version = "1.0.12"
description = "Solana Chacha Cuda APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,12 +10,12 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.9" }
solana-chacha = { path = "../chacha", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-perf = { path = "../perf", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.12" }
solana-chacha = { path = "../chacha", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-perf = { path = "../perf", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
[dev-dependencies]
hex-literal = "0.2.1"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha-sys"
version = "1.0.9"
version = "1.0.12"
description = "Solana chacha-sys"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha"
version = "1.0.9"
version = "1.0.12"
description = "Solana Chacha APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ edition = "2018"
log = "0.4.8"
rand = "0.6.5"
rand_chacha = "0.1.1"
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-perf = { path = "../perf", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-perf = { path = "../perf", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
[dev-dependencies]
hex-literal = "0.2.1"

8
ci/_
View File

@@ -5,7 +5,13 @@
# |source| me
#
base_dir=$(realpath --strip "$(dirname "$0")/..")
_() {
echo "--- $*"
if [[ $(pwd) = $base_dir ]]; then
echo "--- $*"
else
echo "--- $* (wd: $(pwd))"
fi
"$@"
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-clap-utils"
version = "1.0.9"
version = "1.0.12"
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.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
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.0.9"
version = "1.0.12"
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.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -26,28 +26,28 @@ reqwest = { version = "0.10.1", default-features = false, features = ["blocking"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-budget-program = { path = "../programs/budget", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-cli-config = { path = "../cli-config", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.9" }
solana-config-program = { path = "../programs/config", version = "1.0.9" }
solana-faucet = { path = "../faucet", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-stake-program = { path = "../programs/stake", version = "1.0.9" }
solana-storage-program = { path = "../programs/storage", version = "1.0.9" }
solana-vote-program = { path = "../programs/vote", version = "1.0.9" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.9" }
solana-budget-program = { path = "../programs/budget", version = "1.0.12" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-cli-config = { path = "../cli-config", version = "1.0.12" }
solana-client = { path = "../client", version = "1.0.12" }
solana-config-program = { path = "../programs/config", version = "1.0.12" }
solana-faucet = { path = "../faucet", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-stake-program = { path = "../programs/stake", version = "1.0.12" }
solana-storage-program = { path = "../programs/storage", version = "1.0.12" }
solana-vote-program = { path = "../programs/vote", version = "1.0.12" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.12" }
titlecase = "1.1.0"
thiserror = "1.0.11"
url = "2.1.1"
[dev-dependencies]
solana-core = { path = "../core", version = "1.0.9" }
solana-budget-program = { path = "../programs/budget", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.12" }
solana-budget-program = { path = "../programs/budget", version = "1.0.12" }
tempfile = "3.1.0"
[[bin]]

View File

@@ -1181,6 +1181,7 @@ fn process_show_account(
);
println_name_value("Owner:", &account.owner.to_string());
println_name_value("Executable:", &account.executable.to_string());
println_name_value("Rent Epoch:", &account.rent_epoch.to_string());
if let Some(output_file) = output_file {
let mut f = File::create(output_file)?;

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client"
version = "1.0.9"
version = "1.0.12"
description = "Solana Client"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -19,9 +19,10 @@ reqwest = { version = "0.10.1", default-features = false, features = ["blocking"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-vote-program = { path = "../programs/vote", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.12" }
solana-vote-program = { path = "../programs/vote", version = "1.0.12" }
thiserror = "1.0"
tungstenite = "0.10.1"
url = "2.1.1"
@@ -30,4 +31,4 @@ url = "2.1.1"
assert_matches = "1.3.0"
jsonrpc-core = "14.0.5"
jsonrpc-http-server = "14.0.6"
solana-logger = { path = "../logger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.12" }

View File

@@ -2,7 +2,7 @@ use crate::{
client_error::Result,
generic_rpc_client_request::GenericRpcClientRequest,
rpc_request::RpcRequest,
rpc_response::{Response, RpcResponseContext, RpcTransactionStatus},
rpc_response::{Response, RpcResponseContext},
};
use serde_json::{Number, Value};
use solana_sdk::{
@@ -10,6 +10,7 @@ use solana_sdk::{
instruction::InstructionError,
transaction::{self, TransactionError},
};
use solana_transaction_status::TransactionStatus;
use std::{collections::HashMap, sync::RwLock};
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
@@ -100,9 +101,16 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
let status = if self.url == "sig_not_found" {
None
} else {
Some(RpcTransactionStatus { status, slot: 1 })
Some(TransactionStatus {
status,
slot: 1,
confirmations: Some(0),
})
};
serde_json::to_value(vec![status])?
serde_json::to_value(Response {
context: RpcResponseContext { slot: 1 },
value: vec![status],
})?
}
RpcRequest::GetTransactionCount => Value::Number(Number::from(1234)),
RpcRequest::GetSlot => Value::Number(Number::from(0)),

View File

@@ -5,9 +5,9 @@ use crate::{
rpc_client_request::RpcClientRequest,
rpc_request::{RpcError, RpcRequest},
rpc_response::{
Response, RpcAccount, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo,
RpcEpochInfo, RpcFeeCalculator, RpcFeeRateGovernor, RpcIdentity, RpcKeyedAccount,
RpcLeaderSchedule, RpcResult, RpcTransactionStatus, RpcVersionInfo, RpcVoteAccountStatus,
Response, RpcAccount, RpcBlockhashFeeCalculator, RpcContactInfo, RpcEpochInfo,
RpcFeeCalculator, RpcFeeRateGovernor, RpcIdentity, RpcKeyedAccount, RpcLeaderSchedule,
RpcResult, RpcVersionInfo, RpcVoteAccountStatus,
},
};
use bincode::serialize;
@@ -27,6 +27,7 @@ use solana_sdk::{
signers::Signers,
transaction::{self, Transaction, TransactionError},
};
use solana_transaction_status::{ConfirmedBlock, TransactionStatus};
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
use std::{
error,
@@ -123,9 +124,11 @@ impl RpcClient {
json!([[signature.to_string()], commitment_config]),
5,
)?;
let result: Vec<Option<RpcTransactionStatus>> =
let result: Response<Vec<Option<TransactionStatus>>> =
serde_json::from_value(signature_status).unwrap();
Ok(result[0].clone().map(|status_meta| status_meta.status))
Ok(result.value[0]
.clone()
.map(|status_meta| status_meta.status))
}
pub fn get_slot(&self) -> ClientResult<Slot> {
@@ -172,7 +175,7 @@ impl RpcClient {
.map_err(|err| ClientError::new_with_command(err.into(), "GetClusterNodes"))
}
pub fn get_confirmed_block(&self, slot: Slot) -> ClientResult<RpcConfirmedBlock> {
pub fn get_confirmed_block(&self, slot: Slot) -> ClientResult<ConfirmedBlock> {
let response = self
.client
.send(&RpcRequest::GetConfirmedBlock, json!([slot]), 0)
@@ -922,14 +925,25 @@ impl RpcClient {
let response = self
.client
.send(
&RpcRequest::GetNumBlocksSinceSignatureConfirmation,
json!([signature.to_string(), CommitmentConfig::recent().ok()]),
&RpcRequest::GetSignatureStatus,
json!([[signature.to_string()], CommitmentConfig::recent().ok()]),
1,
)
.map_err(|err| err.into_with_command("GetNumBlocksSinceSignatureConfirmation"))?;
serde_json::from_value(response).map_err(|err| {
ClientError::new_with_command(err.into(), "GetNumBlocksSinceSignatureConfirmation")
})
.map_err(|err| err.into_with_command("GetSignatureStatus"))?;
let result: Response<Vec<Option<TransactionStatus>>> =
serde_json::from_value(response).unwrap();
let confirmations = result.value[0]
.clone()
.ok_or_else(|| {
ClientError::new_with_command(
ClientErrorKind::Custom("signature not found".to_string()),
"GetSignatureStatus",
)
})?
.confirmations
.unwrap_or(MAX_LOCKOUT_HISTORY + 1);
Ok(confirmations)
}
pub fn send_and_confirm_transaction_with_spinner<T: Signers>(

View File

@@ -18,7 +18,6 @@ pub enum RpcRequest {
GetIdentity,
GetInflation,
GetLeaderSchedule,
GetNumBlocksSinceSignatureConfirmation,
GetProgramAccounts,
GetRecentBlockhash,
GetFeeCalculatorForBlockhash,
@@ -60,9 +59,6 @@ impl RpcRequest {
RpcRequest::GetIdentity => "getIdentity",
RpcRequest::GetInflation => "getInflation",
RpcRequest::GetLeaderSchedule => "getLeaderSchedule",
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
"getNumBlocksSinceSignatureConfirmation"
}
RpcRequest::GetProgramAccounts => "getProgramAccounts",
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
RpcRequest::GetFeeCalculatorForBlockhash => "getFeeCalculatorForBlockhash",

View File

@@ -1,12 +1,10 @@
use crate::{client_error, rpc_request::RpcError};
use bincode::serialize;
use solana_sdk::{
account::Account,
clock::{Epoch, Slot},
fee_calculator::{FeeCalculator, FeeRateGovernor},
message::MessageHeader,
pubkey::Pubkey,
transaction::{Result, Transaction},
transaction::Result,
};
use std::{collections::HashMap, net::SocketAddr, str::FromStr};
@@ -30,126 +28,6 @@ pub struct RpcBlockCommitment<T> {
pub total_stake: u64,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct RpcReward {
pub pubkey: String,
pub lamports: i64,
}
pub type RpcRewards = Vec<RpcReward>;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcConfirmedBlock {
pub previous_blockhash: String,
pub blockhash: String,
pub parent_slot: Slot,
pub transactions: Vec<RpcTransactionWithStatusMeta>,
pub rewards: RpcRewards,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionWithStatusMeta {
pub transaction: RpcEncodedTransaction,
pub meta: Option<RpcTransactionStatusMeta>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum RpcTransactionEncoding {
Binary,
Json,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", untagged)]
pub enum RpcEncodedTransaction {
Binary(String),
Json(RpcTransaction),
}
impl RpcEncodedTransaction {
pub fn encode(transaction: Transaction, encoding: RpcTransactionEncoding) -> Self {
if encoding == RpcTransactionEncoding::Json {
RpcEncodedTransaction::Json(RpcTransaction {
signatures: transaction
.signatures
.iter()
.map(|sig| sig.to_string())
.collect(),
message: RpcMessage {
header: transaction.message.header,
account_keys: transaction
.message
.account_keys
.iter()
.map(|pubkey| pubkey.to_string())
.collect(),
recent_blockhash: transaction.message.recent_blockhash.to_string(),
instructions: transaction
.message
.instructions
.iter()
.map(|instruction| RpcCompiledInstruction {
program_id_index: instruction.program_id_index,
accounts: instruction.accounts.clone(),
data: bs58::encode(instruction.data.clone()).into_string(),
})
.collect(),
},
})
} else {
RpcEncodedTransaction::Binary(
bs58::encode(serialize(&transaction).unwrap()).into_string(),
)
}
}
}
/// A duplicate representation of a Transaction for pretty JSON serialization
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransaction {
pub signatures: Vec<String>,
pub message: RpcMessage,
}
/// A duplicate representation of a Message for pretty JSON serialization
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcMessage {
pub header: MessageHeader,
pub account_keys: Vec<String>,
pub recent_blockhash: String,
pub instructions: Vec<RpcCompiledInstruction>,
}
/// A duplicate representation of a Message for pretty JSON serialization
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcCompiledInstruction {
pub program_id_index: u8,
pub accounts: Vec<u8>,
pub data: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionStatusMeta {
pub status: Result<()>,
pub fee: u64,
pub pre_balances: Vec<u64>,
pub post_balances: Vec<u64>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionStatus {
pub slot: Slot,
pub status: Result<()>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcBlockhashFeeCalculator {

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-core"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.9"
version = "1.0.12"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -43,33 +43,34 @@ regex = "1.3.4"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-budget-program = { path = "../programs/budget", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.9" }
solana-faucet = { path = "../faucet", version = "1.0.9" }
solana-budget-program = { path = "../programs/budget", version = "1.0.12" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-client = { path = "../client", version = "1.0.12" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.12" }
solana-faucet = { path = "../faucet", version = "1.0.12" }
ed25519-dalek = "=1.0.0-pre.1"
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.9" }
solana-metrics = { path = "../metrics", version = "1.0.9" }
solana-measure = { path = "../measure", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-chacha-cuda = { path = "../chacha-cuda", version = "1.0.9" }
solana-perf = { path = "../perf", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-stake-program = { path = "../programs/stake", version = "1.0.9" }
solana-storage-program = { path = "../programs/storage", version = "1.0.9" }
solana-vote-program = { path = "../programs/vote", version = "1.0.9" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.9" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.12" }
solana-metrics = { path = "../metrics", version = "1.0.12" }
solana-measure = { path = "../measure", version = "1.0.12" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-chacha-cuda = { path = "../chacha-cuda", version = "1.0.12" }
solana-perf = { path = "../perf", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-stake-program = { path = "../programs/stake", version = "1.0.12" }
solana-storage-program = { path = "../programs/storage", version = "1.0.12" }
solana-vote-program = { path = "../programs/vote", version = "1.0.12" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.12" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.0.12" }
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.0.9" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.12" }
trees = "0.2.1"
[dev-dependencies]

View File

@@ -1017,7 +1017,6 @@ mod tests {
};
use crossbeam_channel::unbounded;
use itertools::Itertools;
use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta};
use solana_ledger::{
blockstore::entries_to_test_shreds,
entry::{next_entry, Entry, EntrySlice},
@@ -1030,6 +1029,7 @@ mod tests {
system_transaction,
transaction::TransactionError,
};
use solana_transaction_status::{EncodedTransaction, TransactionWithStatusMeta};
use std::{sync::atomic::Ordering, thread::sleep};
#[test]
@@ -1975,10 +1975,10 @@ mod tests {
let confirmed_block = blockstore.get_confirmed_block(bank.slot(), None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in
for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter()
{
if let RpcEncodedTransaction::Json(transaction) = transaction {
if let EncodedTransaction::Json(transaction) = transaction {
if transaction.signatures[0] == success_signature.to_string() {
assert_eq!(meta.unwrap().status, Ok(()));
} else if transaction.signatures[0] == ix_error_signature.to_string() {

View File

@@ -1,6 +1,8 @@
//! The `ledger_cleanup_service` drops older ledger data to limit disk space usage
use solana_ledger::blockstore::Blockstore;
use solana_ledger::blockstore_db::Result as BlockstoreResult;
use solana_measure::measure::Measure;
use solana_metrics::datapoint_debug;
use solana_sdk::clock::Slot;
use std::string::ToString;
@@ -11,13 +13,22 @@ use std::thread;
use std::thread::{Builder, JoinHandle};
use std::time::Duration;
// - To try and keep the RocksDB size under 512GB:
// Seeing about 1600b/shred, using 2000b/shred for margin, so 250m shreds can be stored in 512gb.
// at 5k shreds/slot at 50k tps, this is 500k slots (~5.5 hours).
// At idle, 60 shreds/slot this is about 4m slots (18 days)
// This is chosen to allow enough time for
// - To try and keep the RocksDB size under 512GB at 50k tps (100 slots take ~2GB).
// - A validator to download a snapshot from a peer and boot from it
// - To make sure that if a validator needs to reboot from its own snapshot, it has enough slots locally
// to catch back up to where it was when it stopped
pub const DEFAULT_MAX_LEDGER_SLOTS: u64 = 270_000;
// Remove a fixed number of slots at a time, it's more efficient than doing it one-by-one
pub const DEFAULT_MAX_LEDGER_SHREDS: u64 = 250_000_000;
// Check for removing slots at this interval so we don't purge too often
// and starve other blockstore users.
pub const DEFAULT_PURGE_SLOT_INTERVAL: u64 = 512;
// Remove a limited number of slots at a time, so the operation
// does not take too long and block other blockstore users.
pub const DEFAULT_PURGE_BATCH_SIZE: u64 = 256;
pub struct LedgerCleanupService {
@@ -36,7 +47,7 @@ impl LedgerCleanupService {
max_ledger_slots
);
let exit = exit.clone();
let mut next_purge_batch = max_ledger_slots;
let mut last_purge_slot = 0;
let t_cleanup = Builder::new()
.name("solana-ledger-cleanup".to_string())
.spawn(move || loop {
@@ -47,7 +58,8 @@ impl LedgerCleanupService {
&new_root_receiver,
&blockstore,
max_ledger_slots,
&mut next_purge_batch,
&mut last_purge_slot,
DEFAULT_PURGE_SLOT_INTERVAL,
) {
match e {
RecvTimeoutError::Disconnected => break,
@@ -59,45 +71,123 @@ impl LedgerCleanupService {
Self { t_cleanup }
}
fn find_slots_to_clean(
blockstore: &Arc<Blockstore>,
root: Slot,
max_ledger_shreds: u64,
) -> (u64, Slot, Slot) {
let mut shreds = Vec::new();
let mut iterate_time = Measure::start("iterate_time");
let mut total_shreds = 0;
let mut first_slot = 0;
for (i, (slot, meta)) in blockstore.slot_meta_iterator(0).unwrap().enumerate() {
if i == 0 {
first_slot = slot;
debug!("purge: searching from slot: {}", slot);
}
// Not exact since non-full slots will have holes
total_shreds += meta.received;
shreds.push((slot, meta.received));
if slot > root {
break;
}
}
iterate_time.stop();
info!(
"checking for ledger purge: max_shreds: {} slots: {} total_shreds: {} {}",
max_ledger_shreds,
shreds.len(),
total_shreds,
iterate_time
);
if (total_shreds as u64) < max_ledger_shreds {
return (0, 0, 0);
}
let mut cur_shreds = 0;
let mut lowest_slot_to_clean = shreds[0].0;
for (slot, num_shreds) in shreds.iter().rev() {
cur_shreds += *num_shreds as u64;
if cur_shreds > max_ledger_shreds {
lowest_slot_to_clean = *slot;
break;
}
}
(cur_shreds, lowest_slot_to_clean, first_slot)
}
fn cleanup_ledger(
new_root_receiver: &Receiver<Slot>,
blockstore: &Arc<Blockstore>,
max_ledger_slots: u64,
next_purge_batch: &mut u64,
max_ledger_shreds: u64,
last_purge_slot: &mut u64,
purge_interval: u64,
) -> Result<(), RecvTimeoutError> {
let disk_utilization_pre = blockstore.storage_size();
let root = new_root_receiver.recv_timeout(Duration::from_secs(1))?;
// Notify blockstore of impending purge
if root > *next_purge_batch {
//cleanup
let lowest_slot = root - max_ledger_slots;
*blockstore.lowest_cleanup_slot.write().unwrap() = lowest_slot;
blockstore.purge_slots(0, Some(lowest_slot));
*next_purge_batch += DEFAULT_PURGE_BATCH_SIZE;
let mut root = new_root_receiver.recv_timeout(Duration::from_secs(1))?;
// Get the newest root
while let Ok(new_root) = new_root_receiver.try_recv() {
root = new_root;
}
let disk_utilization_post = blockstore.storage_size();
if let (Ok(disk_utilization_pre), Ok(disk_utilization_post)) =
(disk_utilization_pre, disk_utilization_post)
{
datapoint_debug!(
"ledger_disk_utilization",
("disk_utilization_pre", disk_utilization_pre as i64, i64),
("disk_utilization_post", disk_utilization_post as i64, i64),
(
"disk_utilization_delta",
(disk_utilization_pre as i64 - disk_utilization_post as i64),
i64
)
if root - *last_purge_slot > purge_interval {
let disk_utilization_pre = blockstore.storage_size();
info!(
"purge: new root: {} last_purge: {} purge_interval: {} disk: {:?}",
root, last_purge_slot, purge_interval, disk_utilization_pre
);
*last_purge_slot = root;
let (num_shreds_to_clean, lowest_slot_to_clean, mut first_slot) =
Self::find_slots_to_clean(blockstore, root, max_ledger_shreds);
if num_shreds_to_clean > 0 {
debug!(
"cleaning up to: {} shreds: {} first: {}",
lowest_slot_to_clean, num_shreds_to_clean, first_slot
);
loop {
let current_lowest =
std::cmp::min(lowest_slot_to_clean, first_slot + DEFAULT_PURGE_BATCH_SIZE);
let mut slot_update_time = Measure::start("slot_update");
*blockstore.lowest_cleanup_slot.write().unwrap() = current_lowest;
slot_update_time.stop();
let mut clean_time = Measure::start("ledger_clean");
blockstore.purge_slots(first_slot, Some(current_lowest));
clean_time.stop();
debug!(
"ledger purge {} -> {}: {} {}",
first_slot, current_lowest, slot_update_time, clean_time
);
first_slot += DEFAULT_PURGE_BATCH_SIZE;
if current_lowest == lowest_slot_to_clean {
break;
}
thread::sleep(Duration::from_millis(500));
}
}
let disk_utilization_post = blockstore.storage_size();
Self::report_disk_metrics(disk_utilization_pre, disk_utilization_post);
}
Ok(())
}
fn report_disk_metrics(pre: BlockstoreResult<u64>, post: BlockstoreResult<u64>) {
if let (Ok(pre), Ok(post)) = (pre, post) {
datapoint_debug!(
"ledger_disk_utilization",
("disk_utilization_pre", pre as i64, i64),
("disk_utilization_post", post as i64, i64),
("disk_utilization_delta", (pre as i64 - post as i64), i64)
);
}
}
pub fn join(self) -> thread::Result<()> {
self.t_cleanup.join()
}
@@ -111,6 +201,7 @@ mod tests {
#[test]
fn test_cleanup() {
solana_logger::setup();
let blockstore_path = get_tmp_ledger_path!();
let blockstore = Blockstore::open(&blockstore_path).unwrap();
let (shreds, _) = make_many_slot_entries(0, 50, 5);
@@ -118,10 +209,10 @@ mod tests {
let blockstore = Arc::new(blockstore);
let (sender, receiver) = channel();
//send a signal to kill slots 0-40
let mut next_purge_slot = 0;
//send a signal to kill all but 5 shreds, which will be in the newest slots
let mut last_purge_slot = 0;
sender.send(50).unwrap();
LedgerCleanupService::cleanup_ledger(&receiver, &blockstore, 10, &mut next_purge_slot)
LedgerCleanupService::cleanup_ledger(&receiver, &blockstore, 5, &mut last_purge_slot, 10)
.unwrap();
//check that 0-40 don't exist
@@ -134,6 +225,62 @@ mod tests {
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
#[test]
fn test_cleanup_speed() {
solana_logger::setup();
let blockstore_path = get_tmp_ledger_path!();
let mut blockstore = Blockstore::open(&blockstore_path).unwrap();
blockstore.set_no_compaction(true);
let blockstore = Arc::new(blockstore);
let (sender, receiver) = channel();
let mut first_insert = Measure::start("first_insert");
let initial_slots = 50;
let initial_entries = 5;
let (shreds, _) = make_many_slot_entries(0, initial_slots, initial_entries);
blockstore.insert_shreds(shreds, None, false).unwrap();
first_insert.stop();
info!("{}", first_insert);
let mut last_purge_slot = 0;
let mut slot = initial_slots;
let mut num_slots = 6;
for _ in 0..5 {
let mut insert_time = Measure::start("insert time");
let batch_size = 2;
let batches = num_slots / batch_size;
for i in 0..batches {
let (shreds, _) = make_many_slot_entries(slot + i * batch_size, batch_size, 5);
blockstore.insert_shreds(shreds, None, false).unwrap();
if i % 100 == 0 {
info!("inserting..{} of {}", i, batches);
}
}
insert_time.stop();
let mut time = Measure::start("purge time");
sender.send(slot + num_slots).unwrap();
LedgerCleanupService::cleanup_ledger(
&receiver,
&blockstore,
initial_slots,
&mut last_purge_slot,
10,
)
.unwrap();
time.stop();
info!(
"slot: {} size: {} {} {}",
slot, num_slots, insert_time, time
);
slot += num_slots;
num_slots *= 2;
}
drop(blockstore);
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
#[test]
fn test_compaction() {
let blockstore_path = get_tmp_ledger_path!();
@@ -142,7 +289,7 @@ mod tests {
let n = 10_000;
let batch_size = 100;
let batches = n / batch_size;
let max_ledger_slots = 100;
let max_ledger_shreds = 100;
for i in 0..batches {
let (shreds, _) = make_many_slot_entries(i * batch_size, batch_size, 1);
@@ -158,8 +305,9 @@ mod tests {
LedgerCleanupService::cleanup_ledger(
&receiver,
&blockstore,
max_ledger_slots,
max_ledger_shreds,
&mut next_purge_batch,
10,
)
.unwrap();
@@ -170,7 +318,7 @@ mod tests {
assert!(u2 < u1, "insufficient compaction! pre={},post={}", u1, u2,);
// check that early slots don't exist
let max_slot = n - max_ledger_slots;
let max_slot = n - max_ledger_shreds - 1;
blockstore
.slot_meta_iterator(0)
.unwrap()

View File

@@ -336,6 +336,7 @@ impl ReplayStage {
&lockouts_sender,
&accounts_hash_sender,
&latest_root_senders,
&subscriptions,
)?;
}
datapoint_debug!(
@@ -607,6 +608,7 @@ impl ReplayStage {
lockouts_sender: &Sender<CommitmentAggregationData>,
accounts_hash_sender: &Option<SnapshotPackageSender>,
latest_root_senders: &[Sender<Slot>],
subscriptions: &Arc<RpcSubscriptions>,
) -> Result<()> {
if bank.is_empty() {
inc_new_counter_info!("replay_stage-voted_empty_bank", 1);
@@ -633,6 +635,7 @@ impl ReplayStage {
.set_roots(&rooted_slots)
.expect("Ledger set roots failed");
Self::handle_new_root(new_root, &bank_forks, progress, accounts_hash_sender);
subscriptions.notify_roots(rooted_slots);
latest_root_senders.iter().for_each(|s| {
if let Err(e) = s.send(new_root) {
trace!("latest root send failed: {:?}", e);
@@ -1066,7 +1069,6 @@ pub(crate) mod tests {
transaction_status_service::TransactionStatusService,
};
use crossbeam_channel::unbounded;
use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta};
use solana_ledger::{
blockstore::make_slot_entries,
blockstore::{entries_to_test_shreds, BlockstoreError},
@@ -1090,6 +1092,7 @@ pub(crate) mod tests {
transaction::TransactionError,
};
use solana_stake_program::stake_state;
use solana_transaction_status::{EncodedTransaction, TransactionWithStatusMeta};
use solana_vote_program::{
vote_state::{self, Vote, VoteState, VoteStateVersions},
vote_transaction,
@@ -1899,10 +1902,10 @@ pub(crate) mod tests {
let confirmed_block = blockstore.get_confirmed_block(slot, None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in
for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter()
{
if let RpcEncodedTransaction::Json(transaction) = transaction {
if let EncodedTransaction::Json(transaction) = transaction {
if transaction.signatures[0] == signatures[0].to_string() {
assert_eq!(meta.unwrap().status, Ok(()));
} else if transaction.signatures[0] == signatures[1].to_string() {

View File

@@ -1,7 +1,7 @@
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
use solana_client::rpc_response::RpcReward;
use solana_ledger::blockstore::Blockstore;
use solana_sdk::{clock::Slot, pubkey::Pubkey};
use solana_transaction_status::Reward;
use std::{
sync::{
atomic::{AtomicBool, Ordering},
@@ -49,7 +49,7 @@ impl RewardsRecorderService {
let (slot, rewards) = rewards_receiver.recv_timeout(Duration::from_secs(1))?;
let rpc_rewards = rewards
.into_iter()
.map(|(pubkey, lamports)| RpcReward {
.map(|(pubkey, lamports)| Reward {
pubkey: pubkey.to_string(),
lamports,
})

View File

@@ -24,6 +24,7 @@ use solana_sdk::{
timing::slot_duration_from_slots_per_year,
transaction::Transaction,
};
use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatus};
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{
collections::HashMap,
@@ -215,25 +216,6 @@ impl JsonRpcRequestProcessor {
}
}
pub fn get_signature_confirmation_status(
&self,
signature: Signature,
commitment: Option<CommitmentConfig>,
) -> Option<RpcSignatureConfirmation> {
self.bank(commitment)
.get_signature_confirmation_status(&signature)
.map(
|SignatureConfirmationStatus {
confirmations,
status,
..
}| RpcSignatureConfirmation {
confirmations,
status,
},
)
}
fn get_slot(&self, commitment: Option<CommitmentConfig>) -> Result<u64> {
Ok(self.bank(commitment).slot())
}
@@ -365,8 +347,8 @@ impl JsonRpcRequestProcessor {
pub fn get_confirmed_block(
&self,
slot: Slot,
encoding: Option<RpcTransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>> {
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedBlock>> {
if self.config.enable_rpc_transaction_history {
Ok(self.blockstore.get_confirmed_block(slot, encoding).ok())
} else {
@@ -420,21 +402,33 @@ impl JsonRpcRequestProcessor {
&self,
signatures: Vec<Signature>,
commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>> {
let mut statuses: Vec<Option<RpcTransactionStatus>> = vec![];
) -> RpcResponse<Vec<Option<TransactionStatus>>> {
let mut statuses: Vec<Option<TransactionStatus>> = vec![];
let bank = self.bank(commitment);
for signature in signatures {
let status = bank.get_signature_confirmation_status(&signature).map(
|SignatureConfirmationStatus { slot, status, .. }| RpcTransactionStatus {
|SignatureConfirmationStatus {
slot,
status,
confirmations,
}| TransactionStatus {
slot,
status,
confirmations: if confirmations <= MAX_LOCKOUT_HISTORY {
Some(confirmations)
} else {
None
},
},
);
statuses.push(status);
}
Ok(statuses)
Ok(Response {
context: RpcResponseContext { slot: bank.slot() },
value: statuses,
})
}
}
@@ -564,7 +558,7 @@ pub trait RpcSol {
meta: Self::Metadata,
signature_strs: Vec<String>,
commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>>;
) -> RpcResponse<Vec<Option<TransactionStatus>>>;
#[rpc(meta, name = "getSlot")]
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64>;
@@ -631,22 +625,6 @@ pub trait RpcSol {
#[rpc(meta, name = "validatorExit")]
fn validator_exit(&self, meta: Self::Metadata) -> Result<bool>;
#[rpc(meta, name = "getNumBlocksSinceSignatureConfirmation")]
fn get_num_blocks_since_signature_confirmation(
&self,
meta: Self::Metadata,
signature_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<Option<usize>>;
#[rpc(meta, name = "getSignatureConfirmation")]
fn get_signature_confirmation(
&self,
meta: Self::Metadata,
signature_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<Option<RpcSignatureConfirmation>>;
#[rpc(meta, name = "getIdentity")]
fn get_identity(&self, meta: Self::Metadata) -> Result<RpcIdentity>;
@@ -661,8 +639,8 @@ pub trait RpcSol {
&self,
meta: Self::Metadata,
slot: Slot,
encoding: Option<RpcTransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>>;
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedBlock>>;
#[rpc(meta, name = "getBlockTime")]
fn get_block_time(&self, meta: Self::Metadata, slot: Slot) -> Result<Option<UnixTimestamp>>;
@@ -910,7 +888,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata,
signature_strs: Vec<String>,
commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>> {
) -> RpcResponse<Vec<Option<TransactionStatus>>> {
let mut signatures: Vec<Signature> = vec![];
for signature_str in signature_strs {
signatures.push(verify_signature(&signature_str)?);
@@ -925,34 +903,6 @@ impl RpcSol for RpcSolImpl {
meta.request_processor.read().unwrap().get_slot(commitment)
}
fn get_num_blocks_since_signature_confirmation(
&self,
meta: Self::Metadata,
signature_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<Option<usize>> {
self.get_signature_confirmation(meta, signature_str, commitment)
.map(|res| res.map(|x| x.confirmations))
}
fn get_signature_confirmation(
&self,
meta: Self::Metadata,
signature_str: String,
commitment: Option<CommitmentConfig>,
) -> Result<Option<RpcSignatureConfirmation>> {
debug!(
"get_signature_confirmation rpc request received: {:?}",
signature_str
);
let signature = verify_signature(&signature_str)?;
Ok(meta
.request_processor
.read()
.unwrap()
.get_signature_confirmation_status(signature, commitment))
}
fn get_transaction_count(
&self,
meta: Self::Metadata,
@@ -1039,7 +989,9 @@ impl RpcSol for RpcSolImpl {
.request_processor
.read()
.unwrap()
.get_signature_confirmation_status(signature, commitment.clone())
.get_signature_status(vec![signature], commitment.clone())?
.value[0]
.clone()
.map(|x| x.status);
if signature_status == Some(Ok(())) {
@@ -1181,8 +1133,8 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
slot: Slot,
encoding: Option<RpcTransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>> {
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedBlock>> {
meta.request_processor
.read()
.unwrap()
@@ -1217,7 +1169,6 @@ pub mod tests {
};
use bincode::deserialize;
use jsonrpc_core::{MetaIoHandler, Output, Response, Value};
use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta};
use solana_ledger::{
blockstore::entries_to_test_shreds, blockstore_processor::fill_blockstore_slot_with_ticks,
entry::next_entry_mut, get_tmp_ledger_path,
@@ -1231,6 +1182,7 @@ pub mod tests {
system_transaction,
transaction::{self, TransactionError},
};
use solana_transaction_status::{EncodedTransaction, TransactionWithStatusMeta};
use solana_vote_program::{
vote_instruction,
vote_state::{Vote, VoteInit, MAX_LOCKOUT_HISTORY},
@@ -1813,10 +1765,10 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta.clone());
let expected_res: transaction::Result<()> = Ok(());
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let result: Vec<Option<RpcTransactionStatus>> =
serde_json::from_value(json["result"].clone())
let result: Option<TransactionStatus> =
serde_json::from_value(json["result"]["value"][0].clone())
.expect("actual response deserialization");
assert_eq!(expected_res, result[0].as_ref().unwrap().status);
assert_eq!(expected_res, result.as_ref().unwrap().status);
// Test getSignatureStatus request on unprocessed tx
let tx = system_transaction::transfer(&alice, &bob_pubkey, 10, blockhash);
@@ -1826,10 +1778,10 @@ pub mod tests {
);
let res = io.handle_request_sync(&req, meta.clone());
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let result: Vec<Option<RpcTransactionStatus>> =
serde_json::from_value(json["result"].clone())
let result: Option<TransactionStatus> =
serde_json::from_value(json["result"]["value"][0].clone())
.expect("actual response deserialization");
assert!(result[0].is_none());
assert!(result.is_none());
// Test getSignatureStatus request on a TransactionError
let req = format!(
@@ -1842,10 +1794,10 @@ pub mod tests {
InstructionError::CustomError(1),
));
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let result: Vec<Option<RpcTransactionStatus>> =
serde_json::from_value(json["result"].clone())
let result: Option<TransactionStatus> =
serde_json::from_value(json["result"]["value"][0].clone())
.expect("actual response deserialization");
assert_eq!(expected_res, result[0].as_ref().unwrap().status);
assert_eq!(expected_res, result.as_ref().unwrap().status);
}
#[test]
@@ -2284,15 +2236,15 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta.clone());
let result: Value = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
let confirmed_block: Option<RpcConfirmedBlock> =
let confirmed_block: Option<ConfirmedBlock> =
serde_json::from_value(result["result"].clone()).unwrap();
let confirmed_block = confirmed_block.unwrap();
assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in
for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter()
{
if let RpcEncodedTransaction::Json(transaction) = transaction {
if let EncodedTransaction::Json(transaction) = transaction {
if transaction.signatures[0] == confirmed_block_signatures[0].to_string() {
assert_eq!(transaction.message.recent_blockhash, blockhash.to_string());
assert_eq!(meta.unwrap().status, Ok(()));
@@ -2316,15 +2268,15 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta);
let result: Value = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
let confirmed_block: Option<RpcConfirmedBlock> =
let confirmed_block: Option<ConfirmedBlock> =
serde_json::from_value(result["result"].clone()).unwrap();
let confirmed_block = confirmed_block.unwrap();
assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in
for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter()
{
if let RpcEncodedTransaction::Binary(transaction) = transaction {
if let EncodedTransaction::Binary(transaction) = transaction {
let decoded_transaction: Transaction =
deserialize(&bs58::decode(&transaction).into_vec().unwrap()).unwrap();
if decoded_transaction.signatures[0] == confirmed_block_signatures[0] {

View File

@@ -5,7 +5,7 @@ use jsonrpc_core::{Error, ErrorCode, Result};
use jsonrpc_derive::rpc;
use jsonrpc_pubsub::{typed::Subscriber, Session, SubscriptionId};
use solana_client::rpc_response::{Response as RpcResponse, RpcAccount, RpcKeyedAccount};
use solana_sdk::{pubkey::Pubkey, signature::Signature, transaction};
use solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature, transaction};
use std::sync::{atomic, Arc};
// Suppress needless_return due to
@@ -102,6 +102,18 @@ pub trait RpcSolPubSub {
name = "slotUnsubscribe"
)]
fn slot_unsubscribe(&self, meta: Option<Self::Metadata>, id: SubscriptionId) -> Result<bool>;
// Get notification when a new root is set
#[pubsub(subscription = "rootNotification", subscribe, name = "rootSubscribe")]
fn root_subscribe(&self, meta: Self::Metadata, subscriber: Subscriber<Slot>);
// Unsubscribe from slot notification subscription.
#[pubsub(
subscription = "rootNotification",
unsubscribe,
name = "rootUnsubscribe"
)]
fn root_unsubscribe(&self, meta: Option<Self::Metadata>, id: SubscriptionId) -> Result<bool>;
}
#[derive(Default)]
@@ -142,10 +154,12 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
let id = self.uid.fetch_add(1, atomic::Ordering::Relaxed);
let sub_id = SubscriptionId::Number(id as u64);
info!("account_subscribe: account={:?} id={:?}", pubkey, sub_id);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
self.subscriptions
.add_account_subscription(&pubkey, confirmations, &sub_id, &sink)
self.subscriptions.add_account_subscription(
pubkey,
confirmations,
sub_id,
subscriber,
)
}
Err(e) => subscriber.reject(e).unwrap(),
}
@@ -180,10 +194,12 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
let id = self.uid.fetch_add(1, atomic::Ordering::Relaxed);
let sub_id = SubscriptionId::Number(id as u64);
info!("program_subscribe: account={:?} id={:?}", pubkey, sub_id);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
self.subscriptions
.add_program_subscription(&pubkey, confirmations, &sub_id, &sink)
self.subscriptions.add_program_subscription(
pubkey,
confirmations,
sub_id,
subscriber,
)
}
Err(e) => subscriber.reject(e).unwrap(),
}
@@ -222,13 +238,11 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
"signature_subscribe: signature={:?} id={:?}",
signature, sub_id
);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
self.subscriptions.add_signature_subscription(
&signature,
signature,
confirmations,
&sub_id,
&sink,
sub_id,
subscriber,
);
}
Err(e) => subscriber.reject(e).unwrap(),
@@ -257,9 +271,7 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
let id = self.uid.fetch_add(1, atomic::Ordering::Relaxed);
let sub_id = SubscriptionId::Number(id as u64);
info!("slot_subscribe: id={:?}", sub_id);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
self.subscriptions.add_slot_subscription(&sub_id, &sink);
self.subscriptions.add_slot_subscription(sub_id, subscriber);
}
fn slot_unsubscribe(&self, _meta: Option<Self::Metadata>, id: SubscriptionId) -> Result<bool> {
@@ -274,6 +286,27 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
})
}
}
fn root_subscribe(&self, _meta: Self::Metadata, subscriber: Subscriber<Slot>) {
info!("root_subscribe");
let id = self.uid.fetch_add(1, atomic::Ordering::Relaxed);
let sub_id = SubscriptionId::Number(id as u64);
info!("root_subscribe: id={:?}", sub_id);
self.subscriptions.add_root_subscription(sub_id, subscriber);
}
fn root_unsubscribe(&self, _meta: Option<Self::Metadata>, id: SubscriptionId) -> Result<bool> {
info!("root_unsubscribe");
if self.subscriptions.remove_root_subscription(&id) {
Ok(true)
} else {
Err(Error {
code: ErrorCode::InvalidParams,
message: "Invalid Request: Subscription id does not exist".into(),
data: None,
})
}
}
}
#[cfg(test)]
@@ -338,7 +371,7 @@ mod tests {
process_transaction_and_notify(&bank_forks, &tx, &rpc.subscriptions).unwrap();
// Test signature confirmation notification
let response = robust_poll_or_panic(receiver);
let (response, _) = robust_poll_or_panic(receiver);
let expected_res: Option<transaction::Result<()>> = Some(Ok(()));
let expected = json!({
"jsonrpc": "2.0",
@@ -480,7 +513,7 @@ mod tests {
}
});
let response = robust_poll_or_panic(receiver);
let (response, _) = robust_poll_or_panic(receiver);
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
let tx = system_transaction::transfer(&alice, &witness.pubkey(), 1, blockhash);
@@ -629,7 +662,7 @@ mod tests {
"subscription": 0,
}
});
let response = robust_poll_or_panic(receiver);
let (response, _) = robust_poll_or_panic(receiver);
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
}
@@ -642,7 +675,7 @@ mod tests {
rpc.subscriptions.notify_slot(0, 0, 0);
// Test slot confirmation notification
let response = robust_poll_or_panic(receiver);
let (response, _) = robust_poll_or_panic(receiver);
let expected_res = SlotInfo {
parent: 0,
slot: 0,
@@ -664,7 +697,7 @@ mod tests {
let (subscriber, _id_receiver, receiver) = Subscriber::new_test("slotNotification");
rpc.slot_subscribe(session, subscriber);
rpc.subscriptions.notify_slot(0, 0, 0);
let response = robust_poll_or_panic(receiver);
let (response, _) = robust_poll_or_panic(receiver);
let expected_res = SlotInfo {
parent: 0,
slot: 0,

View File

@@ -2,7 +2,10 @@
use core::hash::Hash;
use jsonrpc_core::futures::Future;
use jsonrpc_pubsub::{typed::Sink, SubscriptionId};
use jsonrpc_pubsub::{
typed::{Sink, Subscriber},
SubscriptionId,
};
use serde::Serialize;
use solana_client::rpc_response::{Response, RpcAccount, RpcKeyedAccount, RpcResponseContext};
use solana_ledger::bank_forks::BankForks;
@@ -35,12 +38,14 @@ pub struct SlotInfo {
enum NotificationEntry {
Slot(SlotInfo),
Root(Slot),
Bank((Slot, Arc<RwLock<BankForks>>)),
}
impl std::fmt::Debug for NotificationEntry {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
NotificationEntry::Root(root) => write!(f, "Root({})", root),
NotificationEntry::Slot(slot_info) => write!(f, "Slot({:?})", slot_info),
NotificationEntry::Bank((current_slot, _)) => {
write!(f, "Bank({{current_slot: {:?}}})", current_slot)
@@ -61,30 +66,32 @@ type RpcSignatureSubscriptions = RwLock<
>,
>;
type RpcSlotSubscriptions = RwLock<HashMap<SubscriptionId, Sink<SlotInfo>>>;
type RpcRootSubscriptions = RwLock<HashMap<SubscriptionId, Sink<Slot>>>;
fn add_subscription<K, S>(
subscriptions: &mut HashMap<K, HashMap<SubscriptionId, (Sink<S>, Confirmations)>>,
hashmap_key: &K,
hashmap_key: K,
confirmations: Option<Confirmations>,
sub_id: &SubscriptionId,
sink: &Sink<S>,
sub_id: SubscriptionId,
subscriber: Subscriber<S>,
) where
K: Eq + Hash + Clone + Copy,
K: Eq + Hash,
S: Clone,
{
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
let confirmations = confirmations.unwrap_or(0);
let confirmations = if confirmations > MAX_LOCKOUT_HISTORY {
MAX_LOCKOUT_HISTORY
} else {
confirmations
};
if let Some(current_hashmap) = subscriptions.get_mut(hashmap_key) {
current_hashmap.insert(sub_id.clone(), (sink.clone(), confirmations));
if let Some(current_hashmap) = subscriptions.get_mut(&hashmap_key) {
current_hashmap.insert(sub_id, (sink, confirmations));
return;
}
let mut hashmap = HashMap::new();
hashmap.insert(sub_id.clone(), (sink.clone(), confirmations));
subscriptions.insert(*hashmap_key, hashmap);
hashmap.insert(sub_id, (sink, confirmations));
subscriptions.insert(hashmap_key, hashmap);
}
fn remove_subscription<K, S>(
@@ -92,13 +99,13 @@ fn remove_subscription<K, S>(
sub_id: &SubscriptionId,
) -> bool
where
K: Eq + Hash + Clone + Copy,
K: Eq + Hash,
S: Clone,
{
let mut found = false;
subscriptions.retain(|_, v| {
v.retain(|k, _| {
let retain = *k != *sub_id;
let retain = k != sub_id;
if !retain {
found = true;
}
@@ -220,6 +227,7 @@ pub struct RpcSubscriptions {
program_subscriptions: Arc<RpcProgramSubscriptions>,
signature_subscriptions: Arc<RpcSignatureSubscriptions>,
slot_subscriptions: Arc<RpcSlotSubscriptions>,
root_subscriptions: Arc<RpcRootSubscriptions>,
notification_sender: Arc<Mutex<Sender<NotificationEntry>>>,
t_cleanup: Option<JoinHandle<()>>,
notifier_runtime: Option<Runtime>,
@@ -251,6 +259,7 @@ impl RpcSubscriptions {
let program_subscriptions = Arc::new(RpcProgramSubscriptions::default());
let signature_subscriptions = Arc::new(RpcSignatureSubscriptions::default());
let slot_subscriptions = Arc::new(RpcSlotSubscriptions::default());
let root_subscriptions = Arc::new(RpcRootSubscriptions::default());
let notification_sender = Arc::new(Mutex::new(notification_sender));
let exit_clone = exit.clone();
@@ -258,6 +267,7 @@ impl RpcSubscriptions {
let program_subscriptions_clone = program_subscriptions.clone();
let signature_subscriptions_clone = signature_subscriptions.clone();
let slot_subscriptions_clone = slot_subscriptions.clone();
let root_subscriptions_clone = root_subscriptions.clone();
let notifier_runtime = RuntimeBuilder::new()
.core_threads(1)
@@ -277,6 +287,7 @@ impl RpcSubscriptions {
program_subscriptions_clone,
signature_subscriptions_clone,
slot_subscriptions_clone,
root_subscriptions_clone,
);
})
.unwrap();
@@ -286,6 +297,7 @@ impl RpcSubscriptions {
program_subscriptions,
signature_subscriptions,
slot_subscriptions,
root_subscriptions,
notification_sender,
notifier_runtime: Some(notifier_runtime),
t_cleanup: Some(t_cleanup),
@@ -358,13 +370,19 @@ impl RpcSubscriptions {
pub fn add_account_subscription(
&self,
pubkey: &Pubkey,
pubkey: Pubkey,
confirmations: Option<Confirmations>,
sub_id: &SubscriptionId,
sink: &Sink<Response<RpcAccount>>,
sub_id: SubscriptionId,
subscriber: Subscriber<Response<RpcAccount>>,
) {
let mut subscriptions = self.account_subscriptions.write().unwrap();
add_subscription(&mut subscriptions, pubkey, confirmations, sub_id, sink);
add_subscription(
&mut subscriptions,
pubkey,
confirmations,
sub_id,
subscriber,
);
}
pub fn remove_account_subscription(&self, id: &SubscriptionId) -> bool {
@@ -374,13 +392,19 @@ impl RpcSubscriptions {
pub fn add_program_subscription(
&self,
program_id: &Pubkey,
program_id: Pubkey,
confirmations: Option<Confirmations>,
sub_id: &SubscriptionId,
sink: &Sink<Response<RpcKeyedAccount>>,
sub_id: SubscriptionId,
subscriber: Subscriber<Response<RpcKeyedAccount>>,
) {
let mut subscriptions = self.program_subscriptions.write().unwrap();
add_subscription(&mut subscriptions, program_id, confirmations, sub_id, sink);
add_subscription(
&mut subscriptions,
program_id,
confirmations,
sub_id,
subscriber,
);
}
pub fn remove_program_subscription(&self, id: &SubscriptionId) -> bool {
@@ -390,13 +414,19 @@ impl RpcSubscriptions {
pub fn add_signature_subscription(
&self,
signature: &Signature,
signature: Signature,
confirmations: Option<Confirmations>,
sub_id: &SubscriptionId,
sink: &Sink<Response<transaction::Result<()>>>,
sub_id: SubscriptionId,
subscriber: Subscriber<Response<transaction::Result<()>>>,
) {
let mut subscriptions = self.signature_subscriptions.write().unwrap();
add_subscription(&mut subscriptions, signature, confirmations, sub_id, sink);
add_subscription(
&mut subscriptions,
signature,
confirmations,
sub_id,
subscriber,
);
}
pub fn remove_signature_subscription(&self, id: &SubscriptionId) -> bool {
@@ -410,9 +440,10 @@ impl RpcSubscriptions {
self.enqueue_notification(NotificationEntry::Bank((current_slot, bank_forks.clone())));
}
pub fn add_slot_subscription(&self, sub_id: &SubscriptionId, sink: &Sink<SlotInfo>) {
pub fn add_slot_subscription(&self, sub_id: SubscriptionId, subscriber: Subscriber<SlotInfo>) {
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
let mut subscriptions = self.slot_subscriptions.write().unwrap();
subscriptions.insert(sub_id.clone(), sink.clone());
subscriptions.insert(sub_id, sink);
}
pub fn remove_slot_subscription(&self, id: &SubscriptionId) -> bool {
@@ -424,6 +455,24 @@ impl RpcSubscriptions {
self.enqueue_notification(NotificationEntry::Slot(SlotInfo { slot, parent, root }));
}
pub fn add_root_subscription(&self, sub_id: SubscriptionId, subscriber: Subscriber<Slot>) {
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
let mut subscriptions = self.root_subscriptions.write().unwrap();
subscriptions.insert(sub_id, sink);
}
pub fn remove_root_subscription(&self, id: &SubscriptionId) -> bool {
let mut subscriptions = self.root_subscriptions.write().unwrap();
subscriptions.remove(id).is_some()
}
pub fn notify_roots(&self, mut rooted_slots: Vec<Slot>) {
rooted_slots.sort();
rooted_slots.into_iter().for_each(|root| {
self.enqueue_notification(NotificationEntry::Root(root));
});
}
fn enqueue_notification(&self, notification_entry: NotificationEntry) {
match self
.notification_sender
@@ -449,6 +498,7 @@ impl RpcSubscriptions {
program_subscriptions: Arc<RpcProgramSubscriptions>,
signature_subscriptions: Arc<RpcSignatureSubscriptions>,
slot_subscriptions: Arc<RpcSlotSubscriptions>,
root_subscriptions: Arc<RpcRootSubscriptions>,
) {
loop {
if exit.load(Ordering::Relaxed) {
@@ -462,6 +512,12 @@ impl RpcSubscriptions {
notifier.notify(slot_info, sink);
}
}
NotificationEntry::Root(root) => {
let subscriptions = root_subscriptions.read().unwrap();
for (_, sink) in subscriptions.iter() {
notifier.notify(root, sink);
}
}
NotificationEntry::Bank((current_slot, bank_forks)) => {
let pubkeys: Vec<_> = {
let subs = account_subscriptions.read().unwrap();
@@ -541,33 +597,39 @@ impl RpcSubscriptions {
pub(crate) mod tests {
use super::*;
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
use jsonrpc_core::futures;
use jsonrpc_core::futures::{self, stream::Stream};
use jsonrpc_pubsub::typed::Subscriber;
use solana_budget_program;
use solana_sdk::{
signature::{Keypair, Signer},
system_transaction,
};
use tokio::prelude::{Async, Stream};
use std::{fmt::Debug, sync::mpsc::channel, time::Instant};
use tokio::{prelude::FutureExt, runtime::Runtime, timer::Delay};
pub(crate) fn robust_poll<T>(
mut receiver: futures::sync::mpsc::Receiver<T>,
) -> Result<T, RecvTimeoutError> {
const INITIAL_DELAY_MS: u64 = RECEIVE_DELAY_MILLIS * 2;
pub(crate) fn robust_poll_or_panic<T: Debug + Send + 'static>(
receiver: futures::sync::mpsc::Receiver<T>,
) -> (T, futures::sync::mpsc::Receiver<T>) {
let (inner_sender, inner_receiver) = channel();
let mut rt = Runtime::new().unwrap();
rt.spawn(futures::lazy(|| {
let recv_timeout = receiver
.into_future()
.timeout(Duration::from_millis(RECEIVE_DELAY_MILLIS))
.map(move |result| match result {
(Some(value), receiver) => {
inner_sender.send((value, receiver)).expect("send error")
}
(None, _) => panic!("unexpected end of stream"),
})
.map_err(|err| panic!("stream error {:?}", err));
std::thread::sleep(Duration::from_millis(INITIAL_DELAY_MS));
for _i in 0..5 {
let found = receiver.poll();
if let Ok(Async::Ready(Some(result))) = found {
return Ok(result);
}
std::thread::sleep(Duration::from_millis(RECEIVE_DELAY_MILLIS));
}
Err(RecvTimeoutError::Timeout)
}
pub(crate) fn robust_poll_or_panic<T>(receiver: futures::sync::mpsc::Receiver<T>) -> T {
robust_poll(receiver).unwrap_or_else(|err| panic!("expected response! {}", err))
const INITIAL_DELAY_MS: u64 = RECEIVE_DELAY_MILLIS * 2;
Delay::new(Instant::now() + Duration::from_millis(INITIAL_DELAY_MS))
.and_then(|_| recv_timeout)
.map_err(|err| panic!("timer error {:?}", err))
}));
inner_receiver.recv().expect("recv error")
}
#[test]
@@ -600,10 +662,9 @@ pub(crate) mod tests {
let (subscriber, _id_receiver, transport_receiver) =
Subscriber::new_test("accountNotification");
let sub_id = SubscriptionId::Number(0 as u64);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
let exit = Arc::new(AtomicBool::new(false));
let subscriptions = RpcSubscriptions::new(&exit);
subscriptions.add_account_subscription(&alice.pubkey(), None, &sub_id, &sink);
subscriptions.add_account_subscription(alice.pubkey(), None, sub_id.clone(), subscriber);
assert!(subscriptions
.account_subscriptions
@@ -612,7 +673,7 @@ pub(crate) mod tests {
.contains_key(&alice.pubkey()));
subscriptions.notify_subscribers(0, &bank_forks);
let response = robust_poll_or_panic(transport_receiver);
let (response, _) = robust_poll_or_panic(transport_receiver);
let expected = json!({
"jsonrpc": "2.0",
"method": "accountNotification",
@@ -670,10 +731,14 @@ pub(crate) mod tests {
let (subscriber, _id_receiver, transport_receiver) =
Subscriber::new_test("programNotification");
let sub_id = SubscriptionId::Number(0 as u64);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
let exit = Arc::new(AtomicBool::new(false));
let subscriptions = RpcSubscriptions::new(&exit);
subscriptions.add_program_subscription(&solana_budget_program::id(), None, &sub_id, &sink);
subscriptions.add_program_subscription(
solana_budget_program::id(),
None,
sub_id.clone(),
subscriber,
);
assert!(subscriptions
.program_subscriptions
@@ -682,7 +747,7 @@ pub(crate) mod tests {
.contains_key(&solana_budget_program::id()));
subscriptions.notify_subscribers(0, &bank_forks);
let response = robust_poll_or_panic(transport_receiver);
let (response, _) = robust_poll_or_panic(transport_receiver);
let expected = json!({
"jsonrpc": "2.0",
"method": "programNotification",
@@ -750,40 +815,62 @@ pub(crate) mod tests {
let bank_forks = Arc::new(RwLock::new(bank_forks));
let (subscriber, _id_receiver, transport_receiver) =
Subscriber::new_test("signatureNotification");
let sink = subscriber.assign_id(SubscriptionId::Number(0)).unwrap();
let exit = Arc::new(AtomicBool::new(false));
let subscriptions = RpcSubscriptions::new(&exit);
let (past_bank_sub, _id_receiver, past_bank_recv) =
Subscriber::new_test("signatureNotification");
let (processed_sub, _id_receiver, processed_recv) =
Subscriber::new_test("signatureNotification");
subscriptions.add_signature_subscription(
&past_bank_tx.signatures[0],
past_bank_tx.signatures[0],
Some(0),
&SubscriptionId::Number(1 as u64),
&sink.clone(),
SubscriptionId::Number(1 as u64),
Subscriber::new_test("signatureNotification").0,
);
subscriptions.add_signature_subscription(
&processed_tx.signatures[0],
Some(0),
&SubscriptionId::Number(2 as u64),
&sink.clone(),
past_bank_tx.signatures[0],
Some(1),
SubscriptionId::Number(2 as u64),
past_bank_sub,
);
subscriptions.add_signature_subscription(
&unprocessed_tx.signatures[0],
processed_tx.signatures[0],
Some(0),
&SubscriptionId::Number(3 as u64),
&sink.clone(),
SubscriptionId::Number(3 as u64),
processed_sub,
);
subscriptions.add_signature_subscription(
unprocessed_tx.signatures[0],
Some(0),
SubscriptionId::Number(4 as u64),
Subscriber::new_test("signatureNotification").0,
);
{
let sig_subs = subscriptions.signature_subscriptions.read().unwrap();
assert!(sig_subs.contains_key(&past_bank_tx.signatures[0]));
assert_eq!(sig_subs.get(&past_bank_tx.signatures[0]).unwrap().len(), 2);
assert!(sig_subs.contains_key(&unprocessed_tx.signatures[0]));
assert!(sig_subs.contains_key(&processed_tx.signatures[0]));
}
subscriptions.notify_subscribers(1, &bank_forks);
let response = robust_poll_or_panic(transport_receiver);
let expected_res: Option<transaction::Result<()>> = Some(Ok(()));
let expected = json!({
"jsonrpc": "2.0",
"method": "signatureNotification",
"params": {
"result": {
"context": { "slot": 0 },
"value": expected_res,
},
"subscription": 2,
}
});
let (response, _) = robust_poll_or_panic(past_bank_recv);
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
let expected = json!({
"jsonrpc": "2.0",
"method": "signatureNotification",
@@ -792,9 +879,10 @@ pub(crate) mod tests {
"context": { "slot": 1 },
"value": expected_res,
},
"subscription": 0,
"subscription": 3,
}
});
let (response, _) = robust_poll_or_panic(processed_recv);
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
let sig_subs = subscriptions.signature_subscriptions.read().unwrap();
@@ -810,34 +898,6 @@ pub(crate) mod tests {
sig_subs.get(&unprocessed_tx.signatures[0]).unwrap().len(),
1
);
let (subscriber, _id_receiver, transport_receiver) =
Subscriber::new_test("signatureNotification");
let sink = subscriber.assign_id(SubscriptionId::Number(0)).unwrap();
let exit = Arc::new(AtomicBool::new(false));
let subscriptions = RpcSubscriptions::new(&exit);
subscriptions.add_signature_subscription(
&past_bank_tx.signatures[0],
Some(1),
&SubscriptionId::Number(1 as u64),
&sink.clone(),
);
subscriptions.notify_subscribers(1, &bank_forks);
let response = robust_poll_or_panic(transport_receiver);
let expected_res: Option<transaction::Result<()>> = Some(Ok(()));
let expected = json!({
"jsonrpc": "2.0",
"method": "signatureNotification",
"params": {
"result": {
"context": { "slot": 0 },
"value": expected_res,
},
"subscription": 0,
}
});
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
}
#[test]
@@ -845,10 +905,9 @@ pub(crate) mod tests {
let (subscriber, _id_receiver, transport_receiver) =
Subscriber::new_test("slotNotification");
let sub_id = SubscriptionId::Number(0 as u64);
let sink = subscriber.assign_id(sub_id.clone()).unwrap();
let exit = Arc::new(AtomicBool::new(false));
let subscriptions = RpcSubscriptions::new(&exit);
subscriptions.add_slot_subscription(&sub_id, &sink);
subscriptions.add_slot_subscription(sub_id.clone(), subscriber);
assert!(subscriptions
.slot_subscriptions
@@ -857,7 +916,7 @@ pub(crate) mod tests {
.contains_key(&sub_id));
subscriptions.notify_slot(0, 0, 0);
let response = robust_poll_or_panic(transport_receiver);
let (response, _) = robust_poll_or_panic(transport_receiver);
let expected_res = SlotInfo {
parent: 0,
slot: 0,
@@ -879,29 +938,68 @@ pub(crate) mod tests {
.contains_key(&sub_id));
}
#[test]
fn test_check_root_subscribe() {
let (subscriber, _id_receiver, mut transport_receiver) =
Subscriber::new_test("rootNotification");
let sub_id = SubscriptionId::Number(0 as u64);
let exit = Arc::new(AtomicBool::new(false));
let subscriptions = RpcSubscriptions::new(&exit);
subscriptions.add_root_subscription(sub_id.clone(), subscriber);
assert!(subscriptions
.root_subscriptions
.read()
.unwrap()
.contains_key(&sub_id));
subscriptions.notify_roots(vec![2, 1, 3]);
for expected_root in 1..=3 {
let (response, receiver) = robust_poll_or_panic(transport_receiver);
transport_receiver = receiver;
let expected_res_str =
serde_json::to_string(&serde_json::to_value(expected_root).unwrap()).unwrap();
let expected = format!(
r#"{{"jsonrpc":"2.0","method":"rootNotification","params":{{"result":{},"subscription":0}}}}"#,
expected_res_str
);
assert_eq!(expected, response);
}
subscriptions.remove_root_subscription(&sub_id);
assert!(!subscriptions
.root_subscriptions
.read()
.unwrap()
.contains_key(&sub_id));
}
#[test]
fn test_add_and_remove_subscription() {
let (subscriber, _id_receiver, _transport_receiver) = Subscriber::new_test("notification");
let sink = subscriber
.assign_id(SubscriptionId::String("test".to_string()))
.unwrap();
let mut subscriptions: HashMap<u64, HashMap<SubscriptionId, (Sink<()>, Confirmations)>> =
HashMap::new();
let num_keys = 5;
let mut next_id: u64 = 0;
for _ in 0..num_keys {
let key = next_id;
let sub_id = SubscriptionId::Number(next_id);
add_subscription(&mut subscriptions, &key, None, &sub_id, &sink.clone());
next_id += 1;
for key in 0..num_keys {
let (subscriber, _id_receiver, _transport_receiver) =
Subscriber::new_test("notification");
let sub_id = SubscriptionId::Number(key);
add_subscription(&mut subscriptions, key, None, sub_id, subscriber);
}
// Add another subscription to the "0" key
let sub_id = SubscriptionId::Number(next_id);
add_subscription(&mut subscriptions, &0, None, &sub_id, &sink.clone());
let (subscriber, _id_receiver, _transport_receiver) = Subscriber::new_test("notification");
let extra_sub_id = SubscriptionId::Number(num_keys);
add_subscription(
&mut subscriptions,
0,
None,
extra_sub_id.clone(),
subscriber,
);
assert_eq!(subscriptions.len(), num_keys);
assert_eq!(subscriptions.len(), num_keys as usize);
assert_eq!(subscriptions.get(&0).unwrap().len(), 2);
assert_eq!(subscriptions.get(&1).unwrap().len(), 1);
@@ -909,18 +1007,15 @@ pub(crate) mod tests {
remove_subscription(&mut subscriptions, &SubscriptionId::Number(0)),
true
);
assert_eq!(subscriptions.len(), num_keys);
assert_eq!(subscriptions.len(), num_keys as usize);
assert_eq!(subscriptions.get(&0).unwrap().len(), 1);
assert_eq!(
remove_subscription(&mut subscriptions, &SubscriptionId::Number(0)),
false
);
assert_eq!(
remove_subscription(&mut subscriptions, &SubscriptionId::Number(next_id)),
true
);
assert_eq!(subscriptions.len(), num_keys - 1);
assert_eq!(remove_subscription(&mut subscriptions, &extra_sub_id), true);
assert_eq!(subscriptions.len(), (num_keys - 1) as usize);
assert!(subscriptions.get(&0).is_none());
}
}

View File

@@ -1,10 +1,10 @@
use crossbeam_channel::{Receiver, RecvTimeoutError};
use solana_client::rpc_response::RpcTransactionStatusMeta;
use solana_ledger::{blockstore::Blockstore, blockstore_processor::TransactionStatusBatch};
use solana_runtime::{
bank::{Bank, HashAgeKind},
nonce_utils,
};
use solana_transaction_status::TransactionStatusMeta;
use std::{
sync::{
atomic::{AtomicBool, Ordering},
@@ -73,7 +73,7 @@ impl TransactionStatusService {
blockstore
.write_transaction_status(
(slot, transaction.signatures[0]),
&RpcTransactionStatusMeta {
&TransactionStatusMeta {
status,
fee,
pre_balances,

View File

@@ -212,7 +212,7 @@ fn test_rpc_subscriptions() {
// Create transaction signatures to subscribe to
let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
let transactions: Vec<Transaction> = (0..500)
let transactions: Vec<Transaction> = (0..100)
.map(|_| system_transaction::transfer(&alice, &Pubkey::new_rand(), 1, genesis_hash))
.collect();
let mut signature_set: HashSet<String> = transactions
@@ -271,7 +271,7 @@ fn test_rpc_subscriptions() {
});
let rpc_client = RpcClient::new_socket(leader_data.rpc);
let transaction_count = rpc_client
let mut transaction_count = rpc_client
.get_transaction_count_with_commitment(CommitmentConfig::recent())
.unwrap();
@@ -281,10 +281,10 @@ fn test_rpc_subscriptions() {
.send_to(&bincode::serialize(&tx).unwrap(), leader_data.tpu)
.unwrap();
});
let mut x = 0;
let now = Instant::now();
while x < transaction_count + 500 || now.elapsed() > Duration::from_secs(5) {
x = rpc_client
let expected_transaction_count = transaction_count + transactions.len() as u64;
while transaction_count < expected_transaction_count && now.elapsed() < Duration::from_secs(5) {
transaction_count = rpc_client
.get_transaction_count_with_commitment(CommitmentConfig::recent())
.unwrap();
sleep(Duration::from_millis(200));

View File

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

View File

@@ -1,13 +1,17 @@
# Table of contents
* [Introduction](introduction.md)
* [Install the Solana Tool Suite](install-solana.md)
* [Command-line Guide](cli/README.md)
* [Choose a Wallet](cli/choose-a-wallet.md)
* [Hardware Wallets](remote-wallet/README.md)
* [Ledger Hardware Wallet](remote-wallet/ledger.md)
* [Paper Wallet](paper-wallet/README.md)
* [Paper Wallet Usage](paper-wallet/usage.md)
* [Wallet Guide](wallet/README.md)
* [App Wallets](wallet/app-wallets.md)
* [Trust Wallet](wallet/trust-wallet.md)
* [Ledger Live](wallet/ledger-live.md)
* [Command-line Wallets](wallet/cli-wallets.md)
* [Hardware Wallets](remote-wallet/README.md)
* [Ledger Hardware Wallet](remote-wallet/ledger.md)
* [Paper Wallet](paper-wallet/README.md)
* [Paper Wallet Usage](paper-wallet/paper-wallet-usage.md)
* [Command Line Guide](cli/README.md)
* [Install the Solana Command Line Tool Suite](cli/install-solana-cli-tools.md)
* [Generate Keys](cli/generate-keys.md)
* [Send and Receive Tokens](cli/transfer-tokens.md)
* [Delegate Stake](cli/delegate-stake.md)

View File

@@ -31,10 +31,8 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
* [getInflation](jsonrpc-api.md#getinflation)
* [getLeaderSchedule](jsonrpc-api.md#getleaderschedule)
* [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption)
* [getNumBlocksSinceSignatureConfirmation](jsonrpc-api.md#getnumblockssincesignatureconfirmation)
* [getProgramAccounts](jsonrpc-api.md#getprogramaccounts)
* [getRecentBlockhash](jsonrpc-api.md#getrecentblockhash)
* [getSignatureConfirmation](jsonrpc-api.md#getsignatureconfirmation)
* [getSignatureStatus](jsonrpc-api.md#getsignaturestatus)
* [getSlot](jsonrpc-api.md#getslot)
* [getSlotLeader](jsonrpc-api.md#getslotleader)
@@ -298,11 +296,11 @@ The result field will be an object with the following fields:
* `previousBlockhash: <string>` - the blockhash of this block's parent, as base-58 encoded string
* `parentSlot: <u64>` - the slot index of this block's parent
* `transactions: <array>` - an array of JSON objects containing:
* `transaction: <object|string>` - [Transaction](transaction-api.md) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
* `transaction: <object|string>` - [Transaction](#transaction-structure) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
* `meta: <object>` - transaction status metadata object, containing `null` or:
* `status: <object>` - Transaction status:
* `"Ok": null` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L18)
* `fee: <u64>` - fee this transaction was charged, as u64 integer
* `preBalances: <array>` - array of u64 account balances from before the transaction was processed
* `postBalances: <array>` - array of u64 account balances after the transaction was processed
@@ -326,6 +324,25 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m
{"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":"81UZJt4dh4Do66jDhrgkQudS8J2N6iG3jaVav7gJrqJSFY4Ug53iA9JFJZh2gxKWcaFdLJwhHx9mRdg9JwDAWB4ywiu5154CRwXV4FMdnPLg7bhxRLwhhYaLsVgMF5AyNRcTzjCVoBvqFgDU7P8VEKDEiMvD3qxzm1pLZVxDG1LTQpT3Dz4Uviv4KQbFQNuC22KupBoyHFB7Zh6KFdMqux4M9PvhoqcoJsJKwXjWpKu7xmEKnnrSbfLadkgjBmmjhW3fdTrFvnhQdTkhtdJxUL1xS9GMuJQer8YgSKNtUXB1eXZQwXU8bU2BjYkZE6Q5Xww8hu9Z4E4Mo4QsooVtHoP6BM3NKw8zjVbWfoCQqxTrwuSzrNCWCWt58C24LHecH67CTt2uXbYSviixvrYkK7A3t68BxTJcF1dXJitEPTFe2ceTkauLJqrJgnER4iUrsjr26T8YgWvpY9wkkWFSviQW6wV5RASTCUasVEcrDiaKj8EQMkgyDoe9HyKitSVg67vMWJFpUXpQobseWJUs5FTWWzmfHmFp8FZ","meta":{"fee":1000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1}
```
#### Transaction Structure
Transactions are quite different from those on other blockchains. Be sure to review [Anatomy of a Transaction](transaction.md) to learn about transactions on Solana.
The JSON structure of a transaction is defined as follows:
* `signatures: <array[string]>` - A list of base-58 encoded signatures applied to the transaction. The list is always of length `message.header.numRequiredSignatures`, and the signature at index `i` corresponds to the public key at index `i` in `message.account_keys`.
* `message: <object>` - Defines the content of the transaction.
* `accountKeys: <array[string]>` - List of base-58 encoded public keys used by the transaction, including by the instructions and for signatures. The first `message.header.numRequiredSignatures` public keys must sign the transaction.
* `header: <object>` - Details the account types and signatures required by the transaction.
* `numRequiredSignatures: <number>` - The total number of signatures required to make the transaction valid. The signatures must match the first `numRequiredSignatures` of `message.account_keys`.
* `numReadonlySignedAccounts: <number>` - The last `numReadonlySignedAccounts` of the signed keys are read-only accounts. Programs may process multiple transactions that load read-only accounts within a single PoH entry, but are not permitted to credit or debit lamports or modify account data. Transactions targeting the same read-write account are evaluated sequentially.
* `numReadonlyUnsignedAccounts: <number>` - The last `numReadonlyUnsignedAccounts` of the unsigned keys are read-only accounts.
* `recentBlockhash: <string>` - A base-58 encoded hash of a recent block in the ledger used to prevent transaction duplication and to give transactions lifetimes.
* `instructions: <array[object]>` - List of program instructions that will be executed in sequence and committed in one atomic transaction if all succeed.
* `programIdIndex: <number>` - Index into the `message.accountKeys` array indicating the program account that executes this instruction.
* `accounts: <array[number]>` - List of ordered indices into the `message.accountKeys` array indicating which accounts to pass to the program.
* `data: <string>` - The program input data encoded in a base-58 string.
### getConfirmedBlocks
Returns a list of confirmed blocks
@@ -580,29 +597,6 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
{"jsonrpc":"2.0","result":500,"id":1}
```
### getNumBlocksSinceSignatureConfirmation
Returns the current number of blocks since signature has been confirmed.
#### Parameters:
* `<string>` - Signature of Transaction to confirm, as base-58 encoded string
* `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
#### Results:
* `<u64>` - count, or null if signature not found
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getNumBlocksSinceSignatureConfirmation", "params":["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":8,"id":1}
```
### getProgramAccounts
Returns all accounts owned by the provided program Pubkey
@@ -660,33 +654,6 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"blockhash":"CSymwgTNX1j3E4qhKfJAUE41nBWEwXufoYryPbkde5RR","feeCalculator":{"burnPercent":50,"lamportsPerSignature":5000,"maxLamportsPerSignature":10000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":1000,"targetSignaturesPerSlot":20000}}},"id":1}
```
### getSignatureConfirmation
Returns the status and number of confirmations of a given signature.
#### Parameters:
* `<string>` - Signature of Transaction to confirm, as base-58 encoded string
* `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
#### Results:
* `<null>` - Unknown transaction
* `<object>` - Transaction confirmations and status:
* `confirmations: <u64>` - count of confirmations since transaction was processed
* `status: <object>` -
* `"Ok": <null>` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureConfirmation", "params":["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"confirmations":12,"status":{"Ok": null}},"id":1}
```
### getSignatureStatus
Returns the status of a given signature. This method is similar to [confirmTransaction](jsonrpc-api.md#confirmtransaction) but provides more resolution for error events.
@@ -700,11 +667,16 @@ Returns the status of a given signature. This method is similar to [confirmTrans
#### Results:
An RpcResponse containing a JSON object consisting of an array of TransactionStatus objects.
* `RpcResponse<object>` - RpcResponse JSON object with `value` field:
An array of:
* `<null>` - Unknown transaction
* `<object>`
* `slot: <u64>` - The slot the transaction was processed
* `confirmations: <usize | null>` - Number of blocks since signature confirmation, null if rooted
* `status: <object>` - Transaction status
* `"Ok": <null>` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
@@ -716,7 +688,10 @@ An array of:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureStatus", "params":[["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW", "5j7s6NiJS3JAkvgkoc18WVAsiSaci2pxB2A6ueCJP4tprA2TFg9wSyTLeYouxPBJEMzJinENTkpA52YStRW5Dia7"]]]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":[{"slot": 72, "status": {"Ok": null}}, null],"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":82},"value":[{"slot": 72, "confirmations": 10, "status": {"Ok": null}}, null]},"id":1}
// Result, first transaction rooted
{"jsonrpc":"2.0","result":{"context":{"slot":82},"value":[{"slot": 48, "confirmations": null, "status": {"Ok": null}}, null]},"id":1}
```
### getSlot
@@ -914,7 +889,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.0.9"},"id":1}
{"jsonrpc":"2.0","result":{"solana-core": "1.0.12"},"id":1}
```
### getVoteAccounts
@@ -935,7 +910,7 @@ The result field will be a JSON object of `current` and `delinquent` accounts, e
* `epochVoteAccount: <bool>` - bool, whether the vote account is staked for this epoch
* `commission: <number>`, percentage (0-100) of rewards payout owed to the vote account
* `lastVote: <u64>` - Most recent slot voted on by this vote account
* `epochCredits: <array>` - History of how many credits earned by the end of each epoch, as an array of arrays containing: [epoch, credits, previousCredits]
* `epochCredits: <array>` - History of how many credits earned by the end of each epoch, as an array of arrays containing: `[epoch, credits, previousCredits]`
#### Example:
@@ -1280,7 +1255,7 @@ None
### slotUnsubscribe
Unsubscribe from signature confirmation notification
Unsubscribe from slot notifications
#### Parameters:
@@ -1299,3 +1274,55 @@ Unsubscribe from signature confirmation notification
// Result
{"jsonrpc": "2.0","result": true,"id": 1}
```
### rootSubscribe
Subscribe to receive notification anytime a new root is set by the validator.
#### Parameters:
None
#### Results:
* `integer` - subscription id \(needed to unsubscribe\)
#### Example:
```bash
// Request
{"jsonrpc":"2.0", "id":1, "method":"rootSubscribe"}
// Result
{"jsonrpc": "2.0","result": 0,"id": 1}
```
#### Notification Format:
The result is the latest root slot number.
```bash
{"jsonrpc": "2.0","method": "rootNotification", "params": {"result":42,"subscription":0}}
```
### rootUnsubscribe
Unsubscribe from root notifications
#### Parameters:
* `<integer>` - subscription id to cancel
#### Results:
* `<bool>` - unsubscribe success message
#### Example:
```bash
// Request
{"jsonrpc":"2.0", "id":1, "method":"rootUnsubscribe", "params":[0]}
// Result
{"jsonrpc": "2.0","result": true,"id": 1}
```

View File

@@ -1,7 +1,9 @@
# Command-line Guide
In this section, we will describe how to create a Solana *wallet*, how to send
and receive tokens, and how to participate in the cluster by delegating stake.
In this section, we will describe how to use the Solana command-line tools to
create a *wallet*, to send and receive SOL tokens, and to participate in
the cluster by delegating stake.
To interact with a Solana cluster, we will use its command-line interface, also
known as the CLI. We use the command-line because it is the first place the
Solana core team deploys new functionality. The command-line interface is not

View File

@@ -4,8 +4,8 @@ In this section, we will generate a keypair, query it for its public key,
and verify you control its private key. Before you begin, you will need
to:
* [Install the Solana Tool Suite](../install-solana.md)
* [Choose a wallet](choose-a-wallet.md)
* [Install the Solana Tool Suite](install-solana-cli-tools.md)
* [Choose a Command-line wallet](../wallet/cli-wallets.md)
## Generate an FS Wallet Keypair
@@ -52,7 +52,7 @@ the one in your keypair file, and "Failed" otherwise.
## Generate a Paper Wallet Seed Phrase
See [Creating a Paper Wallet](../paper-wallet/usage.md#creating-a-paper-wallet).
See [Creating a Paper Wallet](../paper-wallet/paper-wallet-usage.md#creating-a-paper-wallet).
To verify you control the private key of that public key, use `solana-keygen verify`:
@@ -69,7 +69,7 @@ keypair generated from your seed phrase, and "Failed" otherwise.
## Generate a Hardware Wallet Keypair
Keypairs are automatically derived when you query a hardware wallet with a
[keypair URL](../remote-wallet#specify-a-hardware-wallet-key).
[keypair URL](../remote-wallet/README.md#specify-a-hardware-wallet-key).
Once you have your keypair URL, use `solana-keygen pubkey` to query the hardware
wallet for the keypair's public key:

View File

@@ -6,7 +6,7 @@ To receive tokens, you will need an address for others to send tokens to. In
Solana, an address is the public key of a keypair. There are a variety
of techniques for generating keypairs. The method you choose will depend on how
you choose to store keypairs. Keypairs are stored in wallets. Before receiving
tokens, you will need to [choose a wallet](choose-a-wallet.md) and
tokens, you will need to [choose a wallet](../wallet/cli-wallets.md) and
[generate keys](generate-keys.md). Once completed, you should have a public key
for each keypair you generated. The public key is a long string of base58
characters. Its length varies from 32 to 44 characters.

View File

@@ -171,7 +171,7 @@ $ solana send-timestamp <PUBKEY> <PROCESS_ID> --date 2018-12-24T23:59:00
## Usage
### solana-cli
```text
solana-cli 1.0.9 [channel=unknown commit=unknown]
solana-cli 1.0.12 [channel=unknown commit=unknown]
Blockchain, Rebuilt for Scale
USAGE:

View File

@@ -10,7 +10,7 @@ These protocol-based rewards, to be distributed to participating validation and
Transaction fees are market-based participant-to-participant transfers, attached to network interactions as a necessary motivation and compensation for the inclusion and execution of a proposed transaction \(be it a state execution or proof-of-replication verification\). A mechanism for long-term economic stability and forking protection through partial burning of each transaction fee is also discussed below.
A high-level schematic of Solanas crypto-economic design is shown below in **Figure 1**. The specifics of validation-client economics are described in sections: [Validation-client Economics](ed_validation_client_economics/), [State-validation Protocol-based Rewards](ed_validation_client_economics/ed_vce_state_validation_protocol_based_rewards.md), [State-validation Transaction Fees](ed_validation_client_economics/ed_vce_state_validation_transaction_fees.md) and [Replication-validation Transaction Fees](ed_validation_client_economics/ed_vce_replication_validation_transaction_fees.md). Also, the section titled [Validation Stake Delegation](ed_validation_client_economics/ed_vce_validation_stake_delegation.md) closes with a discussion of validator delegation opportunities and marketplace. Additionally, in [Storage Rent Economics](ed_storage_rent_economics.md), we describe an implementation of storage rent to account for the externality costs of maintaining the active state of the ledger. [Replication-client Economics](ed_replication_client_economics/) will review the Solana network design for global ledger storage/redundancy and archiver-client economics \([Storage-replication rewards](ed_replication_client_economics/ed_rce_storage_replication_rewards.md)\) along with an archiver-to-validator delegation mechanism designed to aide participant on-boarding into the Solana economy discussed in [Replication-client Reward Auto-delegation](ed_replication_client_economics/ed_rce_replication_client_reward_auto_delegation.md). An outline of features for an MVP economic design is discussed in the [Economic Design MVP](ed_mvp.md) section. Finally, in [Attack Vectors](ed_attack_vectors.md), various attack vectors will be described and potential vulnerabilities explored and parameterized.
A high-level schematic of Solanas crypto-economic design is shown below in **Figure 1**. The specifics of validation-client economics are described in sections: [Validation-client Economics](ed_validation_client_economics/README.md), [State-validation Protocol-based Rewards](ed_validation_client_economics/ed_vce_state_validation_protocol_based_rewards.md), [State-validation Transaction Fees](ed_validation_client_economics/ed_vce_state_validation_transaction_fees.md) and [Replication-validation Transaction Fees](ed_validation_client_economics/ed_vce_replication_validation_transaction_fees.md). Also, the section titled [Validation Stake Delegation](ed_validation_client_economics/ed_vce_validation_stake_delegation.md) closes with a discussion of validator delegation opportunities and marketplace. Additionally, in [Storage Rent Economics](ed_storage_rent_economics.md), we describe an implementation of storage rent to account for the externality costs of maintaining the active state of the ledger. [Replication-client Economics](ed_replication_client_economics/README.md) will review the Solana network design for global ledger storage/redundancy and archiver-client economics \([Storage-replication rewards](ed_replication_client_economics/ed_rce_storage_replication_rewards.md)\) along with an archiver-to-validator delegation mechanism designed to aide participant on-boarding into the Solana economy discussed in [Replication-client Reward Auto-delegation](ed_replication_client_economics/ed_rce_replication_client_reward_auto_delegation.md). An outline of features for an MVP economic design is discussed in the [Economic Design MVP](ed_mvp.md) section. Finally, in [Attack Vectors](ed_attack_vectors.md), various attack vectors will be described and potential vulnerabilities explored and parameterized.
![](../../.gitbook/assets/economic_design_infl_230719.png)

View File

@@ -2,7 +2,7 @@
**Subject to change.**
The preceding sections, outlined in the [Economic Design Overview](./), describe a long-term vision of a sustainable Solana economy. Of course, we don't expect the final implementation to perfectly match what has been described above. We intend to fully engage with network stakeholders throughout the implementation phases \(i.e. pre-testnet, testnet, mainnet\) to ensure the system supports, and is representative of, the various network participants' interests. The first step toward this goal, however, is outlining a some desired MVP economic features to be available for early pre-testnet and testnet participants. Below is a rough sketch outlining basic economic functionality from which a more complete and functional system can be developed.
The preceding sections, outlined in the [Economic Design Overview](../README.md), describe a long-term vision of a sustainable Solana economy. Of course, we don't expect the final implementation to perfectly match what has been described above. We intend to fully engage with network stakeholders throughout the implementation phases \(i.e. pre-testnet, testnet, mainnet\) to ensure the system supports, and is representative of, the various network participants' interests. The first step toward this goal, however, is outlining a some desired MVP economic features to be available for early pre-testnet and testnet participants. Below is a rough sketch outlining basic economic functionality from which a more complete and functional system can be developed.
## MVP Economic Features

View File

@@ -4,7 +4,7 @@
Validator-clients have two functional roles in the Solana network:
* Validate \(vote\) the current global state of that PoH along with any Proofs-of-Replication \(see [Replication Client Economics](../ed_replication_client_economics/)\) that they are eligible to validate.
* Validate \(vote\) the current global state of that PoH along with any Proofs-of-Replication \(see [Replication Client Economics](../ed_replication_client_economics/README.md)\) that they are eligible to validate.
* Be elected as leader on a stake-weighted round-robin schedule during which time they are responsible for collecting outstanding transactions and Proofs-of-Replication and incorporating them into the PoH, thus updating the global state of the network and providing chain continuity.
Validator-client rewards for these services are to be distributed at the end of each Solana epoch. As previously discussed, compensation for validator-clients is provided via a protocol-based annual inflation rate dispersed in proportion to the stake-weight of each validator \(see below\) along with leader-claimed transaction fees available during each leader rotation. I.e. during the time a given validator-client is elected as leader, it has the opportunity to keep a portion of each transaction fee, less a protocol-specified amount that is destroyed \(see [Validation-client State Transaction Fees](ed_vce_state_validation_transaction_fees.md)\). PoRep transaction fees are also collected by the leader client and validator PoRep rewards are distributed in proportion to the number of validated PoReps less the number of PoReps that mismatch an archiver's challenge. \(see [Replication-client Transaction Fees](ed_vce_replication_validation_transaction_fees.md)\)

View File

@@ -24,7 +24,7 @@ Running a Solana validation-client required relatively modest upfront hardware c
Despite the low-barrier to entry as a validation-client, from a capital investment perspective, as in any developing economy, there will be much opportunity and need for trusted validation services as evidenced by node reliability, UX/UI, APIs and other software accessibility tools. Additionally, although Solanas validator node startup costs are nominal when compared to similar networks, they may still be somewhat restrictive for some potential participants. In the spirit of developing a true decentralized, permissionless network, these interested parties still have two options to become involved in the Solana network/economy:
1. Delegation of previously acquired tokens with a reliable validation node to earn a portion of interest generated
2. Provide local storage space as a replication-client and receive rewards by submitting Proof-of-Replication \(see [Replication-client Economics](../ed_replication_client_economics/)\).
2. Provide local storage space as a replication-client and receive rewards by submitting Proof-of-Replication \(see [Replication-client Economics](../ed_replication_client_economics/README.md)\).
a. This participant has the additional option to directly delegate their earned storage rewards \([Replication-client Reward Auto-delegation](../ed_replication_client_economics/ed_rce_replication_client_reward_auto_delegation.md)\)

View File

@@ -20,7 +20,7 @@ Slot leaders and validators use a PoH Recorder for both estimating slot height a
### PoH Recorder when Validating
The PoH Recorder acts as a simple VDF when validating. It tells the validator when it needs to switch to the slot leader role. Every time the validator votes on a fork, it should use the fork's latest [blockhash](terminology.md#blockhash) to re-seed the VDF. Re-seeding solves two problems. First, it synchronizes its VDF to the leader's, allowing it to more accurately determine when its leader slot begins. Second, if the previous leader goes down, all wallclock time is accounted for in the next leader's PoH stream. For example, if one block is missing when the leader starts, the block it produces should have a PoH duration of two blocks. The longer duration ensures the following leader isn't attempting to snip all the transactions from the previous leader's slot.
The PoH Recorder acts as a simple VDF when validating. It tells the validator when it needs to switch to the slot leader role. Every time the validator votes on a fork, it should use the fork's latest [blockhash](../terminology.md#blockhash) to re-seed the VDF. Re-seeding solves two problems. First, it synchronizes its VDF to the leader's, allowing it to more accurately determine when its leader slot begins. Second, if the previous leader goes down, all wallclock time is accounted for in the next leader's PoH stream. For example, if one block is missing when the leader starts, the block it produces should have a PoH duration of two blocks. The longer duration ensures the following leader isn't attempting to snip all the transactions from the previous leader's slot.
### PoH Recorder when Leading

View File

@@ -50,7 +50,7 @@ Solana's trustless sense of time and ordering provided by its PoH data structure
## Penalties
As discussed in the [Economic Design](../implemented-proposals/ed_overview/) section, annual validator interest rates are to be specified as a function of total percentage of circulating supply that has been staked. The cluster rewards validators who are online and actively participating in the validation process throughout the entirety of their _validation period_. For validators that go offline/fail to validate transactions during this period, their annual reward is effectively reduced.
As discussed in the [Economic Design](../implemented-proposals/ed_overview/README.md) section, annual validator interest rates are to be specified as a function of total percentage of circulating supply that has been staked. The cluster rewards validators who are online and actively participating in the validation process throughout the entirety of their _validation period_. For validators that go offline/fail to validate transactions during this period, their annual reward is effectively reduced.
Similarly, we may consider an algorithmic reduction in a validator's active amount staked amount in the case that they are offline. I.e. if a validator is inactive for some amount of time, either due to a partition or otherwise, the amount of their stake that is considered active \(eligible to earn rewards\) may be reduced. This design would be structured to help long-lived partitions to eventually reach finality on their respective chains as the % of non-voting total stake is reduced over time until a supermajority can be achieved by the active validators in each partition. Similarly, upon re-engaging, the active amount staked will come back online at some defined rate. Different rates of stake reduction may be considered depending on the size of the partition/active set.

View File

@@ -4,7 +4,7 @@ Some security models require keeping signing keys, and thus the signing
process, separated from transaction creation and network broadcast. Examples
include:
* Collecting signatures from geographically disparate signers in a
[multi-signature scheme](../api-reference/cli.md#multiple-witnesses)
[multi-signature scheme](../cli/usage.md#multiple-witnesses)
* Signing transactions using an [airgapped](https://en.wikipedia.org/wiki/Air_gap_(networking))
signing device

View File

@@ -8,7 +8,7 @@ about in the [proposal](../implemented-proposals/durable-tx-nonces.md).
## Usage Examples
Full usage details for durable nonce CLI commands can be found in the
[CLI reference](../api-reference/cli.md).
[CLI reference](../cli/usage.md).
### Nonce Authority
@@ -47,12 +47,12 @@ solana create-nonce-account nonce-keypair.json 1
{% hint style="info" %}
To keep the keypair entirely offline, use the [Paper Wallet](../paper-wallet/README.md)
keypair generation [instructions](../paper-wallet/usage.md#seed-phrase-generation.md)
keypair generation [instructions](../paper-wallet/paper-wallet-usage.md#seed-phrase-generation.md)
instead
{% endhint %}
{% hint style="info" %}
[Full usage documentation](../api-reference/cli.md#solana-create-nonce-account)
[Full usage documentation](../cli/usage.md#solana-create-nonce-account)
{% endhint %}
### Querying the Stored Nonce Value
@@ -74,7 +74,7 @@ solana nonce nonce-keypair.json
```
{% hint style="info" %}
[Full usage documentation](../api-reference/cli.md#solana-get-nonce)
[Full usage documentation](../cli/usage.md#solana-get-nonce)
{% endhint %}
### Advancing the Stored Nonce Value
@@ -95,7 +95,7 @@ solana new-nonce nonce-keypair.json
```
{% hint style="info" %}
[Full usage documentation](../api-reference/cli.md#solana-new-nonce)
[Full usage documentation](../cli/usage.md#solana-new-nonce)
{% endhint %}
### Display Nonce Account
@@ -117,7 +117,7 @@ nonce: DZar6t2EaCFQTbUP4DHKwZ1wT8gCPW2aRfkVWhydkBvS
```
{% hint style="info" %}
[Full usage documentation](../api-reference/cli.md#solana-nonce-account)
[Full usage documentation](../cli/usage.md#solana-nonce-account)
{% endhint %}
### Withdraw Funds from a Nonce Account
@@ -141,7 +141,7 @@ Close a nonce account by withdrawing the full balance
{% endhint %}
{% hint style="info" %}
[Full usage documentation](../api-reference/cli.md#solana-withdraw-from-nonce-account)
[Full usage documentation](../cli/usage.md#solana-withdraw-from-nonce-account)
{% endhint %}
### Assign a New Authority to a Nonce Account
@@ -161,7 +161,7 @@ solana authorize-nonce-account nonce-keypair.json nonce-authority.json
```
{% hint style="info" %}
[Full usage documentation](../api-reference/cli.md#solana-authorize-nonce-account)
[Full usage documentation](../cli/usage.md#solana-authorize-nonce-account)
{% endhint %}
## Other Commands Supporting Durable Nonces
@@ -172,9 +172,9 @@ supported.
* `--nonce-authority`, specifies an optional [nonce authority](#nonce-authority)
The following subcommands have received this treatment so far
* [`pay`](../api-reference/cli.md#solana-pay)
* [`delegate-stake`](../api-reference/cli.md#solana-delegate-stake)
* [`deactivate-stake`](../api-reference/cli.md#solana-deactivate-stake)
* [`pay`](../cli/usage.md#solana-pay)
* [`delegate-stake`](../cli/usage.md#solana-delegate-stake)
* [`deactivate-stake`](../cli/usage.md#solana-deactivate-stake)
### Example Pay Using Durable Nonce

View File

@@ -12,7 +12,7 @@ protect against this scenario.
## Before You Begin
- [Install the Solana command-line tools](../install-solana.md)
- [Install the Solana command-line tools](../cli/install-solana-cli-tools.md)
### Check your installation

View File

@@ -80,8 +80,8 @@ hard forks should be approached.
We use some degree of macro machinery to automatically generate unit tests
and calculate a digest from ABI items. This is doable by clever use of
`serde::Serialize` ([1]) and `any::typename` ([2]). For a precedent for similar
implementation, `ink` from the Parity Technologies [3] could be informational.
`serde::Serialize` (`[1]`) and `any::typename` (`[2]`). For a precedent for similar
implementation, `ink` from the Parity Technologies `[3]` could be informational.
# References

View File

@@ -16,7 +16,7 @@ hardware wallet.
## Supported Hardware Wallets
The Solana CLI supports the following hardware wallets:
- [Ledger Nano S](ledger.md)
- [Ledger Nano S](ledger.md)
## Specify a Hardware Wallet Key

View File

@@ -6,7 +6,7 @@ secure transaction signing.
## Before You Begin
- [Install the Solana command-line tools](../install-solana.md)
- [Install the Solana command-line tools](../cli/install-solana-cli-tools.md)
- [Initialize your Ledger Nano S](https://support.ledger.com/hc/en-us/articles/360000613793)
- [Install the latest device firmware](https://support.ledgerwallet.com/hc/en-us/articles/360002731113-Update-Ledger-Nano-S-firmware)
@@ -92,8 +92,8 @@ Confirm it prints the same wallet ID as before.
To learn more about keypair URLs, see
[Specify A Hardware Wallet Key](README.md#specify-a-hardware-wallet-key)
Read more about [sending and receiving tokens](../transfer-tokens.md) and
[delegating stake](../delegate-stake.md). You can use your Ledger keypair URL
Read more about [sending and receiving tokens](../cli/transfer-tokens.md) and
[delegating stake](../cli/delegate-stake.md). You can use your Ledger keypair URL
anywhere you see an option or argument that accepts a `<KEYPAIR>`.
## Support

View File

@@ -33,7 +33,7 @@ Here are our recommendations for low, medium, and high end machine specification
## Software
* We build and run on Ubuntu 18.04. Some users have had trouble when running on Ubuntu 16.04
* See [Installing Solana](../install-solana.md) for the current Solana software release.
* See [Installing Solana](../cli/install-solana-cli-tools.md) for the current Solana software release.
Be sure to ensure that the machine used is not behind a residential NAT to avoid
NAT traversal issues. A cloud-hosted machine works best. **Ensure that IP ports 8000 through 10000 are not blocked for Internet inbound and outbound traffic.**

View File

@@ -69,7 +69,7 @@ account.
This is a normal transaction so the standard transaction fee will apply. The
transaction fee range is defined by the genesis block. The actual fee will
fluctuate based on transaction load. You can determine the current fee via the
[RPC API “getRecentBlockhash”](../api-reference/jsonrpc-api.md#getrecentblockhash)
[RPC API “getRecentBlockhash”](../apps/jsonrpc-api.md#getrecentblockhash)
before submitting a transaction.
Learn more about [transaction fees here](../implemented-proposals/transaction-fees.md).

View File

@@ -52,7 +52,7 @@ A gossip network connecting all [nodes](terminology.md#node) of a [cluster](term
## cooldown period
Some number of epochs after stake has been deactivated while it progressively becomes available for withdrawal. During this period, the stake is considered to be "deactivating". More info about: [warmup and cooldown](cluster/stake-delegation-and-rewards.md#stake-warmup-cooldown-withdrawal)
Some number of epochs after stake has been deactivated while it progressively becomes available for withdrawal. During this period, the stake is considered to be "deactivating". More info about: [warmup and cooldown](implemented-proposals/staking-rewards.md#stake-warmup-cooldown-withdrawal)
## credit
@@ -178,7 +178,7 @@ See [Proof of History](terminology.md#proof-of-history).
## point
A weighted [credit](terminology.md#credit) in a rewards regime. In the validator [rewards regime](proposals/staking-rewards.md), the number of points owed to a stake during redemption is the product of the [vote credits](terminology.md#vote-credit) earned and the number of lamports staked.
A weighted [credit](terminology.md#credit) in a rewards regime. In the validator [rewards regime](cluster/stake-delegation-and-rewards.md), the number of points owed to a stake during redemption is the product of the [vote credits](terminology.md#vote-credit) earned and the number of lamports staked.
## private key

View File

@@ -2,7 +2,7 @@
In order to participate in any Tour de SOL dry-runs or stages, you need to register for the Tour de SOL.
See [Registration info](../../registration/).
See [Registration info](../../registration/README.md).
In order to obtain your allotment of lamports at the start of a Tour de SOL stage or dry run, you need to publish your validator's identity public key under your keybase.io account.

View File

@@ -1,6 +1,6 @@
# Blockstore
After a block reaches finality, all blocks from that one on down to the genesis block form a linear chain with the familiar name blockchain. Until that point, however, the validator must maintain all potentially valid chains, called _forks_. The process by which forks naturally form as a result of leader rotation is described in [fork generation](../../cluster/fork-generation.md). The _blockstore_ data structure described here is how a validator copes with those forks until blocks are finalized.
After a block reaches finality, all blocks from that one on down to the genesis block form a linear chain with the familiar name blockchain. Until that point, however, the validator must maintain all potentially valid chains, called _forks_. The process by which forks naturally form as a result of leader rotation is described in [fork generation](../cluster/fork-generation.md). The _blockstore_ data structure described here is how a validator copes with those forks until blocks are finalized.
The blockstore allows a validator to record every shred it observes on the network, in any order, as long as the shred is signed by the expected leader for a given slot.

View File

@@ -64,4 +64,4 @@ To pass messages between programs, the receiving program must accept the message
## Future Work
* [Continuations and Signals for long running Transactions]([https://github.com/solana-labs/solana/issues/1485])
* [Continuations and Signals for long running Transactions](https://github.com/solana-labs/solana/issues/1485)

61
docs/src/wallet/README.md Normal file
View File

@@ -0,0 +1,61 @@
# Solana Wallet Guide
This document describes the different wallet options that are available to users
of Solana who want to be able to send, receive and interact with
SOL tokens on the Solana blockchain.
## What is a Wallet?
A crypto wallet is a device or application that stores a collection of keys and
can be used to send, receive,
and track ownership of cryptocurrencies. Wallets can take many forms.
A wallet might be a directory or file in your computer's file system,
a piece of paper, or a specialized device called a *hardware wallet*.
There are also various smartphone apps and computer programs
that provide a user-friendly way to create and manage wallets.
A *keypair* is a securely generated *private key* and its
cryptographically-derived *public key*. A private key and its corresponding
public key are together known as a *keypair*.
A wallet contains a collection of one or more keypairs and provides some means
to interact with them.
The *public key* (commonly shortened to *pubkey*) is known as the wallet's
*receiving address* or simply its *address*. The wallet address **may be shared
and displayed freely**. When another party is going to send some amount of
cryptocurrency to a wallet, they need to know the wallet's receiving address.
Depending on a blockchain's implementation, the address can also be used to view
certain information about a wallet, such as viewing the balance,
but has no ability to change anything about the wallet or withdraw any tokens.
The *private key* is required to digitally sign any transactions to send
cryptocurrencies to another address or to make any changes to the wallet.
The private key **must never be shared**. If someone gains access to the
private key to a wallet, they can withdraw all the tokens it contains.
If the private key for a wallet is lost, any tokens that have been sent
to that wallet's address are **permanently lost**.
Different wallet solutions offer different approaches to keypair security and
interacting with the keypair and sign transactions to use/spend the tokens.
Some are easier to use than others.
Some store and back up private keys more securely.
Solana supports multiple types of wallets so you can choose the right balance
of security and convenience.
**If you want to be able to receive SOL tokens on the Solana blockchain,
you first will need to create a wallet.**
## Supported Wallets
Solana supports supports several types of wallets in the Solana native
command-line app as well as wallets from third-parties.
For the majority of users, we recommend using one of the
[app wallets](app-wallets.md), which will provide a more familiar user
experience rather than needing to learn command line tools.
{% page-ref page="app-wallets.md" %}
For advanced users or developers, the [command-line wallets](cli-wallets.md)
may be more appropriate, as new features on the Solana blockchain will always be
supported on the command line first before being integrated into third-party
solutions.
{% page-ref page="cli-wallets.md" %}

View File

@@ -0,0 +1,26 @@
# App Wallets
Solana supports multiple third-party apps which should provide a familiar
experience for most people who are new or experienced with using crypto wallets.
## Trust Wallet
[Trust Wallet](https://trustwallet.com/) is an app for iOS and Android. This is
currently the easiest and fastest way to get set up with a new wallet on Solana.
The app is free and getting your wallet set up only takes a few minutes.
{% page-ref page="trust-wallet.md" %}
## Ledger Live with Ledger Nano S
[Ledger Live](https://www.ledger.com/ledger-live) is available as free desktop
software and as a free app for iOS and Android. It is used to manage apps and
crypto accounts on a Ledger *hardware wallet*, which must be purchased
separately and connected to the device running Ledger Live.
[Ledger Nano S](https://shop.ledger.com/products/ledger-nano-s) is a
hardware wallet which stores the wallet's private keys on a secure device that
is physically separate from the computer, and connects via USB cable.
This provides an extra level of security but requires the user to purchase and
keep track of the hardware device.
Solana does not support the Ledger Nano **X** at this time.
{% page-ref page="ledger-live.md" %}

View File

@@ -1,11 +1,13 @@
# Choose a Wallet
# Command Line Wallets
Keypairs are stored in *wallets* and wallets come in many forms. A wallet might
be a directory in your computer's file system, a piece of paper, or a
specialized device called a *hardware wallet*. Some wallets are easier to use
than others. Some are more secure than others. In this section, we will compare
and contrast different types of wallets and help you choose the wallet that
best fits your needs.
Solana supports several different types of wallets that can be used to interface
directly with the Solana command-line tools.
**If you are unfamiliar with using command line programs and just want to be able
to send and receive SOL tokens, we recommend setting up a third-party
[App Wallet](app-wallets.md)**.
To use a Command Line Wallet, you must first [install the Solana CLI tools](../cli/install-solana-cli-tools.md)
## File System Wallet
@@ -38,10 +40,12 @@ In terms of convenience versus security, a paper wallet sits at the opposite
side of the spectrum from an FS wallet. It is terribly inconvenient to use, but
offers excellent security. That high security is further amplified when paper
wallets are used in conjunction with
[offline signing](../offline-signing/index.md). Custody services such as
[Coinbase Custody](https://custody.coinbase.com/) use this combination. Paper wallets
and custody services are an excellent way to secure a large number of tokens
for a long period of time.
[offline signing](../offline-signing/README.md). Custody services such as
[Coinbase Custody](https://custody.coinbase.com/) use this combination.
Paper wallets and custody services are an excellent way to secure a large number
of tokens for a long period of time.
{% page-ref page="../paper-wallet/README.md" %}
## Hardware Wallet
@@ -56,10 +60,4 @@ security and convenience for cryptocurrencies. It effectively automates the
process of offline signing while retaining nearly all the convenience of an FS
wallet.
## Which Wallet is Best?
Different people will have different needs, but if you are still unsure what
is best for you after reading the comparisons above, go with a
[Ledger Nano S](https://shop.ledger.com/products/ledger-nano-s). The
[Nano S is well-integrated into Solana's tool suite](../remote-wallet/ledger.md)
and offers an outstanding blend of security and convenience.
{% page-ref page="../remote-wallet/README.md" %}

View File

@@ -0,0 +1,42 @@
#Ledger Live and Ledger Nano S
This document describes how to set up a
[Ledger Nano S hardware wallet](https://shop.ledger.com/products/ledger-nano-s)
with the [Ledger Live](https://www.ledger.com/ledger-live) software.
**NOTE: While Solana tools are fully integrated with the Ledger Nano S device,
and the Solana App can be installed on the Nano S using Ledger Live, adding and
managing wallet accounts currently requires use of our command-line tools.
Integration with Ledger Live to use Solana wallet accounts on Ledger Live
will be available in the future.**
Users may [use a Ledger Nano S with the Solana command
line tools](../remote-wallet/ledger.md).
##Set up a Ledger Nano S
- Order a [Nano S from Ledger](https://shop.ledger.com/products/ledger-nano-s)
- Follow the instructions for device setup included in the package,
or [Ledger's Start page](https://www.ledger.com/start/)
##Install Ledger Live
- Install [Ledger Live desktop software](https://www.ledger.com/ledger-live/),
or
- Install the [Ledger Live app for iOS](https://apps.apple.com/app/id1361671700)
or [Ledger Live for Android](https://play.google.com/store/apps/details?id=com.ledger.live).
- Requires iOS 9.1 or later. Compatible with iPhone, iPad, and iPod touch.
- Requires Android 7.0 or later.
- Connect your Nano S to your device and follow the instructions
##Install the Solana App on your Nano S
- Open Ledger Live
- Currently Ledger Live needs to be in "Developer Mode"
(Settings > Experimental Features > Developer Mode) to see our app.
- Go to Manager in the app and find "Solana" in the App Catalog and
click Install
- Make sure your device is plugged in via USB and is unlocked with its PIN
- You may be prompted on the Nano S to confirm the install of Solana App
- "Solana" should now show as "Installed" in the Ledger Live Manager
##Interact with Solana network
- To interact with your Ledger wallet on our live network, please see our
instructions on how to [use a Ledger Nano S with the Solana command
line tools](../remote-wallet/ledger.md).

View File

@@ -0,0 +1,37 @@
#Trust Wallet
**NOTE: Trust Wallet currently only supports Solana on the iOS version of its
app. Support for Android is coming very very soon!**
##Set Up Trust Wallet
- Open the App Store or Play Store
- Download “Trust: Crypto & Bitcoin Wallet” from Six Days LLC
- Requires iOS 13.0 or higher
- Requires Android 6.0 or higher
- Open Trust Wallet and follow the app prompts to get started
##Add Solana (SOL) tokens to your wallet
- From the main page, go to the “Tokens” tab at the top of the screen
- Tap the “+” icon at the top right corner
- Search for “Solana” in the search page, and when the “Solana SOL” token is
shown, slide the slider to enable this token.
- You can now tap the Solana icon to access your Solana wallet.
[Trust Wallet Official Docs: How to Add or Remove a Coin](https://community.trustwallet.com/t/how-to-add-or-remove-a-coin/896)
##Receiving SOL tokens
- To receive SOL tokens that youve purchased or earned, you need to send your
Receive Address to whoever is sending you tokens.
- Tap “Receive” to view a QR code and your text address, which is a long string
of letters and numbers.
- Tap “Copy” or “Share” to send the address.
- Be very careful when you copy and paste your receive address anywhere that
you do not miss any characters at the beginning or end of the string.
- If you send an incorrect Receive address to someone and they send tokens
to that address, **those tokens will be lost forever**.
[Trust Wallet Official Docs: How to Find my Receiving Address](https://community.trustwallet.com/t/how-to-find-my-receiving-address/2006)
##Troubleshooting
If you are having trouble setting up your Trust Wallet app, check out their
[Community Help Center](https://community.trustwallet.com/c/helpcenter)

View File

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

View File

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

View File

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

View File

@@ -3,19 +3,19 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-gossip"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-net-utils = { path = "../net-utils", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-core = { path = "../core", version = "1.0.12" }
solana-client = { path = "../client", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-net-utils = { path = "../net-utils", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }

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.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -24,11 +24,11 @@ reqwest = { version = "0.10.1", default-features = false, features = ["blocking"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.9" }
solana-config-program = { path = "../programs/config", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-client = { path = "../client", version = "1.0.12" }
solana-config-program = { path = "../programs/config", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
semver = "0.9.0"
tar = "0.4.26"
tempdir = "0.3.7"

View File

@@ -2,8 +2,10 @@
extern crate lazy_static;
use clap::{crate_description, crate_name, App, AppSettings, Arg, ArgMatches, SubCommand};
use solana_clap_utils::input_validators::{is_pubkey, is_url};
use solana_sdk::pubkey::Pubkey;
use solana_clap_utils::{
input_parsers::pubkey_of,
input_validators::{is_pubkey, is_url},
};
mod build_env;
mod command;
@@ -53,6 +55,30 @@ pub fn explicit_release_of(
})
}
fn handle_init(matches: &ArgMatches<'_>, config_file: &str) -> Result<(), String> {
let json_rpc_url = matches.value_of("json_rpc_url").unwrap();
let update_manifest_pubkey = pubkey_of(&matches, "update_manifest_pubkey");
let data_dir = matches.value_of("data_dir").unwrap();
let no_modify_path = matches.is_present("no_modify_path");
let explicit_release = explicit_release_of(&matches, "explicit_release");
if update_manifest_pubkey.is_none() && explicit_release.is_none() {
Err(format!(
"Please specify the release to install for {}. See --help for more",
build_env::TARGET
))
} else {
command::init(
config_file,
data_dir,
json_rpc_url,
&update_manifest_pubkey.unwrap_or_default(),
no_modify_path,
explicit_release,
)
}
}
pub fn main() -> Result<(), String> {
solana_logger::setup();
@@ -111,7 +137,6 @@ pub fn main() -> Result<(), String> {
.long("pubkey")
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey)
.help("Public key of the update manifest"),
)
@@ -121,7 +146,7 @@ pub fn main() -> Result<(), String> {
.index(1)
.conflicts_with_all(&["json_rpc_url", "update_manifest_pubkey"])
.validator(is_explicit_release)
.help("The exact version to install. Either a semver or release channel name"),
.help("The release version or channel to install"),
),
)
.subcommand(
@@ -206,26 +231,7 @@ pub fn main() -> Result<(), String> {
let config_file = matches.value_of("config_file").unwrap();
match matches.subcommand() {
("init", Some(matches)) => {
let json_rpc_url = matches.value_of("json_rpc_url").unwrap();
let update_manifest_pubkey = matches
.value_of("update_manifest_pubkey")
.unwrap()
.parse::<Pubkey>()
.unwrap();
let data_dir = matches.value_of("data_dir").unwrap();
let no_modify_path = matches.is_present("no_modify_path");
let explicit_release = explicit_release_of(&matches, "explicit_release");
command::init(
config_file,
data_dir,
json_rpc_url,
&update_manifest_pubkey,
no_modify_path,
explicit_release,
)
}
("init", Some(matches)) => handle_init(&matches, &config_file),
("info", Some(matches)) => {
let local_info_only = matches.is_present("local_info_only");
command::info(config_file, local_info_only).map(|_| ())
@@ -309,7 +315,6 @@ pub fn main_init() -> Result<(), String> {
.long("pubkey")
.value_name("PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey)
.help("Public key of the update manifest"),
)
@@ -319,28 +324,10 @@ pub fn main_init() -> Result<(), String> {
.index(1)
.conflicts_with_all(&["json_rpc_url", "update_manifest_pubkey"])
.validator(is_explicit_release)
.help("The exact version to install. Updates will not be available if this argument is used"),
.help("The release version or channel to install"),
)
.get_matches();
let config_file = matches.value_of("config_file").unwrap();
let json_rpc_url = matches.value_of("json_rpc_url").unwrap();
let update_manifest_pubkey = matches
.value_of("update_manifest_pubkey")
.unwrap()
.parse::<Pubkey>()
.unwrap();
let data_dir = matches.value_of("data_dir").unwrap();
let no_modify_path = matches.is_present("no_modify_path");
let explicit_release = explicit_release_of(&matches, "explicit_release");
command::init(
config_file,
data_dir,
json_rpc_url,
&update_manifest_pubkey,
no_modify_path,
explicit_release,
)
handle_init(&matches, &config_file)
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-keygen"
version = "1.0.9"
version = "1.0.12"
description = "Solana key generation utility"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,10 +13,10 @@ bs58 = "0.3.0"
clap = "2.33"
dirs = "2.0.2"
num_cpus = "1.12.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-cli-config = { path = "../cli-config", version = "1.0.9" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-cli-config = { path = "../cli-config", version = "1.0.12" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
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.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,12 +14,13 @@ clap = "2.33.0"
histogram = "*"
serde_json = "1.0.46"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-vote-program = { path = "../programs/vote", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-vote-program = { path = "../programs/vote", version = "1.0.12" }
solana-stake-program = { path = "../programs/stake", version = "1.0.12" }
tempfile = "3.1.0"
[dev-dependencies]

View File

@@ -21,6 +21,7 @@ use solana_sdk::{
use solana_vote_program::vote_state::VoteState;
use std::{
collections::{BTreeMap, HashMap, HashSet},
convert::TryInto,
ffi::OsStr,
fs::{self, File},
io::{self, stdout, Write},
@@ -35,6 +36,32 @@ enum LedgerOutputMethod {
Json,
}
fn output_slot_rewards(
blockstore: &Blockstore,
slot: Slot,
method: &LedgerOutputMethod,
) -> Result<(), String> {
// Note: rewards are not output in JSON yet
if *method == LedgerOutputMethod::Print {
if let Ok(rewards) = blockstore.read_rewards(slot) {
if let Some(rewards) = rewards {
if !rewards.is_empty() {
println!(" Rewards:");
for reward in rewards {
println!(
" Account {}: {}{} SOL",
reward.pubkey,
if reward.lamports < 0 { '-' } else { ' ' },
lamports_to_sol(reward.lamports.abs().try_into().unwrap())
);
}
}
}
}
}
Ok(())
}
fn output_slot(
blockstore: &Blockstore,
slot: Slot,
@@ -93,6 +120,15 @@ fn output_slot(
println!(" {:?}", vote_instruction);
raw = false;
}
} else if program_pubkey == solana_stake_program::id() {
if let Ok(stake_instruction) =
limited_deserialize::<
solana_stake_program::stake_instruction::StakeInstruction,
>(&instruction.data)
{
println!(" {:?}", stake_instruction);
raw = false;
}
} else if program_pubkey == solana_sdk::system_program::id() {
if let Ok(system_instruction) =
limited_deserialize::<
@@ -108,15 +144,62 @@ fn output_slot(
println!(" Data: {:?}", instruction.data);
}
}
match blockstore.read_transaction_status((slot, transaction.signatures[0])) {
Ok(transaction_status) => {
if let Some(transaction_status) = transaction_status {
println!(
" Status: {}",
if transaction_status.status.is_ok() {
"Ok".into()
} else {
transaction_status.status.unwrap_err().to_string()
}
);
println!(" Fee: {}", transaction_status.fee);
assert_eq!(
transaction_status.pre_balances.len(),
transaction_status.post_balances.len()
);
for (i, (pre, post)) in transaction_status
.pre_balances
.iter()
.zip(transaction_status.post_balances.iter())
.enumerate()
{
if pre == post {
println!(
" Account {} balance: {} SOL",
i,
lamports_to_sol(*pre)
);
} else {
println!(
" Account {} balance: {} SOL -> {} SOL",
i,
lamports_to_sol(*pre),
lamports_to_sol(*post)
);
}
}
} else {
println!(" Status: Unavailable");
}
}
Err(err) => {
println!(" Status: {:?}", err);
}
}
}
}
LedgerOutputMethod::Json => {
// Note: transaction status is not output in JSON yet
serde_json::to_writer(stdout(), &entry).expect("serialize entry");
stdout().write_all(b",\n").expect("newline");
}
}
}
Ok(())
output_slot_rewards(blockstore, slot, method)
}
fn output_ledger(blockstore: Blockstore, starting_slot: Slot, method: LedgerOutputMethod) {

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ledger"
version = "1.0.9"
version = "1.0.12"
description = "Solana ledger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -28,19 +28,19 @@ reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0
regex = "1.3.4"
serde = "1.0.104"
serde_bytes = "0.11.3"
solana-client = { path = "../client", version = "1.0.9" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-measure = { path = "../measure", version = "1.0.9" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.9" }
solana-metrics = { path = "../metrics", version = "1.0.9" }
solana-perf = { path = "../perf", version = "1.0.9" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.12" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-measure = { path = "../measure", version = "1.0.12" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.12" }
solana-metrics = { path = "../metrics", version = "1.0.12" }
solana-perf = { path = "../perf", version = "1.0.12" }
ed25519-dalek = "1.0.0-pre.1"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-stake-program = { path = "../programs/stake", version = "1.0.9" }
solana-vote-program = { path = "../programs/vote", version = "1.0.9" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-stake-program = { path = "../programs/stake", version = "1.0.12" }
solana-vote-program = { path = "../programs/vote", version = "1.0.12" }
symlink = "0.1.0"
tar = "0.4.26"
thiserror = "1.0"
@@ -57,7 +57,7 @@ features = ["lz4"]
[dev-dependencies]
assert_matches = "1.3.0"
matches = "0.1.6"
solana-budget-program = { path = "../programs/budget", version = "1.0.9" }
solana-budget-program = { path = "../programs/budget", version = "1.0.12" }
[lib]
crate-type = ["lib"]

View File

@@ -185,7 +185,6 @@ impl BankForks {
// of banks since the last snapshot
if self.snapshot_config.is_some() && snapshot_package_sender.is_some() {
let config = self.snapshot_config.as_ref().unwrap();
info!("setting snapshot root: {}", root);
if root - self.last_snapshot_slot >= config.snapshot_interval_slots as Slot {
let mut snapshot_time = Measure::start("total-snapshot-ms");
let r = self.generate_snapshot(

View File

@@ -22,10 +22,6 @@ use rayon::{
ThreadPool,
};
use rocksdb::DBRawIterator;
use solana_client::rpc_response::{
RpcConfirmedBlock, RpcEncodedTransaction, RpcRewards, RpcTransactionEncoding,
RpcTransactionStatusMeta, RpcTransactionWithStatusMeta,
};
use solana_measure::measure::Measure;
use solana_metrics::{datapoint_debug, datapoint_error};
use solana_rayon_threadlimit::get_thread_count;
@@ -40,6 +36,10 @@ use solana_sdk::{
timing::timestamp,
transaction::Transaction,
};
use solana_transaction_status::{
ConfirmedBlock, EncodedTransaction, Rewards, TransactionEncoding, TransactionStatusMeta,
TransactionWithStatusMeta,
};
use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::TIMESTAMP_SLOT_INTERVAL};
use std::{
cell::RefCell,
@@ -1396,15 +1396,15 @@ impl Blockstore {
pub fn get_confirmed_block(
&self,
slot: Slot,
encoding: Option<RpcTransactionEncoding>,
) -> Result<RpcConfirmedBlock> {
encoding: Option<TransactionEncoding>,
) -> Result<ConfirmedBlock> {
let lowest_cleanup_slot = self.lowest_cleanup_slot.read().unwrap();
// lowest_cleanup_slot is the last slot that was not cleaned up by
// LedgerCleanupService
if *lowest_cleanup_slot > slot {
return Err(BlockstoreError::SlotCleanedUp);
}
let encoding = encoding.unwrap_or(RpcTransactionEncoding::Json);
let encoding = encoding.unwrap_or(TransactionEncoding::Json);
if self.is_root(slot) {
let slot_meta_cf = self.db.column::<cf::SlotMeta>();
let slot_meta = match slot_meta_cf.get(slot)? {
@@ -1433,7 +1433,7 @@ impl Blockstore {
let rewards = self.rewards_cf.get(slot)?.unwrap_or_else(|| vec![]);
let block = RpcConfirmedBlock {
let block = ConfirmedBlock {
previous_blockhash: previous_blockhash.to_string(),
blockhash: blockhash.to_string(),
parent_slot: slot_meta.parent_slot,
@@ -1453,15 +1453,14 @@ impl Blockstore {
fn map_transactions_to_statuses<'a>(
&self,
slot: Slot,
encoding: RpcTransactionEncoding,
encoding: TransactionEncoding,
iterator: impl Iterator<Item = Transaction> + 'a,
) -> Vec<RpcTransactionWithStatusMeta> {
) -> Vec<TransactionWithStatusMeta> {
iterator
.map(|transaction| {
let signature = transaction.signatures[0];
let encoded_transaction =
RpcEncodedTransaction::encode(transaction, encoding.clone());
RpcTransactionWithStatusMeta {
let encoded_transaction = EncodedTransaction::encode(transaction, encoding.clone());
TransactionWithStatusMeta {
transaction: encoded_transaction,
meta: self
.transaction_status_cf
@@ -1472,15 +1471,26 @@ impl Blockstore {
.collect()
}
pub fn read_transaction_status(
&self,
index: (Slot, Signature),
) -> Result<Option<TransactionStatusMeta>> {
self.transaction_status_cf.get(index)
}
pub fn write_transaction_status(
&self,
index: (Slot, Signature),
status: &RpcTransactionStatusMeta,
status: &TransactionStatusMeta,
) -> Result<()> {
self.transaction_status_cf.put(index, status)
}
pub fn write_rewards(&self, index: Slot, rewards: RpcRewards) -> Result<()> {
pub fn read_rewards(&self, index: Slot) -> Result<Option<Rewards>> {
self.rewards_cf.get(index)
}
pub fn write_rewards(&self, index: Slot, rewards: Rewards) -> Result<()> {
self.rewards_cf.put(index, &rewards)
}
@@ -4803,7 +4813,7 @@ pub mod tests {
.put_meta_bytes(slot - 1, &serialize(&parent_meta).unwrap())
.unwrap();
let expected_transactions: Vec<(Transaction, Option<RpcTransactionStatusMeta>)> = entries
let expected_transactions: Vec<(Transaction, Option<TransactionStatusMeta>)> = entries
.iter()
.cloned()
.filter(|entry| !entry.is_tick())
@@ -4820,7 +4830,7 @@ pub mod tests {
.transaction_status_cf
.put(
(slot, signature),
&RpcTransactionStatusMeta {
&TransactionStatusMeta {
status: Ok(()),
fee: 42,
pre_balances: pre_balances.clone(),
@@ -4832,7 +4842,7 @@ pub mod tests {
.transaction_status_cf
.put(
(slot + 1, signature),
&RpcTransactionStatusMeta {
&TransactionStatusMeta {
status: Ok(()),
fee: 42,
pre_balances: pre_balances.clone(),
@@ -4842,7 +4852,7 @@ pub mod tests {
.unwrap();
(
transaction,
Some(RpcTransactionStatusMeta {
Some(TransactionStatusMeta {
status: Ok(()),
fee: 42,
pre_balances,
@@ -4859,12 +4869,12 @@ pub mod tests {
let confirmed_block = ledger.get_confirmed_block(slot, None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 100);
let expected_block = RpcConfirmedBlock {
let expected_block = ConfirmedBlock {
transactions: expected_transactions
.iter()
.cloned()
.map(|(tx, meta)| RpcTransactionWithStatusMeta {
transaction: RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json),
.map(|(tx, meta)| TransactionWithStatusMeta {
transaction: EncodedTransaction::encode(tx, TransactionEncoding::Json),
meta,
})
.collect(),
@@ -4880,12 +4890,12 @@ pub mod tests {
let confirmed_block = ledger.get_confirmed_block(slot + 1, None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 100);
let expected_block = RpcConfirmedBlock {
let expected_block = ConfirmedBlock {
transactions: expected_transactions
.iter()
.cloned()
.map(|(tx, meta)| RpcTransactionWithStatusMeta {
transaction: RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json),
.map(|(tx, meta)| TransactionWithStatusMeta {
transaction: EncodedTransaction::encode(tx, TransactionEncoding::Json),
meta,
})
.collect(),
@@ -5105,7 +5115,7 @@ pub mod tests {
assert!(transaction_status_cf
.put(
(0, Signature::default()),
&RpcTransactionStatusMeta {
&TransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Err(
TransactionError::AccountNotFound
),
@@ -5117,7 +5127,7 @@ pub mod tests {
.is_ok());
// result found
let RpcTransactionStatusMeta {
let TransactionStatusMeta {
status,
fee,
pre_balances,
@@ -5135,7 +5145,7 @@ pub mod tests {
assert!(transaction_status_cf
.put(
(9, Signature::default()),
&RpcTransactionStatusMeta {
&TransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Ok(()),
fee: 9u64,
pre_balances: pre_balances_vec.clone(),
@@ -5145,7 +5155,7 @@ pub mod tests {
.is_ok());
// result found
let RpcTransactionStatusMeta {
let TransactionStatusMeta {
status,
fee,
pre_balances,
@@ -5200,7 +5210,7 @@ pub mod tests {
transaction_status_cf
.put(
(slot, transaction.signatures[0]),
&RpcTransactionStatusMeta {
&TransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Err(
TransactionError::AccountNotFound,
),
@@ -5223,7 +5233,7 @@ pub mod tests {
let map = blockstore.map_transactions_to_statuses(
slot,
RpcTransactionEncoding::Json,
TransactionEncoding::Json,
transactions.into_iter(),
);
assert_eq!(map.len(), 5);

View File

@@ -10,8 +10,8 @@ use rocksdb::{
};
use serde::de::DeserializeOwned;
use serde::Serialize;
use solana_client::rpc_response::{RpcRewards, RpcTransactionStatusMeta};
use solana_sdk::{clock::Slot, signature::Signature};
use solana_transaction_status::{Rewards, TransactionStatusMeta};
use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc};
use thiserror::Error;
@@ -53,7 +53,7 @@ pub enum BlockstoreError {
FsExtraError(#[from] fs_extra::error::Error),
SlotCleanedUp,
}
pub(crate) type Result<T> = std::result::Result<T, BlockstoreError>;
pub type Result<T> = std::result::Result<T, BlockstoreError>;
impl std::fmt::Display for BlockstoreError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -269,7 +269,7 @@ pub trait TypedColumn: Column {
}
impl TypedColumn for columns::TransactionStatus {
type Type = RpcTransactionStatusMeta;
type Type = TransactionStatusMeta;
}
pub trait SlotColumn<Index = u64> {}
@@ -330,7 +330,7 @@ impl ColumnName for columns::Rewards {
const NAME: &'static str = REWARDS_CF;
}
impl TypedColumn for columns::Rewards {
type Type = RpcRewards;
type Type = Rewards;
}
impl Column for columns::ShredCode {

View File

@@ -8,7 +8,7 @@ use solana_measure::measure::Measure;
use solana_runtime::{
accounts_db::{SnapshotStorage, SnapshotStorages},
bank::{
self, deserialize_from_snapshot, Bank, BankRcSerialize, BankSlotDelta,
self, bank_1_0::Bank1_0, deserialize_from_snapshot, Bank, BankRcSerialize, BankSlotDelta,
MAX_SNAPSHOT_DATA_FILE_SIZE,
},
};
@@ -30,7 +30,8 @@ pub const TAR_SNAPSHOTS_DIR: &str = "snapshots";
pub const TAR_ACCOUNTS_DIR: &str = "accounts";
pub const TAR_VERSION_FILE: &str = "version";
pub const SNAPSHOT_VERSION: &str = "1.0.0";
pub const SNAPSHOT_VERSION_1_0: &str = "1.0.0";
pub const SNAPSHOT_VERSION: &str = "1.1.0";
#[derive(PartialEq, Ord, Eq, Debug)]
pub struct SlotSnapshotPaths {
@@ -593,6 +594,10 @@ where
MAX_SNAPSHOT_DATA_FILE_SIZE,
|stream| {
let mut bank: Bank = match snapshot_version {
SNAPSHOT_VERSION_1_0 => {
let bank_1_0: Bank1_0 = deserialize_from_snapshot(stream.by_ref())?;
bank_1_0.convert_to_current()
}
SNAPSHOT_VERSION => deserialize_from_snapshot(stream.by_ref())?,
_ => {
return Err(get_io_error(&format!(
@@ -602,6 +607,7 @@ where
}
};
info!("Rebuilding accounts...");
let rc = bank::BankRc::from_stream(
account_paths,
bank.slot(),

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.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -12,23 +12,23 @@ homepage = "https://solana.com/"
itertools = "0.8.1"
log = "0.4.8"
rand = "0.6.5"
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.9" }
solana-config-program = { path = "../programs/config", version = "1.0.9" }
solana-core = { path = "../core", version = "1.0.9" }
solana-client = { path = "../client", version = "1.0.9" }
solana-faucet = { path = "../faucet", version = "1.0.9" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.9" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.9" }
solana-ledger = { path = "../ledger", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-runtime = { path = "../runtime", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-stake-program = { path = "../programs/stake", version = "1.0.9" }
solana-storage-program = { path = "../programs/storage", version = "1.0.9" }
solana-vest-program = { path = "../programs/vest", version = "1.0.9" }
solana-vote-program = { path = "../programs/vote", version = "1.0.9" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.12" }
solana-config-program = { path = "../programs/config", version = "1.0.12" }
solana-core = { path = "../core", version = "1.0.12" }
solana-client = { path = "../client", version = "1.0.12" }
solana-faucet = { path = "../faucet", version = "1.0.12" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.12" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.12" }
solana-ledger = { path = "../ledger", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
solana-runtime = { path = "../runtime", version = "1.0.12" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-stake-program = { path = "../programs/stake", version = "1.0.12" }
solana-storage-program = { path = "../programs/storage", version = "1.0.12" }
solana-vest-program = { path = "../programs/vest", version = "1.0.12" }
solana-vote-program = { path = "../programs/vote", version = "1.0.12" }
tempfile = "3.1.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.9" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.12" }
[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.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,8 +14,8 @@ byte-unit = "3.0.3"
clap = "2.33.0"
serde = "1.0.104"
serde_json = "1.0.46"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
[[bin]]
name = "solana-log-analyzer"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-logger"
version = "1.0.9"
version = "1.0.12"
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.0.9"
version = "1.0.12"
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.0.9" }
solana-metrics = { path = "../metrics", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
solana-metrics = { path = "../metrics", version = "1.0.12" }
[target."cfg(unix)".dependencies]
jemallocator = "0.3.2"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-merkle-tree"
version = "1.0.9"
version = "1.0.12"
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.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
[dev-dependencies]
hex = "0.4.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-metrics"
version = "1.0.9"
version = "1.0.12"
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.1", default-features = false, features = ["blocking", "rustls-tls"] }
solana-sdk = { path = "../sdk", version = "1.0.9" }
solana-sdk = { path = "../sdk", version = "1.0.12" }
[dev-dependencies]
rand = "0.6.5"

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.0.9"
version = "1.0.12"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -13,8 +13,8 @@ publish = false
clap = "2.33.0"
serde = "1.0.104"
serde_json = "1.0.46"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
rand = "0.6.5"
[[bin]]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-net-utils"
version = "1.0.9"
version = "1.0.12"
description = "Solana Network Utilities"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,8 +18,8 @@ rand = "0.6.1"
serde = "1.0.104"
serde_derive = "1.0.103"
socket2 = "0.3.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.9" }
solana-logger = { path = "../logger", version = "1.0.9" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.12" }
solana-logger = { path = "../logger", version = "1.0.12" }
tokio = "0.1"
tokio-codec = "0.1"

View File

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

232
programs/bpf/Cargo.lock generated
View File

@@ -177,12 +177,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bumpalo"
version = "3.1.2"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bv"
version = "0.11.0"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"feature-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -719,6 +719,15 @@ dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gethostname"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.12"
@@ -1936,7 +1945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "solana-bpf-loader-program"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1944,170 +1953,170 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 1.1.0",
"solana-sdk 1.1.0",
"solana-logger 1.0.10",
"solana-sdk 1.0.10",
"solana_rbpf 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-programs"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-bpf-loader-program 1.1.0",
"solana-logger 1.1.0",
"solana-runtime 1.1.0",
"solana-sdk 1.1.0",
"solana-bpf-loader-program 1.0.10",
"solana-logger 1.0.10",
"solana-runtime 1.0.10",
"solana-sdk 1.0.10",
"solana_rbpf 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-rust-128bit"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-bpf-rust-128bit-dep 1.1.0",
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-bpf-rust-128bit-dep 1.0.10",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-128bit-dep"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-alloc"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-dep-crate"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-dup-accounts"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-error-handling"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-rust-external-spend"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-iter"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-bpf-rust-many-args-dep 1.1.0",
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-bpf-rust-many-args-dep 1.0.10",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-many-args-dep"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-noop"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-panic"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-param-passing"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-bpf-rust-param-passing-dep 1.1.0",
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-bpf-rust-param-passing-dep 1.0.10",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-param-passing-dep"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"solana-sdk 1.1.0",
"solana-sdk-bpf-test 1.1.0",
"solana-sdk 1.0.10",
"solana-sdk-bpf-test 1.0.10",
]
[[package]]
name = "solana-config-program"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 1.1.0",
"solana-sdk 1.1.0",
"solana-logger 1.0.10",
"solana-sdk 1.0.10",
]
[[package]]
name = "solana-crate-features"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2130,7 +2139,7 @@ dependencies = [
[[package]]
name = "solana-logger"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2139,45 +2148,46 @@ dependencies = [
[[package]]
name = "solana-measure"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-metrics 1.1.0",
"solana-sdk 1.1.0",
"solana-metrics 1.0.10",
"solana-sdk 1.0.10",
]
[[package]]
name = "solana-metrics"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.1.0",
"sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.0.10",
]
[[package]]
name = "solana-rayon-threadlimit"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-runtime"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bv 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2188,28 +2198,27 @@ dependencies = [
"rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-bpf-loader-program 1.1.0",
"solana-logger 1.1.0",
"solana-measure 1.1.0",
"solana-metrics 1.1.0",
"solana-rayon-threadlimit 1.1.0",
"solana-sdk 1.1.0",
"solana-stake-program 1.1.0",
"solana-storage-program 1.1.0",
"solana-vote-program 1.1.0",
"sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-bpf-loader-program 1.0.10",
"solana-logger 1.0.10",
"solana-measure 1.0.10",
"solana-metrics 1.0.10",
"solana-rayon-threadlimit 1.0.10",
"solana-sdk 1.0.10",
"solana-stake-program 1.0.10",
"solana-storage-program 1.0.10",
"solana-vote-program 1.0.10",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-sdk"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bv 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2229,19 +2238,19 @@ dependencies = [
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-crate-features 1.1.0",
"solana-logger 1.1.0",
"solana-sdk-macro 1.1.0",
"solana-crate-features 1.0.10",
"solana-logger 1.0.10",
"solana-sdk-macro 1.0.10",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-sdk-bpf-test"
version = "1.1.0"
version = "1.0.10"
[[package]]
name = "solana-sdk-macro"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2251,7 +2260,7 @@ dependencies = [
[[package]]
name = "solana-stake-program"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2259,17 +2268,17 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-config-program 1.1.0",
"solana-logger 1.1.0",
"solana-metrics 1.1.0",
"solana-sdk 1.1.0",
"solana-vote-program 1.1.0",
"solana-config-program 1.0.10",
"solana-logger 1.0.10",
"solana-metrics 1.0.10",
"solana-sdk 1.0.10",
"solana-vote-program 1.0.10",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-storage-program"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2278,13 +2287,13 @@ dependencies = [
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 1.1.0",
"solana-sdk 1.1.0",
"solana-logger 1.0.10",
"solana-sdk 1.0.10",
]
[[package]]
name = "solana-vote-program"
version = "1.1.0"
version = "1.0.10"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2292,9 +2301,9 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 1.1.0",
"solana-metrics 1.1.0",
"solana-sdk 1.1.0",
"solana-logger 1.0.10",
"solana-metrics 1.0.10",
"solana-sdk 1.0.10",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2400,15 +2409,6 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sys-info"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.1.0"
@@ -2870,7 +2870,7 @@ name = "wasm-bindgen-backend"
version = "0.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3068,8 +3068,8 @@ dependencies = [
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
"checksum bloom 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d00ac8e5056d6d65376a3c1aa5c7c34850d6949ace17f0266953a254eb3d6fe8"
"checksum bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae"
"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4"
"checksum bv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cd4ae9e585e783756cd14b0ea21863acdfbb6383664ac2f7c9ef8d180a14727"
"checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
"checksum bv 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
@@ -3132,6 +3132,7 @@ dependencies = [
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
@@ -3275,7 +3276,6 @@ dependencies = [
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
"checksum sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d4eff5474e55653c77b4470bdc2278c7e22f942d59658d0e8767d1c97e02a7b9"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-bpf-programs"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.9"
version = "1.0.12"
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.0.9" }
solana-logger = { path = "../../logger", version = "1.0.9" }
solana-runtime = { path = "../../runtime", version = "1.0.9" }
solana-sdk = { path = "../../sdk", version = "1.0.9" }
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.0.12" }
solana-logger = { path = "../../logger", version = "1.0.12" }
solana-runtime = { path = "../../runtime", version = "1.0.12" }
solana-sdk = { path = "../../sdk", version = "1.0.12" }
solana_rbpf = "=0.1.21"
[[bench]]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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