Compare commits

...

25 Commits

Author SHA1 Message Date
mergify[bot]
de76df0cbb Bump spl-token to clean up magic number (bp #11726) (#11737)
* Bump spl-token to clean up magic number (#11726)

(cherry picked from commit 2fd2aceeb2)

# Conflicts:
#	account-decoder/Cargo.toml
#	core/Cargo.toml
#	transaction-status/Cargo.toml

* Fix conflicts and toml order

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2020-08-20 17:35:28 +00:00
Justin Starry
a0190b4105 Hotfix for enabling CPI (#11728) 2020-08-20 15:41:37 +08:00
carllin
5255a6ebd2 Cleanup test utilities (#11725)
Co-authored-by: Carl <carl@solana.com>
2020-08-20 00:10:18 -07:00
mergify[bot]
8575514235 Allow votes to timestamp subsequent slots with the same timestamp (#11715) (#11719)
(cherry picked from commit b1bc901a66)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-20 02:00:32 +00:00
Trent Nelson
2a1946436b Bump version to 1.2.26 2020-08-19 20:33:40 +00:00
Michael Vines
80649a9c3d Revert "Revert "rpc: rework binary encoding. BREAKING CHANGE (bp #11646) (#11673)""
This reverts commit fb90fb3feb.
2020-08-18 21:25:31 -07:00
Michael Vines
ad74ba0eb0 The end_slot argument to purge is now optional 2020-08-19 03:19:02 +00:00
mergify[bot]
fd41ad5d8f Remove old signatureSubscribe info (#11704) (#11705)
(cherry picked from commit 35828e8fe7)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-19 02:43:44 +00:00
mergify[bot]
63855d5c2a Get index (#11694) (#11696)
(cherry picked from commit 55ce2ebd53)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-18 19:12:49 +00:00
Michael Vines
00251f710e Bump version to v1.2.25 2020-08-18 08:40:00 -07:00
Justin Starry
14bc623989 Fully enable cross program support in mainnet-beta 2020-08-18 06:33:12 -07:00
Michael Vines
fb90fb3feb Revert "rpc: rework binary encoding. BREAKING CHANGE (bp #11646) (#11673)"
This reverts commit d6ca879d39.
2020-08-18 06:27:20 -07:00
mergify[bot]
d6ca879d39 rpc: rework binary encoding. BREAKING CHANGE (bp #11646) (#11673)
* Add base64 (binary64) encoding for getConfirmedTransaction/getConfirmedBlock

(cherry picked from commit b5f3ced860)

# Conflicts:
#	transaction-status/Cargo.toml

* decode-transaction now supports binary64

(cherry picked from commit 2ebc68a9e2)

# Conflicts:
#	cli/src/cli.rs

* Rework UiAccountData encode/decode such that it works from Rust

(cherry picked from commit 757e147b3b)

# Conflicts:
#	cli/src/cli.rs

* Rename Binary64 to Base64.  Establish Base58 encoding

(cherry picked from commit adc984a225)

* Remove "binary" encoding. Document "encoding" as required

(cherry picked from commit e5281157fa)

* resolve conflicts

Co-authored-by: Michael Vines <mvines@gmail.com>
2020-08-18 04:18:48 +00:00
mergify[bot]
2dcde5281d Faucet: Add per-request cap (#11665) (#11668)
* Add per-request cap; also use clap-utils

* Clean up arg names and take cap inputs as SOL

(cherry picked from commit 71d5409b3b)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-18 01:24:41 +00:00
mergify[bot]
e2626dad83 Re-do rent collection check on rent-exempt account (bp #11349) (#11654)
* Re-do rent collection check on rent-exempt account (#11349)

* wip: re-do rent collection check on rent-exempt account

* Let's see how the ci goes

* Restore previous code

* Well, almost all new changes are revertable

* Update doc

* Add test and gating

* Fix tests

* Fix tests, especially avoid to change abi...

* Fix more tests...

* Fix snapshot restore

* Align to _new_ with better uninitialized detection

(cherry picked from commit 23fa84b322)

# Conflicts:
#	core/src/rpc_subscriptions.rs
#	core/tests/bank_forks.rs
#	runtime/src/bank.rs

* Fix conflicts

* Add missing comment

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
2020-08-17 11:14:56 +00:00
mergify[bot]
070fbeb69a Rpc: Add until parameter for getConfirmedSignaturesForAddress2 (#11644) (#11647)
* Refactor bigtable apis to accept start and end keys

* Make helper fn to deserialize cell data

* Refactor get_confirmed_signatures_for_address to use get_row_data range

* Add until param to get_confirmed_signatures_for_address

* Add until param to blockstore api

* Plumb until through client/cli

* Simplify client params

(cherry picked from commit 6c5b8f324a)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-15 18:04:08 +00:00
mergify[bot]
497ec24754 Bigtable: Use index to filter address-signatures correctly (#11622) (#11642)
* Use index to filter address-signatures correctly

* Pull additional keys to account for filtered records

* Clarify variable name

(cherry picked from commit 820af533a4)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-14 21:08:52 +00:00
Trent Nelson
1bda09bf0e Bump version to 1.2.24 2020-08-14 18:51:08 +00:00
mergify[bot]
7ca7f8604d short_vec::decode_len() returns wrong size for aliased values (bp #11624) (#11630)
* Add failing test for decoding ShortU16 alias values

(cherry picked from commit 338f66f9aa)

* Factor out ShortU16 deser vistor logic to helper

(cherry picked from commit 6222fbcc66)

* Reimplement decode_len() with ShortU16 vistor helper

(cherry picked from commit 30dbe257cf)

Co-authored-by: Trent Nelson <trent@solana.com>
2020-08-14 15:40:12 +00:00
mergify[bot]
e2b5f2dd9c RPC: getConfirmedSignaturesForAddress2 only returns confirmed signatures (#11615) (#11617)
* Add failing test case

* Limit to only rooted slots

(cherry picked from commit 99fb36fe45)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-13 18:31:20 +00:00
mergify[bot]
3652bd57a9 Ensure highest_confirmed_root only grows (bp #11596) (#11607)
* Ensure highest_confirmed_root only grows (#11596)

* Split out commitment-cache update for unit testing

* Add failing test

* Ensure highest_confirmed_root only grows

(cherry picked from commit 4da1e9833c)

# Conflicts:
#	core/src/commitment_service.rs

* Adapt to v1.2

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2020-08-13 09:19:14 +00:00
mergify[bot]
5077d6bfb3 Return blockstore signatures-for-address despite bigtable error (#11594) (#11598)
(cherry picked from commit b1e452f876)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-08-13 01:22:31 +00:00
mergify[bot]
f0ee3e9deb Fix assertion failure (#11572) (#11589)
Co-authored-by: Carl <carl@solana.com>
(cherry picked from commit 473b5249e3)

Co-authored-by: carllin <wumu727@gmail.com>
2020-08-12 20:38:57 +00:00
mergify[bot]
babad39846 Fix typo: epoch => slot... (#11573) (#11579)
(cherry picked from commit 51e818ad64)

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
2020-08-12 09:23:05 +00:00
Trent Nelson
c15aa4a968 Bump version to 1.2.23 2020-08-12 00:34:33 +00:00
132 changed files with 1862 additions and 1149 deletions

305
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-account-decoder"
version = "1.2.22"
version = "1.2.26"
description = "Solana account decoder"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,14 +15,14 @@ bs58 = "0.3.1"
bv = "0.11.1"
Inflector = "0.11.4"
lazy_static = "1.4.0"
solana-config-program = { path = "../programs/config", version = "1.2.22" }
solana-sdk = { path = "../sdk", version = "1.2.22" }
solana-stake-program = { path = "../programs/stake", version = "1.2.22" }
solana-vote-program = { path = "../programs/vote", version = "1.2.22" }
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
serde = "1.0.112"
serde_derive = "1.0.103"
serde_json = "1.0.54"
solana-config-program = { path = "../programs/config", version = "1.2.26" }
solana-sdk = { path = "../sdk", version = "1.2.26" }
solana-stake-program = { path = "../programs/stake", version = "1.2.26" }
solana-vote-program = { path = "../programs/vote", version = "1.2.26" }
spl-token-v1-0 = { package = "spl-token", version = "1.0.8", features = ["skip-no-mangle"] }
thiserror = "1.0"
[package.metadata.docs.rs]

View File

@@ -32,17 +32,18 @@ pub struct UiAccount {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", untagged)]
pub enum UiAccountData {
Binary(String),
LegacyBinary(String), // Legacy. Retained for RPC backwards compatibility
Json(ParsedAccount),
Binary64(String),
Binary(String, UiAccountEncoding),
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum UiAccountEncoding {
Binary, // SLOW! Avoid this encoding
Binary, // Legacy. Retained for RPC backwards compatibility
Base58,
Base64,
JsonParsed,
Binary64,
}
impl UiAccount {
@@ -54,20 +55,24 @@ impl UiAccount {
data_slice_config: Option<UiDataSliceConfig>,
) -> Self {
let data = match encoding {
UiAccountEncoding::Binary => UiAccountData::Binary(
UiAccountEncoding::Binary => UiAccountData::LegacyBinary(
bs58::encode(slice_data(&account.data, data_slice_config)).into_string(),
),
UiAccountEncoding::Binary64 => UiAccountData::Binary64(base64::encode(slice_data(
&account.data,
data_slice_config,
))),
UiAccountEncoding::Base58 => UiAccountData::Binary(
bs58::encode(slice_data(&account.data, data_slice_config)).into_string(),
encoding,
),
UiAccountEncoding::Base64 => UiAccountData::Binary(
base64::encode(slice_data(&account.data, data_slice_config)),
encoding,
),
UiAccountEncoding::JsonParsed => {
if let Ok(parsed_data) =
parse_account_data(pubkey, &account.owner, &account.data, additional_data)
{
UiAccountData::Json(parsed_data)
} else {
UiAccountData::Binary64(base64::encode(&account.data))
UiAccountData::Binary(base64::encode(&account.data), UiAccountEncoding::Base64)
}
}
};
@@ -83,8 +88,12 @@ impl UiAccount {
pub fn decode(&self) -> Option<Account> {
let data = match &self.data {
UiAccountData::Json(_) => None,
UiAccountData::Binary(blob) => bs58::decode(blob).into_vec().ok(),
UiAccountData::Binary64(blob) => base64::decode(blob).ok(),
UiAccountData::LegacyBinary(blob) => bs58::decode(blob).into_vec().ok(),
UiAccountData::Binary(blob, encoding) => match encoding {
UiAccountEncoding::Base58 => bs58::decode(blob).into_vec().ok(),
UiAccountEncoding::Base64 => base64::decode(blob).ok(),
UiAccountEncoding::Binary | UiAccountEncoding::JsonParsed => None,
},
}?;
Some(Account {
lamports: self.lamports,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -27,5 +27,5 @@ Alternatively, you can source it from within a script:
local PATCH=0
local SPECIAL=""
semverParseInto "1.2.22" MAJOR MINOR PATCH SPECIAL
semverParseInto "1.2.26" MAJOR MINOR PATCH SPECIAL
semverParseInto "3.2.1" MAJOR MINOR PATCH SPECIAL

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ use crate::{
vote::*,
};
use chrono::prelude::*;
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
use clap::{value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand};
use log::*;
use num_traits::FromPrimitive;
use serde_json::{self, json, Value};
@@ -247,6 +247,7 @@ pub enum CliCommand {
TransactionHistory {
address: Pubkey,
before: Option<Signature>,
until: Option<Signature>,
limit: usize,
},
// Nonce commands
@@ -844,9 +845,14 @@ pub fn parse_command(
_ => Err(CliError::BadParameter("Invalid signature".to_string())),
},
("decode-transaction", Some(matches)) => {
let encoded_transaction = EncodedTransaction::Binary(
matches.value_of("base58_transaction").unwrap().to_string(),
);
let blob = value_t_or_exit!(matches, "transaction", String);
let encoding = match matches.value_of("encoding").unwrap() {
"base58" => UiTransactionEncoding::Binary,
"base64" => UiTransactionEncoding::Base64,
_ => unreachable!(),
};
let encoded_transaction = EncodedTransaction::Binary(blob, encoding);
if let Some(transaction) = encoded_transaction.decode() {
Ok(CliCommandInfo {
command: CliCommand::DecodeTransaction(transaction),
@@ -1177,7 +1183,7 @@ fn process_confirm(
if let Some(transaction_status) = status {
if config.verbose {
match rpc_client
.get_confirmed_transaction(signature, UiTransactionEncoding::Binary)
.get_confirmed_transaction(signature, UiTransactionEncoding::Base64)
{
Ok(confirmed_transaction) => {
println!(
@@ -1233,7 +1239,7 @@ fn process_show_account(
account: UiAccount::encode(
account_pubkey,
account,
UiAccountEncoding::Binary64,
UiAccountEncoding::Base64,
None,
None,
),
@@ -1848,8 +1854,9 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
CliCommand::TransactionHistory {
address,
before,
until,
limit,
} => process_transaction_history(&rpc_client, config, address, *before, *limit),
} => process_transaction_history(&rpc_client, config, address, *before, *until, *limit),
// Nonce Commands
@@ -2547,12 +2554,22 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
SubCommand::with_name("decode-transaction")
.about("Decode a base-58 binary transaction")
.arg(
Arg::with_name("base58_transaction")
Arg::with_name("transaction")
.index(1)
.value_name("BASE58_TRANSACTION")
.value_name("TRANSACTION")
.takes_value(true)
.required(true)
.help("The transaction to decode"),
.help("transaction to decode"),
)
.arg(
Arg::with_name("encoding")
.index(2)
.value_name("ENCODING")
.possible_values(&["base58", "base64"]) // Subset of `UiTransactionEncoding` enum
.default_value("base58")
.takes_value(true)
.required(true)
.help("transaction encoding"),
),
)
.subcommand(

View File

@@ -14,7 +14,7 @@ use solana_clap_utils::{
};
use solana_client::{
pubsub_client::{PubsubClient, SlotInfoMessage},
rpc_client::RpcClient,
rpc_client::{GetConfirmedSignaturesForAddress2Config, RpcClient},
rpc_config::{RpcLargestAccountsConfig, RpcLargestAccountsFilter},
};
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
@@ -457,12 +457,21 @@ pub fn parse_transaction_history(
),
None => None,
};
let until = match matches.value_of("until") {
Some(signature) => Some(
signature
.parse()
.map_err(|err| CliError::BadParameter(format!("Invalid signature: {}", err)))?,
),
None => None,
};
let limit = value_t_or_exit!(matches, "limit", usize);
Ok(CliCommandInfo {
command: CliCommand::TransactionHistory {
address,
before,
until,
limit,
},
signers: vec![],
@@ -1282,12 +1291,16 @@ pub fn process_transaction_history(
config: &CliConfig,
address: &Pubkey,
before: Option<Signature>,
until: Option<Signature>,
limit: usize,
) -> ProcessResult {
let results = rpc_client.get_confirmed_signatures_for_address2_with_config(
address,
before,
Some(limit),
GetConfirmedSignaturesForAddress2Config {
before,
until,
limit: Some(limit),
},
)?;
let transactions_found = format!("{} transactions found", results.len());

View File

@@ -348,7 +348,7 @@ mod tests {
let rpc_nonce_account = UiAccount::encode(
&nonce_pubkey,
nonce_account,
UiAccountEncoding::Binary64,
UiAccountEncoding::Base64,
None,
None,
);

View File

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

View File

@@ -15,12 +15,7 @@ use bincode::serialize;
use indicatif::{ProgressBar, ProgressStyle};
use log::*;
use serde_json::{json, Value};
use solana_account_decoder::{
parse_token::UiTokenAmount,
UiAccount,
UiAccountData::{Binary, Binary64},
UiAccountEncoding,
};
use solana_account_decoder::{parse_token::UiTokenAmount, UiAccount, UiAccountEncoding};
use solana_sdk::{
account::Account,
clock::{
@@ -296,18 +291,21 @@ impl RpcClient {
&self,
address: &Pubkey,
) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
self.get_confirmed_signatures_for_address2_with_config(address, None, None)
self.get_confirmed_signatures_for_address2_with_config(
address,
GetConfirmedSignaturesForAddress2Config::default(),
)
}
pub fn get_confirmed_signatures_for_address2_with_config(
&self,
address: &Pubkey,
before: Option<Signature>,
limit: Option<usize>,
config: GetConfirmedSignaturesForAddress2Config,
) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
let config = RpcGetConfirmedSignaturesForAddress2Config {
before: before.map(|signature| signature.to_string()),
limit,
before: config.before.map(|signature| signature.to_string()),
until: config.until.map(|signature| signature.to_string()),
limit: config.limit,
};
let result: Vec<RpcConfirmedTransactionStatusWithSignature> = self.send(
@@ -474,7 +472,7 @@ impl RpcClient {
commitment_config: CommitmentConfig,
) -> RpcResult<Option<Account>> {
let config = RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Binary64),
encoding: Some(UiAccountEncoding::Base64),
commitment: Some(commitment_config),
data_slice: None,
};
@@ -492,17 +490,8 @@ impl RpcClient {
}
let Response {
context,
value: mut rpc_account,
value: rpc_account,
} = serde_json::from_value::<Response<Option<UiAccount>>>(result_json)?;
if let Some(ref mut account) = rpc_account {
if let Binary(_) = &account.data {
let tmp = Binary64(String::new());
match std::mem::replace(&mut account.data, tmp) {
Binary(new_data) => account.data = Binary64(new_data),
_ => panic!("should have gotten binary here."),
}
}
}
trace!("Response account {:?} {:?}", pubkey, rpc_account);
let account = rpc_account.and_then(|rpc_account| rpc_account.decode());
Ok(Response {
@@ -1144,6 +1133,13 @@ impl RpcClient {
}
}
#[derive(Debug, Default)]
pub struct GetConfirmedSignaturesForAddress2Config {
pub before: Option<Signature>,
pub until: Option<Signature>,
pub limit: Option<usize>,
}
fn new_spinner_progress_bar() -> ProgressBar {
let progress_bar = ProgressBar::new(42);
progress_bar

View File

@@ -71,5 +71,6 @@ pub enum RpcTokenAccountsFilter {
#[serde(rename_all = "camelCase")]
pub struct RpcGetConfirmedSignaturesForAddress2Config {
pub before: Option<String>, // Signature as base-58 string
pub until: Option<String>, // Signature as base-58 string
pub limit: Option<usize>,
}

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-core"
description = "Blockchain, Rebuilt for Scale"
version = "1.2.22"
version = "1.2.26"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -42,32 +42,32 @@ regex = "1.3.7"
serde = "1.0.110"
serde_derive = "1.0.103"
serde_json = "1.0.53"
solana-account-decoder = { path = "../account-decoder", version = "1.2.22" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.22" }
solana-budget-program = { path = "../programs/budget", version = "1.2.22" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.22" }
solana-client = { path = "../client", version = "1.2.22" }
solana-faucet = { path = "../faucet", version = "1.2.22" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.22" }
solana-ledger = { path = "../ledger", version = "1.2.22" }
solana-logger = { path = "../logger", version = "1.2.22" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.22" }
solana-metrics = { path = "../metrics", version = "1.2.22" }
solana-measure = { path = "../measure", version = "1.2.22" }
solana-net-utils = { path = "../net-utils", version = "1.2.22" }
solana-perf = { path = "../perf", version = "1.2.22" }
solana-runtime = { path = "../runtime", version = "1.2.22" }
solana-sdk = { path = "../sdk", version = "1.2.22" }
solana-stake-program = { path = "../programs/stake", version = "1.2.22" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.2.22" }
solana-streamer = { path = "../streamer", version = "1.2.22" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.22" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.22" }
solana-version = { path = "../version", version = "1.2.22" }
solana-vote-program = { path = "../programs/vote", version = "1.2.22" }
solana-vote-signer = { path = "../vote-signer", version = "1.2.22" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.22" }
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
solana-account-decoder = { path = "../account-decoder", version = "1.2.26" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.26" }
solana-budget-program = { path = "../programs/budget", version = "1.2.26" }
solana-clap-utils = { path = "../clap-utils", version = "1.2.26" }
solana-client = { path = "../client", version = "1.2.26" }
solana-faucet = { path = "../faucet", version = "1.2.26" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.26" }
solana-ledger = { path = "../ledger", version = "1.2.26" }
solana-logger = { path = "../logger", version = "1.2.26" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.26" }
solana-metrics = { path = "../metrics", version = "1.2.26" }
solana-measure = { path = "../measure", version = "1.2.26" }
solana-net-utils = { path = "../net-utils", version = "1.2.26" }
solana-perf = { path = "../perf", version = "1.2.26" }
solana-runtime = { path = "../runtime", version = "1.2.26" }
solana-sdk = { path = "../sdk", version = "1.2.26" }
solana-stake-program = { path = "../programs/stake", version = "1.2.26" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.2.26" }
solana-streamer = { path = "../streamer", version = "1.2.26" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.26" }
solana-transaction-status = { path = "../transaction-status", version = "1.2.26" }
solana-version = { path = "../version", version = "1.2.26" }
solana-vote-program = { path = "../programs/vote", version = "1.2.26" }
solana-vote-signer = { path = "../vote-signer", version = "1.2.26" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.26" }
spl-token-v1-0 = { package = "spl-token", version = "1.0.8", features = ["skip-no-mangle"] }
tempfile = "3.1.0"
thiserror = "1.0"
tokio = { version = "0.2.22", features = ["full"] }

View File

@@ -1146,9 +1146,7 @@ mod tests {
// Create the set of relevant voters for the next epoch
let new_epoch = last_known_epoch + 1;
let first_slot_in_new_epoch = bank.epoch_schedule().get_first_slot_in_epoch(new_epoch);
let new_keypairs: Vec<_> = (0..10)
.map(|_| ValidatorVoteKeypairs::new(Keypair::new(), Keypair::new(), Keypair::new()))
.collect();
let new_keypairs: Vec<_> = (0..10).map(|_| ValidatorVoteKeypairs::new_rand()).collect();
let new_epoch_authorized_voters: HashMap<_, _> = new_keypairs
.iter()
.chain(validator_voting_keypairs[0..5].iter())
@@ -1187,15 +1185,14 @@ mod tests {
let ref_count_per_vote = 2;
// Create some voters at genesis
let validator_keypairs: Vec<_> = (0..2)
.map(|_| ValidatorVoteKeypairs::new(Keypair::new(), Keypair::new(), Keypair::new()))
.collect();
let validator_keypairs: Vec<_> =
(0..2).map(|_| ValidatorVoteKeypairs::new_rand()).collect();
let GenesisConfigInfo { genesis_config, .. } =
genesis_utils::create_genesis_config_with_vote_accounts(
10_000,
&validator_keypairs,
100,
vec![100; validator_keypairs.len()],
);
let bank = Bank::new(&genesis_config);
let exit = Arc::new(AtomicBool::new(false));
@@ -1336,14 +1333,13 @@ mod tests {
Vec<ValidatorVoteKeypairs>,
Arc<RpcSubscriptions>,
) {
let validator_voting_keypairs: Vec<_> = (0..10)
.map(|_| ValidatorVoteKeypairs::new(Keypair::new(), Keypair::new(), Keypair::new()))
.collect();
let validator_voting_keypairs: Vec<_> =
(0..10).map(|_| ValidatorVoteKeypairs::new_rand()).collect();
let GenesisConfigInfo { genesis_config, .. } =
genesis_utils::create_genesis_config_with_vote_accounts(
10_000,
&validator_voting_keypairs,
100,
vec![100; validator_voting_keypairs.len()],
);
let bank = Bank::new(&genesis_config);
let vote_tracker = VoteTracker::new(&bank);

View File

@@ -8,6 +8,7 @@ use solana_runtime::bank::Bank;
use solana_sdk::clock::Slot;
use solana_vote_program::vote_state::VoteState;
use std::{
cmp::max,
collections::HashMap,
sync::atomic::{AtomicBool, Ordering},
sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender},
@@ -103,27 +104,8 @@ impl AggregateCommitmentService {
}
let mut aggregate_commitment_time = Measure::start("aggregate-commitment-ms");
let (block_commitment, rooted_stake) =
Self::aggregate_commitment(&ancestors, &aggregation_data.bank);
let largest_confirmed_root =
get_largest_confirmed_root(rooted_stake, aggregation_data.total_staked);
let mut new_block_commitment = BlockCommitmentCache::new(
block_commitment,
largest_confirmed_root,
aggregation_data.total_staked,
aggregation_data.bank,
block_commitment_cache.read().unwrap().blockstore.clone(),
aggregation_data.root,
aggregation_data.root,
);
new_block_commitment.highest_confirmed_slot =
new_block_commitment.calculate_highest_confirmed_slot();
let mut w_block_commitment_cache = block_commitment_cache.write().unwrap();
std::mem::swap(&mut *w_block_commitment_cache, &mut new_block_commitment);
let cache_slot_info =
Self::update_commitment_cache(block_commitment_cache, aggregation_data, ancestors);
aggregate_commitment_time.stop();
datapoint_info!(
"block-commitment-cache",
@@ -134,12 +116,50 @@ impl AggregateCommitmentService {
)
);
subscriptions.notify_subscribers(CacheSlotInfo {
current_slot: w_block_commitment_cache.slot(),
node_root: w_block_commitment_cache.root(),
largest_confirmed_root: w_block_commitment_cache.largest_confirmed_root(),
highest_confirmed_slot: w_block_commitment_cache.highest_confirmed_slot(),
});
// Triggers rpc_subscription notifications as soon as new commitment data is available,
// sending just the commitment cache slot information that the notifications thread
// needs
subscriptions.notify_subscribers(cache_slot_info);
}
}
fn update_commitment_cache(
block_commitment_cache: &RwLock<BlockCommitmentCache>,
aggregation_data: CommitmentAggregationData,
ancestors: Vec<u64>,
) -> CacheSlotInfo {
let (block_commitment, rooted_stake) =
Self::aggregate_commitment(&ancestors, &aggregation_data.bank);
let largest_confirmed_root =
get_largest_confirmed_root(rooted_stake, aggregation_data.total_staked);
let mut new_block_commitment = BlockCommitmentCache::new(
block_commitment,
largest_confirmed_root,
aggregation_data.total_staked,
aggregation_data.bank,
block_commitment_cache.read().unwrap().blockstore.clone(),
aggregation_data.root,
aggregation_data.root,
);
new_block_commitment.highest_confirmed_slot =
new_block_commitment.calculate_highest_confirmed_slot();
let mut w_block_commitment_cache = block_commitment_cache.write().unwrap();
let largest_confirmed_root = max(
new_block_commitment.largest_confirmed_root(),
w_block_commitment_cache.largest_confirmed_root(),
);
new_block_commitment.set_largest_confirmed_root(largest_confirmed_root);
std::mem::swap(&mut *w_block_commitment_cache, &mut new_block_commitment);
CacheSlotInfo {
current_slot: w_block_commitment_cache.slot(),
node_root: w_block_commitment_cache.root(),
largest_confirmed_root: w_block_commitment_cache.largest_confirmed_root(),
highest_confirmed_slot: w_block_commitment_cache.highest_confirmed_slot(),
}
}
@@ -225,10 +245,24 @@ impl AggregateCommitmentService {
#[cfg(test)]
mod tests {
use super::*;
use solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo};
use solana_sdk::pubkey::Pubkey;
use solana_ledger::{
bank_forks::BankForks,
blockstore::Blockstore,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
get_tmp_ledger_path,
};
use solana_runtime::genesis_utils::{
create_genesis_config_with_vote_accounts, ValidatorVoteKeypairs,
};
use solana_sdk::{
pubkey::Pubkey,
signature::{Keypair, Signer},
};
use solana_stake_program::stake_state;
use solana_vote_program::vote_state::{self, VoteStateVersions};
use solana_vote_program::{
vote_state::{self, VoteStateVersions},
vote_transaction,
};
#[test]
fn test_get_largest_confirmed_root() {
@@ -451,4 +485,167 @@ mod tests {
assert_eq!(rooted_stake.len(), 2);
assert_eq!(get_largest_confirmed_root(rooted_stake, 100), 1)
}
#[test]
fn test_highest_confirmed_root_advance() {
fn get_vote_account_root_slot(vote_pubkey: Pubkey, bank: &Arc<Bank>) -> Slot {
let account = &bank.vote_accounts()[&vote_pubkey].1;
let vote_state = VoteState::from(account).unwrap();
vote_state.root_slot.unwrap()
}
let ledger_path = get_tmp_ledger_path!();
{
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
let block_commitment_cache = RwLock::new(
BlockCommitmentCache::new_for_tests_with_blockstore(blockstore),
);
let node_keypair = Keypair::new().to_bytes();
let vote_keypair = Keypair::new().to_bytes();
let stake_keypair = Keypair::new().to_bytes();
let validator_keypairs = vec![ValidatorVoteKeypairs {
node_keypair: Keypair::from_bytes(&node_keypair).unwrap(),
vote_keypair: Keypair::from_bytes(&vote_keypair).unwrap(),
stake_keypair: Keypair::from_bytes(&stake_keypair).unwrap(),
}];
let GenesisConfigInfo {
genesis_config,
mint_keypair,
voting_keypair: _,
} = create_genesis_config_with_vote_accounts(
1_000_000_000,
&validator_keypairs,
vec![100; validator_keypairs.len()],
);
let node_keypair = Keypair::from_bytes(&node_keypair).unwrap();
let vote_keypair = Keypair::from_bytes(&vote_keypair).unwrap();
let bank0 = Bank::new(&genesis_config);
bank0
.transfer(100_000, &mint_keypair, &node_keypair.pubkey())
.unwrap();
let mut bank_forks = BankForks::new(bank0);
// Fill bank_forks with banks with votes landing in the next slot
// Create enough banks such that vote account will root slots 0 and 1
for x in 0..33 {
let previous_bank = bank_forks.get(x).unwrap();
let bank = Bank::new_from_parent(previous_bank, &Pubkey::default(), x + 1);
let vote = vote_transaction::new_vote_transaction(
vec![x],
previous_bank.hash(),
previous_bank.last_blockhash(),
&node_keypair,
&vote_keypair,
&vote_keypair,
);
bank.process_transaction(&vote).unwrap();
bank_forks.insert(bank);
}
let working_bank = bank_forks.working_bank();
let root = get_vote_account_root_slot(vote_keypair.pubkey(), &working_bank);
for x in 0..root {
bank_forks.set_root(x, &None, None);
}
// Add an additional bank/vote that will root slot 2
let bank33 = bank_forks.get(33).unwrap();
let bank34 = Bank::new_from_parent(bank33, &Pubkey::default(), 34);
let vote33 = vote_transaction::new_vote_transaction(
vec![33],
bank33.hash(),
bank33.last_blockhash(),
&node_keypair,
&vote_keypair,
&vote_keypair,
);
bank34.process_transaction(&vote33).unwrap();
bank_forks.insert(bank34);
let working_bank = bank_forks.working_bank();
let root = get_vote_account_root_slot(vote_keypair.pubkey(), &working_bank);
let ancestors = working_bank.status_cache_ancestors();
let _ = AggregateCommitmentService::update_commitment_cache(
&block_commitment_cache,
CommitmentAggregationData {
bank: working_bank,
root: 0,
total_staked: 100,
},
ancestors,
);
let largest_confirmed_root = block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root();
bank_forks.set_root(root, &None, Some(largest_confirmed_root));
let largest_confirmed_root_bank = bank_forks.get(largest_confirmed_root);
assert!(largest_confirmed_root_bank.is_some());
// Add a forked bank. Because the vote for bank 33 landed in the non-ancestor, the vote
// account's root (and thus the highest_confirmed_root) rolls back to slot 1
let bank33 = bank_forks.get(33).unwrap();
let bank35 = Bank::new_from_parent(bank33, &Pubkey::default(), 35);
bank_forks.insert(bank35);
let working_bank = bank_forks.working_bank();
let ancestors = working_bank.status_cache_ancestors();
let _ = AggregateCommitmentService::update_commitment_cache(
&block_commitment_cache,
CommitmentAggregationData {
bank: working_bank,
root: 1,
total_staked: 100,
},
ancestors,
);
let largest_confirmed_root = block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root();
let largest_confirmed_root_bank = bank_forks.get(largest_confirmed_root);
assert!(largest_confirmed_root_bank.is_some());
// Add additional banks beyond lockout built on the new fork to ensure that behavior
// continues normally
for x in 35..=37 {
let previous_bank = bank_forks.get(x).unwrap();
let bank = Bank::new_from_parent(previous_bank, &Pubkey::default(), x + 1);
let vote = vote_transaction::new_vote_transaction(
vec![x],
previous_bank.hash(),
previous_bank.last_blockhash(),
&node_keypair,
&vote_keypair,
&vote_keypair,
);
bank.process_transaction(&vote).unwrap();
bank_forks.insert(bank);
}
let working_bank = bank_forks.working_bank();
let root = get_vote_account_root_slot(vote_keypair.pubkey(), &working_bank);
let ancestors = working_bank.status_cache_ancestors();
let _ = AggregateCommitmentService::update_commitment_cache(
&block_commitment_cache,
CommitmentAggregationData {
bank: working_bank,
root: 0,
total_staked: 100,
},
ancestors,
);
let largest_confirmed_root = block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root();
bank_forks.set_root(root, &None, Some(largest_confirmed_root));
let largest_confirmed_root_bank = bank_forks.get(largest_confirmed_root);
assert!(largest_confirmed_root_bank.is_some());
}
Blockstore::destroy(&ledger_path).unwrap();
}
}

View File

@@ -676,12 +676,7 @@ pub mod test {
create_genesis_config_with_vote_accounts, GenesisConfigInfo, ValidatorVoteKeypairs,
},
};
use solana_sdk::{
clock::Slot,
hash::Hash,
pubkey::Pubkey,
signature::{Keypair, Signer},
};
use solana_sdk::{clock::Slot, hash::Hash, pubkey::Pubkey, signature::Signer};
use solana_vote_program::{
vote_state::{Vote, VoteStateVersions, MAX_LOCKOUT_HISTORY},
vote_transaction,
@@ -936,14 +931,8 @@ pub mod test {
HeaviestSubtreeForkChoice,
) {
let keypairs: HashMap<_, _> = std::iter::repeat_with(|| {
let node_keypair = Keypair::new();
let vote_keypair = Keypair::new();
let stake_keypair = Keypair::new();
let node_pubkey = node_keypair.pubkey();
(
node_pubkey,
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
)
let vote_keypairs = ValidatorVoteKeypairs::new_rand();
(vote_keypairs.node_keypair.pubkey(), vote_keypairs)
})
.take(num_keypairs)
.collect();
@@ -979,7 +968,11 @@ pub mod test {
genesis_config,
mint_keypair,
voting_keypair: _,
} = create_genesis_config_with_vote_accounts(1_000_000_000, &validator_keypairs, stake);
} = create_genesis_config_with_vote_accounts(
1_000_000_000,
&validator_keypairs,
vec![stake; validator_keypairs.len()],
);
let bank0 = Bank::new(&genesis_config);

View File

@@ -167,7 +167,7 @@ impl ForkProgress {
num_dropped_blocks_on_fork: u64,
) -> Self {
let validator_fork_info = {
if bank.collector_id() == my_pubkey {
if bank.collector_id() == my_pubkey && bank.slot() > 0 {
let stake = bank.epoch_vote_account_stake(voting_pubkey);
Some(ValidatorStakeInfo::new(
*voting_pubkey,

View File

@@ -1082,7 +1082,7 @@ mod test {
} = genesis_utils::create_genesis_config_with_vote_accounts(
1_000_000_000,
&[&keypairs],
10000,
vec![10000],
);
let bank0 = Arc::new(Bank::new(&genesis_config));
let bank9 = Bank::new_from_parent(&bank0, &Pubkey::default(), duplicate_slot);
@@ -1144,7 +1144,7 @@ mod test {
genesis_utils::create_genesis_config_with_vote_accounts(
1_000_000_000,
&[keypairs],
100,
vec![100],
);
let bank0 = Bank::new(&genesis_config);

View File

@@ -170,11 +170,20 @@ impl RepairWeight {
if new_root == self.root {
return;
}
// Root slot of the tree that contains `new_root`, if one exists
let new_root_tree_root = self.slot_to_tree.get(&new_root).cloned();
// Purge outdated trees from `self.trees`
let subtrees_to_purge: Vec<_> = self
.trees
.keys()
.filter(|subtree_root| **subtree_root < new_root && **subtree_root != self.root)
.filter(|subtree_root| {
**subtree_root < new_root
&& new_root_tree_root
.map(|new_root_tree_root| **subtree_root != new_root_tree_root)
.unwrap_or(true)
})
.cloned()
.collect();
for subtree_root in subtrees_to_purge {
@@ -188,25 +197,26 @@ impl RepairWeight {
);
}
let mut root_tree = self.trees.remove(&self.root).expect("root tree must exist");
if let Some(new_root_tree_root) = new_root_tree_root {
let mut new_root_tree = self
.trees
.remove(&new_root_tree_root)
.expect("Found slot root earlier in self.slot_to_trees, treee must exist");
// Find all descendants of `self.root` that are not reachable from `new_root`.
// These are exactly the unrooted slots, which can be purged and added to
// `self.unrooted_slots`.
let unrooted_slots = new_root_tree.subtree_diff(new_root_tree_root, new_root);
self.remove_tree_slots(unrooted_slots.iter(), new_root);
// Find all descendants of `self.root` that are not reachable from `new_root`.
// These are exactly the unrooted slots, which can be purged and added to
// `self.unrooted_slots`.
let unrooted_slots = root_tree.subtree_diff(self.root, new_root);
self.remove_tree_slots(unrooted_slots.iter(), new_root);
new_root_tree.set_root(new_root);
if !root_tree.contains_slot(new_root) {
// If the current `root_tree` does not contain the new root, we can
// just make a new tree for the new root
self.insert_new_tree(new_root);
} else {
root_tree.set_root(new_root);
// Update `self.slot_to_tree` to reflect new root
self.rename_tree_root(&root_tree, new_root);
self.rename_tree_root(&new_root_tree, new_root);
// Insert the tree for the new root
self.trees.insert(new_root, root_tree);
self.trees.insert(new_root, new_root_tree);
} else {
self.insert_new_tree(new_root);
}
// Purge `self.unrooted_slots` of slots less than `new_root` as we know any
@@ -501,6 +511,7 @@ mod test {
use super::*;
use solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path};
use solana_runtime::{bank::Bank, bank_utils};
use solana_sdk::hash::Hash;
use trees::tr;
#[test]
@@ -648,7 +659,7 @@ mod test {
assert_eq!(repair_weight.trees.get(&8).unwrap().ancestors(10), vec![8]);
// Connect orphan back to main fork
blockstore.add_tree(tr(6) / (tr(8)), true, true);
blockstore.add_tree(tr(6) / (tr(8)), true, true, 2, Hash::default());
assert_eq!(
AncestorIterator::new(8, &blockstore).collect::<Vec<_>>(),
vec![6, 5, 3, 1, 0]
@@ -732,8 +743,8 @@ mod test {
assert!(repair_weight.trees.contains_key(&20));
// Resolve orphans in blockstore
blockstore.add_tree(tr(6) / (tr(8)), true, true);
blockstore.add_tree(tr(11) / (tr(20)), true, true);
blockstore.add_tree(tr(6) / (tr(8)), true, true, 2, Hash::default());
blockstore.add_tree(tr(11) / (tr(20)), true, true, 2, Hash::default());
// Call `update_orphan_ancestors` to resolve orphan
repair_weight.update_orphan_ancestors(
&blockstore,
@@ -843,8 +854,8 @@ mod test {
// Resolve the orphans, should now return no
// orphans
repairs = vec![];
blockstore.add_tree(tr(6) / (tr(8)), true, true);
blockstore.add_tree(tr(11) / (tr(20)), true, true);
blockstore.add_tree(tr(6) / (tr(8)), true, true, 2, Hash::default());
blockstore.add_tree(tr(11) / (tr(20)), true, true, 2, Hash::default());
repair_weight.get_best_orphans(
&blockstore,
&mut repairs,
@@ -879,7 +890,7 @@ mod test {
// orphan in the `trees` map, we should search for
// exactly one more of the remaining two
let mut repairs = vec![];
blockstore.add_tree(tr(100) / (tr(101)), true, true);
blockstore.add_tree(tr(100) / (tr(101)), true, true, 2, Hash::default());
repair_weight.get_best_orphans(
&blockstore,
&mut repairs,
@@ -954,13 +965,34 @@ mod test {
}
}
#[test]
fn test_set_root_existing_non_root_tree() {
let (_, _, mut repair_weight) = setup_orphan_repair_weight();
// Set root in an existing orphan branch, slot 10
repair_weight.set_root(10);
check_old_root_purged_verify_new_root(0, 10, &repair_weight);
// Should purge old root tree [0, 6]
for slot in 0..6 {
assert!(!repair_weight.slot_to_tree.contains_key(&slot));
}
// Should purge orphan parent as well
assert!(!repair_weight.slot_to_tree.contains_key(&8));
// Other higher orphan branch rooted at slot `20` remains unchanged
assert_eq!(repair_weight.trees.get(&20).unwrap().root(), 20);
assert_eq!(*repair_weight.slot_to_tree.get(&20).unwrap(), 20);
}
#[test]
fn test_set_root_check_unrooted_slots() {
let (blockstore, bank, mut repair_weight) = setup_orphan_repair_weight();
// Chain orphan 8 back to the main fork, but don't
// touch orphan 20
blockstore.add_tree(tr(4) / (tr(8)), true, true);
blockstore.add_tree(tr(4) / (tr(8)), true, true, 2, Hash::default());
// Call `update_orphan_ancestors` to resolve orphan
repair_weight.update_orphan_ancestors(
@@ -1030,10 +1062,10 @@ mod test {
}
// Chain orphan 8 back to slot `old_parent`
blockstore.add_tree(tr(*old_parent) / (tr(8)), true, true);
blockstore.add_tree(tr(*old_parent) / (tr(8)), true, true, 2, Hash::default());
// Chain orphan 20 back to orphan 8
blockstore.add_tree(tr(8) / (tr(20)), true, true);
blockstore.add_tree(tr(8) / (tr(20)), true, true, 2, Hash::default());
// Call `update_orphan_ancestors` to resolve orphan
repair_weight.update_orphan_ancestors(
@@ -1058,7 +1090,13 @@ mod test {
// Add a vote that chains back to `old_parent`, should be purged
let new_vote_slot = 100;
blockstore.add_tree(tr(*old_parent) / tr(new_vote_slot), true, true);
blockstore.add_tree(
tr(*old_parent) / tr(new_vote_slot),
true,
true,
2,
Hash::default(),
);
repair_weight.add_votes(
&blockstore,
vec![(new_vote_slot, vec![Pubkey::default()])].into_iter(),
@@ -1106,7 +1144,7 @@ mod test {
);
// Ancestors of slot 31 are [30], with no existing subtree
blockstore.add_tree(tr(30) / (tr(31)), true, true);
blockstore.add_tree(tr(30) / (tr(31)), true, true, 2, Hash::default());
assert_eq!(
repair_weight.find_ancestor_subtree_of_slot(&blockstore, 31),
(vec![30].into_iter().collect::<VecDeque<_>>(), None)
@@ -1124,7 +1162,7 @@ mod test {
// Chain orphan 8 back to slot 4 on a different fork, ancestor search
// should not return ancestors earlier than the root
blockstore.add_tree(tr(4) / (tr(8)), true, true);
blockstore.add_tree(tr(4) / (tr(8)), true, true, 2, Hash::default());
assert_eq!(
repair_weight.find_ancestor_subtree_of_slot(&blockstore, 8),
(vec![4].into_iter().collect::<VecDeque<_>>(), None)
@@ -1211,8 +1249,8 @@ mod test {
*/
let blockstore = setup_forks();
blockstore.add_tree(tr(8) / (tr(10) / (tr(11))), true, true);
blockstore.add_tree(tr(20) / (tr(22) / (tr(23))), true, true);
blockstore.add_tree(tr(8) / (tr(10) / (tr(11))), true, true, 2, Hash::default());
blockstore.add_tree(tr(20) / (tr(22) / (tr(23))), true, true, 2, Hash::default());
assert!(blockstore.orphan(8).unwrap().is_some());
blockstore
}
@@ -1234,7 +1272,7 @@ mod test {
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3) / (tr(5) / (tr(6)))));
let ledger_path = get_tmp_ledger_path!();
let blockstore = Blockstore::open(&ledger_path).unwrap();
blockstore.add_tree(forks, false, true);
blockstore.add_tree(forks, false, true, 2, Hash::default());
blockstore
}
}

View File

@@ -151,6 +151,7 @@ pub mod test {
use super::*;
use solana_ledger::{get_tmp_ledger_path, shred::Shred};
use solana_runtime::bank_utils;
use solana_sdk::hash::Hash;
use trees::tr;
#[test]
@@ -247,7 +248,13 @@ pub mod test {
repairs = vec![];
let best_overall_slot = heaviest_subtree_fork_choice.best_overall_slot();
assert_eq!(heaviest_subtree_fork_choice.best_overall_slot(), 4);
blockstore.add_tree(tr(best_overall_slot) / (tr(6) / tr(7)), true, false);
blockstore.add_tree(
tr(best_overall_slot) / (tr(6) / tr(7)),
true,
false,
2,
Hash::default(),
);
get_best_repair_shreds(
&heaviest_subtree_fork_choice,
&blockstore,
@@ -301,7 +308,7 @@ pub mod test {
// Adding incomplete children with higher weighted parents, even if
// the parents are complete should still be repaired
repairs = vec![];
blockstore.add_tree(tr(2) / (tr(8)), true, false);
blockstore.add_tree(tr(2) / (tr(8)), true, false, 2, Hash::default());
get_best_repair_shreds(
&heaviest_subtree_fork_choice,
&blockstore,
@@ -323,7 +330,7 @@ pub mod test {
let (blockstore, heaviest_subtree_fork_choice) = setup_forks();
// Add a branch to slot 2, make sure it doesn't repair child
// 4 again when the Unvisited(2) event happens
blockstore.add_tree(tr(2) / (tr(6) / tr(7)), true, false);
blockstore.add_tree(tr(2) / (tr(6) / tr(7)), true, false, 2, Hash::default());
let mut repairs = vec![];
get_best_repair_shreds(
&heaviest_subtree_fork_choice,
@@ -369,7 +376,7 @@ pub mod test {
// Adding slot 2 to ignore should not remove its unexplored children from
// the repair set
repairs = vec![];
blockstore.add_tree(tr(2) / (tr(6) / tr(7)), true, false);
blockstore.add_tree(tr(2) / (tr(6) / tr(7)), true, false, 2, Hash::default());
ignore_set.insert(2);
get_best_repair_shreds(
&heaviest_subtree_fork_choice,
@@ -421,7 +428,7 @@ pub mod test {
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3) / (tr(5))));
let ledger_path = get_tmp_ledger_path!();
let blockstore = Blockstore::open(&ledger_path).unwrap();
blockstore.add_tree(forks.clone(), false, false);
blockstore.add_tree(forks.clone(), false, false, 2, Hash::default());
(blockstore, HeaviestSubtreeForkChoice::new_from_tree(forks))
}

View File

@@ -1976,7 +1976,7 @@ pub(crate) mod tests {
genesis_utils::create_genesis_config_with_vote_accounts(
10_000,
&validator_authorized_voter_keypairs,
100,
vec![100; validator_authorized_voter_keypairs.len()],
);
let bank0 = Bank::new(&genesis_config);
@@ -2702,15 +2702,9 @@ pub(crate) mod tests {
#[test]
fn test_compute_bank_stats_confirmed() {
let node_keypair = Keypair::new();
let vote_keypair = Keypair::new();
let stake_keypair = Keypair::new();
let node_pubkey = node_keypair.pubkey();
let mut keypairs = HashMap::new();
keypairs.insert(
node_pubkey,
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
);
let vote_keypairs = ValidatorVoteKeypairs::new_rand();
let node_pubkey = vote_keypairs.node_keypair.pubkey();
let keypairs: HashMap<_, _> = vec![(node_pubkey, vote_keypairs)].into_iter().collect();
let (bank_forks, mut progress, mut heaviest_subtree_fork_choice) =
initialize_state(&keypairs, 10_000);
@@ -3029,14 +3023,8 @@ pub(crate) mod tests {
#[test]
fn test_update_slot_propagated_threshold_from_votes() {
let keypairs: HashMap<_, _> = iter::repeat_with(|| {
let node_keypair = Keypair::new();
let vote_keypair = Keypair::new();
let stake_keypair = Keypair::new();
let node_pubkey = node_keypair.pubkey();
(
node_pubkey,
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
)
let vote_keypairs = ValidatorVoteKeypairs::new_rand();
(vote_keypairs.node_keypair.pubkey(), vote_keypairs)
})
.take(10)
.collect();
@@ -3209,17 +3197,10 @@ pub(crate) mod tests {
#[test]
fn test_update_propagation_status() {
// Create genesis stakers
let node_keypair = Keypair::new();
let vote_keypair = Keypair::new();
let stake_keypair = Keypair::new();
let vote_pubkey = Arc::new(vote_keypair.pubkey());
let mut keypairs = HashMap::new();
keypairs.insert(
node_keypair.pubkey(),
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
);
let vote_keypairs = ValidatorVoteKeypairs::new_rand();
let node_pubkey = vote_keypairs.node_keypair.pubkey();
let vote_pubkey = Arc::new(vote_keypairs.vote_keypair.pubkey());
let keypairs: HashMap<_, _> = vec![(node_pubkey, vote_keypairs)].into_iter().collect();
let stake = 10_000;
let (mut bank_forks, mut progress_map, _) = initialize_state(&keypairs, stake);
@@ -3301,14 +3282,8 @@ pub(crate) mod tests {
#[test]
fn test_chain_update_propagation_status() {
let keypairs: HashMap<_, _> = iter::repeat_with(|| {
let node_keypair = Keypair::new();
let vote_keypair = Keypair::new();
let stake_keypair = Keypair::new();
let node_pubkey = node_keypair.pubkey();
(
node_pubkey,
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
)
let vote_keypairs = ValidatorVoteKeypairs::new_rand();
(vote_keypairs.node_keypair.pubkey(), vote_keypairs)
})
.take(10)
.collect();
@@ -3384,14 +3359,8 @@ pub(crate) mod tests {
fn test_chain_update_propagation_status2() {
let num_validators = 6;
let keypairs: HashMap<_, _> = iter::repeat_with(|| {
let node_keypair = Keypair::new();
let vote_keypair = Keypair::new();
let stake_keypair = Keypair::new();
let node_pubkey = node_keypair.pubkey();
(
node_pubkey,
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
)
let vote_keypairs = ValidatorVoteKeypairs::new_rand();
(vote_keypairs.node_keypair.pubkey(), vote_keypairs)
})
.take(num_validators)
.collect();

View File

@@ -195,8 +195,11 @@ impl JsonRpcRequestProcessor {
if let Some(account) = bank.get_account(pubkey) {
if account.owner == spl_token_id_v1_0() && encoding == UiAccountEncoding::JsonParsed {
response = Some(get_parsed_token_account(bank.clone(), pubkey, account));
} else if encoding == UiAccountEncoding::Binary && account.data.len() > 128 {
let message = "Encoded binary (base 58) data should be less than 128 bytes, please use Binary64 encoding.".to_string();
} else if (encoding == UiAccountEncoding::Binary
|| encoding == UiAccountEncoding::Base58)
&& account.data.len() > 128
{
let message = "Encoded binary (base 58) data should be less than 128 bytes, please use Base64 encoding.".to_string();
return Err(error::Error {
code: error::ErrorCode::InvalidRequest,
message,
@@ -847,6 +850,7 @@ impl JsonRpcRequestProcessor {
&self,
address: Pubkey,
mut before: Option<Signature>,
until: Option<Signature>,
mut limit: usize,
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>> {
if self.config.enable_rpc_transaction_history {
@@ -862,6 +866,7 @@ impl JsonRpcRequestProcessor {
address,
highest_confirmed_root,
before,
until,
limit,
)
.map_err(|err| Error::invalid_params(format!("{}", err)))?;
@@ -873,17 +878,22 @@ impl JsonRpcRequestProcessor {
before = results.last().map(|x| x.signature);
}
let mut bigtable_results = self
.runtime_handle
.block_on(
bigtable_ledger_storage.get_confirmed_signatures_for_address(
&address,
before.as_ref(),
limit,
),
)
.map_err(|err| Error::invalid_params(format!("{}", err)))?;
results.append(&mut bigtable_results)
let bigtable_results = self.runtime_handle.block_on(
bigtable_ledger_storage.get_confirmed_signatures_for_address(
&address,
before.as_ref(),
until.as_ref(),
limit,
),
);
match bigtable_results {
Ok(mut bigtable_results) => {
results.append(&mut bigtable_results);
}
Err(err) => {
warn!("{:?}", err);
}
}
}
}
@@ -1232,7 +1242,7 @@ fn check_slice_and_encoding(encoding: &UiAccountEncoding, data_slice_is_some: bo
UiAccountEncoding::JsonParsed => {
if data_slice_is_some {
let message =
"Sliced account data can only be encoded using binary (base 58) or binary64 encoding."
"Sliced account data can only be encoded using binary (base 58) or base64 encoding."
.to_string();
Err(error::Error {
code: error::ErrorCode::InvalidRequest,
@@ -1243,7 +1253,7 @@ fn check_slice_and_encoding(encoding: &UiAccountEncoding, data_slice_is_some: bo
Ok(())
}
}
UiAccountEncoding::Binary | UiAccountEncoding::Binary64 => Ok(()),
UiAccountEncoding::Binary | UiAccountEncoding::Base58 | UiAccountEncoding::Base64 => Ok(()),
}
}
@@ -1346,9 +1356,7 @@ fn get_token_program_id_and_mint(
/// program_id) and decimals
fn get_mint_owner_and_decimals(bank: &Arc<Bank>, mint: &Pubkey) -> Result<(Pubkey, u8)> {
if mint == &spl_token_v1_0_native_mint() {
// Uncomment the following once spl_token is bumped to a version that includes native_mint::DECIMALS
// Ok((spl_token_id_v1_0(), spl_token_v1_0::native_mint::DECIMALS))
Ok((spl_token_id_v1_0(), 9))
Ok((spl_token_id_v1_0(), spl_token_v1_0::native_mint::DECIMALS))
} else {
let mint_account = bank.get_account(mint).ok_or_else(|| {
Error::invalid_params("Invalid param: could not find mint".to_string())
@@ -2279,6 +2287,11 @@ impl RpcSol for RpcSolImpl {
} else {
None
};
let until = if let Some(until) = config.until {
Some(verify_signature(&until)?)
} else {
None
};
let limit = config
.limit
.unwrap_or(MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT);
@@ -2290,7 +2303,7 @@ impl RpcSol for RpcSolImpl {
)));
}
meta.get_confirmed_signatures_for_address2(address, before, limit)
meta.get_confirmed_signatures_for_address2(address, before, until, limit)
}
fn get_first_available_block(&self, meta: Self::Metadata) -> Result<Slot> {
@@ -3061,13 +3074,13 @@ pub mod tests {
"result": {
"context":{"slot":0},
"value":{
"owner": "11111111111111111111111111111111",
"lamports": 20,
"data": "",
"executable": false,
"rentEpoch": 0
},
"owner": "11111111111111111111111111111111",
"lamports": 20,
"data": "",
"executable": false,
"rentEpoch": 0
},
},
"id": 1,
});
let expected: Response =
@@ -3083,16 +3096,7 @@ pub mod tests {
bank.store_account(&address, &account);
let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}", {{"encoding":"binary64"}}]}}"#,
address
);
let res = io.handle_request_sync(&req, meta.clone());
let result: Value = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(result["result"]["value"]["data"], base64::encode(&data));
let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}", {{"encoding":"binary64", "dataSlice": {{"length": 2, "offset": 1}}}}]}}"#,
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}", {{"encoding":"base64"}}]}}"#,
address
);
let res = io.handle_request_sync(&req, meta.clone());
@@ -3100,7 +3104,19 @@ pub mod tests {
.expect("actual response deserialization");
assert_eq!(
result["result"]["value"]["data"],
base64::encode(&data[1..3]),
json!([base64::encode(&data), "base64"]),
);
let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}", {{"encoding":"base64", "dataSlice": {{"length": 2, "offset": 1}}}}]}}"#,
address
);
let res = io.handle_request_sync(&req, meta.clone());
let result: Value = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(
result["result"]["value"]["data"],
json!([base64::encode(&data[1..3]), "base64"]),
);
let req = format!(
@@ -4315,7 +4331,7 @@ pub mod tests {
for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter()
{
if let EncodedTransaction::Binary(transaction) = transaction {
if let EncodedTransaction::LegacyBinary(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

@@ -602,7 +602,7 @@ mod tests {
"lamports": 51,
"data": bs58::encode(expected_data).into_string(),
"executable": false,
"rentEpoch": 1,
"rentEpoch": 0,
},
},
"subscription": 0,
@@ -720,7 +720,7 @@ mod tests {
"lamports": 100,
"data": expected_data,
"executable": false,
"rentEpoch": 1,
"rentEpoch": 0,
},
},
"subscription": 0,
@@ -899,7 +899,7 @@ mod tests {
"lamports": 100,
"data": "",
"executable": false,
"rentEpoch": 1,
"rentEpoch": 0,
},
},
"subscription": 0,
@@ -986,11 +986,13 @@ mod tests {
BlockCommitmentCache::new_for_tests_with_blockstore(blockstore.clone()),
));
let validator_voting_keypairs: Vec<_> = (0..10)
.map(|_| ValidatorVoteKeypairs::new(Keypair::new(), Keypair::new(), Keypair::new()))
.collect();
let GenesisConfigInfo { genesis_config, .. } =
create_genesis_config_with_vote_accounts(10_000, &validator_voting_keypairs, 100);
let validator_voting_keypairs: Vec<_> =
(0..10).map(|_| ValidatorVoteKeypairs::new_rand()).collect();
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config_with_vote_accounts(
10_000,
&validator_voting_keypairs,
vec![100; validator_voting_keypairs.len()],
);
let exit = Arc::new(AtomicBool::new(false));
let bank = Bank::new(&genesis_config);
let bank_forks = BankForks::new(bank);

View File

@@ -1099,7 +1099,7 @@ pub(crate) mod tests {
"executable": false,
"lamports": 1,
"owner": "Budget1111111111111111111111111111111111111",
"rentEpoch": 1,
"rentEpoch": 0,
},
},
"subscription": 0,
@@ -1185,7 +1185,7 @@ pub(crate) mod tests {
"executable": false,
"lamports": 1,
"owner": "Budget1111111111111111111111111111111111111",
"rentEpoch": 1,
"rentEpoch": 0,
},
"pubkey": alice.pubkey().to_string(),
},
@@ -1607,7 +1607,7 @@ pub(crate) mod tests {
"executable": false,
"lamports": 1,
"owner": "Budget1111111111111111111111111111111111111",
"rentEpoch": 1,
"rentEpoch": 0,
},
},
"subscription": 0,
@@ -1641,7 +1641,7 @@ pub(crate) mod tests {
"executable": false,
"lamports": 1,
"owner": "Budget1111111111111111111111111111111111111",
"rentEpoch": 1,
"rentEpoch": 0,
},
},
"subscription": 1,

View File

@@ -849,6 +849,8 @@ impl TestValidator {
} = create_genesis_config_with_leader_ex(
mint_lamports,
&contact_info.id,
&Keypair::new(),
&Pubkey::new_rand(),
42,
bootstrap_validator_lamports,
);
@@ -865,17 +867,17 @@ impl TestValidator {
let (ledger_path, blockhash) = create_new_tmp_ledger!(&genesis_config);
let leader_voting_keypair = Arc::new(voting_keypair);
let config = ValidatorConfig {
rpc_ports: Some((node.info.rpc.port(), node.info.rpc_pubsub.port())),
..ValidatorConfig::default()
};
let vote_pubkey = voting_keypair.pubkey();
let node = Validator::new(
node,
&node_keypair,
&ledger_path,
&leader_voting_keypair.pubkey(),
vec![leader_voting_keypair.clone()],
&voting_keypair.pubkey(),
vec![Arc::new(voting_keypair)],
None,
true,
&config,
@@ -887,7 +889,7 @@ impl TestValidator {
alice: mint_keypair,
ledger_path,
genesis_hash: blockhash,
vote_pubkey: leader_voting_keypair.pubkey(),
vote_pubkey,
}
}
}

View File

@@ -1,31 +1,32 @@
// Long-running bank_forks tests
macro_rules! DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS {
($x:ident) => {
($x:ident, $y:ident, $z:ident) => {
#[allow(non_snake_case)]
mod $x {
mod $z {
use super::*;
const SNAPSHOT_VERSION: SnapshotVersion = SnapshotVersion::$x;
const OPERATING_MODE: OperatingMode = OperatingMode::$y;
#[test]
fn test_bank_forks_status_cache_snapshot_n() {
run_test_bank_forks_status_cache_snapshot_n(SNAPSHOT_VERSION)
run_test_bank_forks_status_cache_snapshot_n(SNAPSHOT_VERSION, OPERATING_MODE)
}
#[test]
fn test_bank_forks_snapshot_n() {
run_test_bank_forks_snapshot_n(SNAPSHOT_VERSION)
run_test_bank_forks_snapshot_n(SNAPSHOT_VERSION, OPERATING_MODE)
}
#[test]
fn test_concurrent_snapshot_packaging() {
run_test_concurrent_snapshot_packaging(SNAPSHOT_VERSION)
run_test_concurrent_snapshot_packaging(SNAPSHOT_VERSION, OPERATING_MODE)
}
#[test]
fn test_slots_to_snapshot() {
run_test_slots_to_snapshot(SNAPSHOT_VERSION)
run_test_slots_to_snapshot(SNAPSHOT_VERSION, OPERATING_MODE)
}
}
};
@@ -52,7 +53,7 @@ mod tests {
};
use solana_sdk::{
clock::Slot,
genesis_config::GenesisConfig,
genesis_config::{GenesisConfig, OperatingMode},
hash::hashv,
pubkey::Pubkey,
signature::{Keypair, Signer},
@@ -61,8 +62,12 @@ mod tests {
use std::{fs, path::PathBuf, sync::atomic::AtomicBool, sync::mpsc::channel, sync::Arc};
use tempfile::TempDir;
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_1_0);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_2_0);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_1_0, Development, V1_1_0_Development);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_1_0, Preview, V1_1_0_Preview);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_1_0, Stable, V1_1_0_Stable);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_2_0, Development, V1_2_0_Development);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_2_0, Preview, V1_2_0_Preview);
DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_2_0, Stable, V1_2_0_Stable);
struct SnapshotTestConfig {
accounts_dir: TempDir,
@@ -76,12 +81,14 @@ mod tests {
impl SnapshotTestConfig {
fn new(
snapshot_version: SnapshotVersion,
operating_mode: OperatingMode,
snapshot_interval_slots: u64,
) -> SnapshotTestConfig {
let accounts_dir = TempDir::new().unwrap();
let snapshot_dir = TempDir::new().unwrap();
let snapshot_output_path = TempDir::new().unwrap();
let genesis_config_info = create_genesis_config(10_000);
let mut genesis_config_info = create_genesis_config(10_000);
genesis_config_info.genesis_config.operating_mode = operating_mode;
let bank0 = Bank::new_with_paths(
&genesis_config_info.genesis_config,
vec![accounts_dir.path().to_path_buf()],
@@ -113,6 +120,7 @@ mod tests {
fn restore_from_snapshot(
old_bank_forks: &BankForks,
old_last_slot: Slot,
old_genesis_config: &GenesisConfig,
account_paths: &[PathBuf],
) {
let (snapshot_path, snapshot_package_output_path) = old_bank_forks
@@ -137,7 +145,7 @@ mod tests {
&CompressionType::Bzip2,
),
CompressionType::Bzip2,
&GenesisConfig::default(),
old_genesis_config,
)
.unwrap();
@@ -161,6 +169,7 @@ mod tests {
// `last_slot` bank
fn run_bank_forks_snapshot_n<F>(
snapshot_version: SnapshotVersion,
operating_mode: OperatingMode,
last_slot: Slot,
f: F,
set_root_interval: u64,
@@ -169,10 +178,9 @@ mod tests {
{
solana_logger::setup();
// Set up snapshotting config
let mut snapshot_test_config = SnapshotTestConfig::new(snapshot_version, 1);
let mut snapshot_test_config = SnapshotTestConfig::new(snapshot_version, operating_mode, 1);
let bank_forks = &mut snapshot_test_config.bank_forks;
let accounts_dir = &snapshot_test_config.accounts_dir;
let mint_keypair = &snapshot_test_config.genesis_config_info.mint_keypair;
let (s, _r) = channel();
@@ -188,6 +196,7 @@ mod tests {
bank_forks.set_root(bank.slot(), &sender, None);
}
}
// Generate a snapshot package for last bank
let last_bank = bank_forks.get(last_slot).unwrap();
let snapshot_config = &snapshot_test_config.snapshot_config;
@@ -206,17 +215,23 @@ mod tests {
snapshot_version,
)
.unwrap();
snapshot_utils::archive_snapshot_package(&snapshot_package).unwrap();
restore_from_snapshot(bank_forks, last_slot, &[accounts_dir.path().to_path_buf()]);
// Restore bank from snapshot
let account_paths = &[snapshot_test_config.accounts_dir.path().to_path_buf()];
let genesis_config = &snapshot_test_config.genesis_config_info.genesis_config;
restore_from_snapshot(bank_forks, last_slot, genesis_config, account_paths);
}
fn run_test_bank_forks_snapshot_n(snapshot_version: SnapshotVersion) {
fn run_test_bank_forks_snapshot_n(
snapshot_version: SnapshotVersion,
operating_mode: OperatingMode,
) {
// create banks upto slot 4 and create 1 new account in each bank. test that bank 4 snapshots
// and restores correctly
run_bank_forks_snapshot_n(
snapshot_version,
operating_mode,
4,
|bank, mint_keypair| {
let key1 = Keypair::new().pubkey();
@@ -247,11 +262,14 @@ mod tests {
}
}
fn run_test_concurrent_snapshot_packaging(snapshot_version: SnapshotVersion) {
fn run_test_concurrent_snapshot_packaging(
snapshot_version: SnapshotVersion,
operating_mode: OperatingMode,
) {
solana_logger::setup();
// Set up snapshotting config
let mut snapshot_test_config = SnapshotTestConfig::new(snapshot_version, 1);
let mut snapshot_test_config = SnapshotTestConfig::new(snapshot_version, operating_mode, 1);
let bank_forks = &mut snapshot_test_config.bank_forks;
let accounts_dir = &snapshot_test_config.accounts_dir;
@@ -396,7 +414,10 @@ mod tests {
);
}
fn run_test_slots_to_snapshot(snapshot_version: SnapshotVersion) {
fn run_test_slots_to_snapshot(
snapshot_version: SnapshotVersion,
operating_mode: OperatingMode,
) {
solana_logger::setup();
let num_set_roots = MAX_CACHE_ENTRIES * 2;
@@ -405,6 +426,7 @@ mod tests {
// Make sure this test never clears bank.slots_since_snapshot
let mut snapshot_test_config = SnapshotTestConfig::new(
snapshot_version,
operating_mode,
(*add_root_interval * num_set_roots * 2) as u64,
);
let mut current_bank = snapshot_test_config.bank_forks[0].clone();
@@ -438,7 +460,10 @@ mod tests {
}
}
fn run_test_bank_forks_status_cache_snapshot_n(snapshot_version: SnapshotVersion) {
fn run_test_bank_forks_status_cache_snapshot_n(
snapshot_version: SnapshotVersion,
operating_mode: OperatingMode,
) {
// create banks upto slot (MAX_CACHE_ENTRIES * 2) + 1 while transferring 1 lamport into 2 different accounts each time
// this is done to ensure the AccountStorageEntries keep getting cleaned up as the root moves
// ahead. Also tests the status_cache purge and status cache snapshotting.
@@ -448,6 +473,7 @@ mod tests {
for set_root_interval in &[1, 4] {
run_bank_forks_snapshot_n(
snapshot_version,
operating_mode,
(MAX_CACHE_ENTRIES * 2 + 1) as u64,
|bank, mint_keypair| {
let tx = system_transaction::transfer(

View File

@@ -29,13 +29,12 @@ fn test_node(exit: &Arc<AtomicBool>) -> (Arc<ClusterInfo>, GossipService, UdpSoc
}
fn test_node_with_bank(
node_keypair: Keypair,
node_keypair: Arc<Keypair>,
exit: &Arc<AtomicBool>,
bank_forks: Arc<RwLock<BankForks>>,
) -> (Arc<ClusterInfo>, GossipService, UdpSocket) {
let keypair = Arc::new(node_keypair);
let mut test_node = Node::new_localhost_with_pubkey(&keypair.pubkey());
let cluster_info = Arc::new(ClusterInfo::new(test_node.info.clone(), keypair));
let mut test_node = Node::new_localhost_with_pubkey(&node_keypair.pubkey());
let cluster_info = Arc::new(ClusterInfo::new(test_node.info.clone(), node_keypair));
let gossip_service = GossipService::new(
&cluster_info,
Some(bank_forks),
@@ -224,13 +223,19 @@ pub fn cluster_info_scale() {
let vote_keypairs: Vec<_> = (0..num_nodes)
.map(|_| ValidatorVoteKeypairs::new_rand())
.collect();
let genesis_config_info = create_genesis_config_with_vote_accounts(10_000, &vote_keypairs, 100);
let genesis_config_info = create_genesis_config_with_vote_accounts(
10_000,
&vote_keypairs,
vec![100; vote_keypairs.len()],
);
let bank0 = Bank::new(&genesis_config_info.genesis_config);
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0)));
let nodes: Vec<_> = vote_keypairs
.into_iter()
.map(|keypairs| test_node_with_bank(keypairs.node_keypair, &exit, bank_forks.clone()))
.map(|keypairs| {
test_node_with_bank(Arc::new(keypairs.node_keypair), &exit, bank_forks.clone())
})
.collect();
let ci0 = nodes[0].0.my_contact_info();
for node in &nodes[1..] {

View File

@@ -103,7 +103,7 @@ fn test_rpc_send_tx() {
use solana_account_decoder::UiAccountEncoding;
use solana_client::rpc_config::RpcAccountInfoConfig;
let config = RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Binary64),
encoding: Some(UiAccountEncoding::Base64),
commitment: None,
data_slice: None,
};

View File

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

View File

@@ -157,9 +157,9 @@ Returns all information associated with the account of provided Pubkey
- `<string>` - Pubkey of account to query, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary", "binary64", or jsonParsed". If parameter not provided, the default encoding is "binary". "binary" is base-58 encoded and limited to Account data of less than 128 bytes. "binary64" will return base64 encoded data for Account data of any size.
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "binary" or "binary64" encoding.
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", or jsonParsed". "base58" is limited to Account data of less than 128 bytes. "base64" will return base64 encoded data for Account data of any size.
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to base64 encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
#### Results:
@@ -169,7 +169,7 @@ The result will be an RpcResponse JSON object with `value` equal to:
- `<object>` - otherwise, a JSON object containing:
- `lamports: <u64>`, number of lamports assigned to this account, as a u64
- `owner: <string>`, base-58 encoded Pubkey of the program this account has been assigned to
- `data: <string|object>`, data associated with the account, either as base-58 encoded binary data or JSON format `{<program>: <state>}`, depending on encoding parameter
- `data: <[string, encoding]|object>`, data associated with the account, either as encoded binary data or JSON format `{<program>: <state>}`, depending on encoding parameter
- `executable: <bool>`, boolean indicating if the account contains a program \(and is strictly read-only\)
- `rentEpoch: <u64>`, the epoch at which this account will next owe rent, as u64
@@ -177,10 +177,10 @@ The result will be an RpcResponse JSON object with `value` equal to:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["4fYNw3dojWmQ4dXtSGE9epjRGy9pFSx62YypT7avPYvA"]}' http://localhost:8899
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg",{"encoding": "base58"}]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"data":"11116bv5nS2h3y12kD1yUKeMZvGcKLSjQgX6BeV7u1FrjeJcKfsHRTPuR3oZ1EioKtYGiYxpxMG5vpbZLsbcBYBEmZZcMKaSoGx9JZeAuWf","executable":false,"lamports":1000000000,"owner":"11111111111111111111111111111111","rentEpoch":2}},"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"data":["11116bv5nS2h3y12kD1yUKeMZvGcKLSjQgX6BeV7u1FrjeJcKfsHRTPuR3oZ1EioKtYGiYxpxMG5vpbZLsbcBYBEmZZcMKaSoGx9JZeAuWf","base58"],"executable":false,"lamports":1000000000,"owner":"11111111111111111111111111111111","rentEpoch":2}},"id":1}
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["4fYNw3dojWmQ4dXtSGE9epjRGy9pFSx62YypT7avPYvA",{"encoding":"json"}]}' http://localhost:8899
@@ -307,7 +307,7 @@ Returns identity and transaction information about a confirmed block in the ledg
#### Parameters:
- `<u64>` - slot, as u64 integer
- `<string>` - (optional) encoding for each returned Transaction, either "json", "jsonParsed", or "binary". If parameter not provided, the default encoding is JSON. **jsonParsed encoding is UNSTABLE**
- `<string>` - encoding for each returned Transaction, either "json", "jsonParsed", "base58" (*slow*), or "base64". If parameter not provided, the default encoding is JSON. **jsonParsed encoding is UNSTABLE**
Parsed-JSON encoding attempts to use program-specific instruction parsers to return more human-readable and explicit data in the `transaction.message.instructions` list. If parsed-JSON is requested but a parser cannot be found, the instruction falls back to regular JSON encoding (`accounts`, `data`, and `programIdIndex` fields).
#### Results:
@@ -320,7 +320,7 @@ 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; if the parent block is not available due to ledger cleanup, this field will return "11111111111111111111111111111111"
- `parentSlot: <u64>` - the slot index of this block's parent
- `transactions: <array>` - an array of JSON objects containing:
- `transaction: <object|string>` - [Transaction](#transaction-structure) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
- `transaction: <object|[string,encoding]>` - [Transaction](#transaction-structure) object, either in JSON format or encoded binary data, depending on encoding parameter
- `meta: <object>` - transaction status metadata object, containing `null` or:
- `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
- `fee: <u64>` - fee this transaction was charged, as u64 integer
@@ -341,13 +341,13 @@ The result field will be an object with the following fields:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "json"]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":{"message":{"accountKeys":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC","39UAy8hsoYPywGPGdmun747omSr79zLSjqvPJN3zetoH","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":2},"instructions":[{"accounts":[1,2,3],"data":"29z5mr1JoRmJYQ6ynmk3pf31cGFRziAF1M3mT3L6sFXf5cKLdkEaMXMT8AqLpD4CpcupHmuMEmtZHpomrwfdZetSomNy3d","programIdIndex":4}],"recentBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA"},"signatures":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4vANMjSKiwEchGSXwVrQkwHnmsbKQmy9vdrsYxWdCup1bLsFzX8gKrFTSVDCZCae2dbxJB9mPNhqB2sD1vvr4sAD"]},"meta":{"err":null,"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1}
{"jsonrpc":"2.0","result":{"blockTime":null,"blockhash":"3Eq21vXNB5s86c62bVuUfTeaMif1N2kUqRPBmGRJhyTA","parentSlot":429,"previousBlockhash":"mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B","rewards":[],"transactions":[{"meta":{"err":null,"fee":5000,"postBalances":[499998932500,26858640,1,1,1],"preBalances":[499998937500,26858640,1,1,1],"status":{"Ok":null}},"transaction":{"message":{"accountKeys":["3UVYmECPPMZSCqWKfENfuoTv51fTDTWicX9xmBD2euKe","AjozzgE83A3x1sHNUR64hfH7zaEBWeMaFuAN9kQgujrc","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":1},"instructions":[{"accounts":[1,2,3,0],"data":"37u9WtQpcm6ULa3WRQHmj49EPs4if7o9f1jSRVZpm2dvihR9C8jY4NqEwXUbLwx15HBSNcP1","programIdIndex":4}],"recentBlockhash":"mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B"},"signatures":["2nBhEBYYvfaAe16UMNqRHre4YNSskvuYgx3M6E4JP1oDYvZEJHvoPzyUidNgNX5r9sTyN1J9UxtbCXy2rqYcuyuv"]}}]},"id":1}
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "binary"]}' localhost:8899
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "base64"]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":"81UZJt4dh4Do66jDhrgkQudS8J2N6iG3jaVav7gJrqJSFY4Ug53iA9JFJZh2gxKWcaFdLJwhHx9mRdg9JwDAWB4ywiu5154CRwXV4FMdnPLg7bhxRLwhhYaLsVgMF5AyNRcTzjCVoBvqFgDU7P8VEKDEiMvD3qxzm1pLZVxDG1LTQpT3Dz4Uviv4KQbFQNuC22KupBoyHFB7Zh6KFdMqux4M9PvhoqcoJsJKwXjWpKu7xmEKnnrSbfLadkgjBmmjhW3fdTrFvnhQdTkhtdJxUL1xS9GMuJQer8YgSKNtUXB1eXZQwXU8bU2BjYkZE6Q5Xww8hu9Z4E4Mo4QsooVtHoP6BM3NKw8zjVbWfoCQqxTrwuSzrNCWCWt58C24LHecH67CTt2uXbYSviixvrYkK7A3t68BxTJcF1dXJitEPTFe2ceTkauLJqrJgnER4iUrsjr26T8YgWvpY9wkkWFSviQW6wV5RASTCUasVEcrDiaKj8EQMkgyDoe9HyKitSVg67vMWJFpUXpQobseWJUs5FTWWzmfHmFp8FZ","meta":{"err":null,"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1}
{"jsonrpc":"2.0","result":{"blockTime":null,"blockhash":"3Eq21vXNB5s86c62bVuUfTeaMif1N2kUqRPBmGRJhyTA","parentSlot":429,"previousBlockhash":"mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B","rewards":[],"transactions":[{"meta":{"err":null,"fee":5000,"postBalances":[499998932500,26858640,1,1,1],"preBalances":[499998937500,26858640,1,1,1],"status":{"Ok":null}},"transaction":["AVj7dxHlQ9IrvdYVIjuiRFs1jLaDMHixgrv+qtHBwz51L4/ImLZhszwiyEJDIp7xeBSpm/TX5B7mYzxa+fPOMw0BAAMFJMJVqLw+hJYheizSoYlLm53KzgT82cDVmazarqQKG2GQsLgiqktA+a+FDR4/7xnDX7rsusMwryYVUdixfz1B1Qan1RcZLwqvxvJl4/t3zHragsUp0L47E24tAFUgAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAHYUgdNXR0u3xNdiTr072z2DVec9EQQ/wNo1OAAAAAAAtxOUhPBp2WSjUNJEgfvy70BbxI00fZyEPvFHNfxrtEAQQEAQIDADUCAAAAAQAAAAAAAACtAQAAAAAAAAdUE18R96XTJCe+YfRfUp6WP+YKCy/72ucOL8AoBFSpAA==","base64"]}]},"id":1}
```
#### Transaction Structure
@@ -465,14 +465,14 @@ Returns transaction details for a confirmed transaction
- `<string>` - transaction signature as base-58 encoded string
N encoding attempts to use program-specific instruction parsers to return more human-readable and explicit data in the `transaction.message.instructions` list. If parsed-JSON is requested but a parser cannot be found, the instruction falls back to regular JSON encoding (`accounts`, `data`, and `programIdIndex` fields).
- `<string>` - (optional) encoding for the returned Transaction, either "json", "jsonParsed", or "binary". **jsonParsed encoding is UNSTABLE**
- `<string>` - (optional) encoding for the returned Transaction, either "json", "jsonParsed", "base58" (*slow*), or "base64". If parameter not provided, the default encoding is JSON. **jsonParsed encoding is UNSTABLE**
#### Results:
- `<null>` - if transaction is not found or not confirmed
- `<object>` - if transaction is confirmed, an object with the following fields:
- `slot: <u64>` - the slot this transaction was processed in
- `transaction: <object|string>` - [Transaction](#transaction-structure) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
- `transaction: <object|[string,encoding]>` - [Transaction](#transaction-structure) object, either in JSON format or encoded binary data, depending on encoding parameter
- `meta: <object | null>` - transaction status metadata object:
- `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
- `fee: <u64>` - fee this transaction was charged, as u64 integer
@@ -486,16 +486,16 @@ N encoding attempts to use program-specific instruction parsers to return more h
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby", "json"]}' localhost:8899
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["2nBhEBYYvfaAe16UMNqRHre4YNSskvuYgx3M6E4JP1oDYvZEJHvoPzyUidNgNX5r9sTyN1J9UxtbCXy2rqYcuyuv", "json"]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{"slot":430,"transaction":{"message":{"accountKeys":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC","39UAy8hsoYPywGPGdmun747omSr79zLSjqvPJN3zetoH","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":2},"instructions":[{"accounts":[1,2,3],"data":"29z5mr1JoRmJYQ6ynmk3pf31cGFRziAF1M3mT3L6sFXf5cKLdkEaMXMT8AqLpD4CpcupHmuMEmtZHpomrwfdZetSomNy3d","programIdIndex":4}],"recentBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA"},"signatures":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4vANMjSKiwEchGSXwVrQkwHnmsbKQmy9vdrsYxWdCup1bLsFzX8gKrFTSVDCZCae2dbxJB9mPNhqB2sD1vvr4sAD"]},"meta":{"err":null,"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}},"id":1}
{"jsonrpc":"2.0","result":{"meta":{"err":null,"fee":5000,"postBalances":[499998932500,26858640,1,1,1],"preBalances":[499998937500,26858640,1,1,1],"status":{"Ok":null}},"slot":430,"transaction":{"message":{"accountKeys":["3UVYmECPPMZSCqWKfENfuoTv51fTDTWicX9xmBD2euKe","AjozzgE83A3x1sHNUR64hfH7zaEBWeMaFuAN9kQgujrc","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":1},"instructions":[{"accounts":[1,2,3,0],"data":"37u9WtQpcm6ULa3WRQHmj49EPs4if7o9f1jSRVZpm2dvihR9C8jY4NqEwXUbLwx15HBSNcP1","programIdIndex":4}],"recentBlockhash":"mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B"},"signatures":["2nBhEBYYvfaAe16UMNqRHre4YNSskvuYgx3M6E4JP1oDYvZEJHvoPzyUidNgNX5r9sTyN1J9UxtbCXy2rqYcuyuv"]}},"id":1}
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby", "binary"]}' localhost:8899
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["2nBhEBYYvfaAe16UMNqRHre4YNSskvuYgx3M6E4JP1oDYvZEJHvoPzyUidNgNX5r9sTyN1J9UxtbCXy2rqYcuyuv", "base64"]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{"slot":430,"transaction":"81UZJt4dh4Do66jDhrgkQudS8J2N6iG3jaVav7gJrqJSFY4Ug53iA9JFJZh2gxKWcaFdLJwhHx9mRdg9JwDAWB4ywiu5154CRwXV4FMdnPLg7bhxRLwhhYaLsVgMF5AyNRcTzjCVoBvqFgDU7P8VEKDEiMvD3qxzm1pLZVxDG1LTQpT3Dz4Uviv4KQbFQNuC22KupBoyHFB7Zh6KFdMqux4M9PvhoqcoJsJKwXjWpKu7xmEKnnrSbfLadkgjBmmjhW3fdTrFvnhQdTkhtdJxUL1xS9GMuJQer8YgSKNtUXB1eXZQwXU8bU2BjYkZE6Q5Xww8hu9Z4E4Mo4QsooVtHoP6BM3NKw8zjVbWfoCQqxTrwuSzrNCWCWt58C24LHecH67CTt2uXbYSviixvrYkK7A3t68BxTJcF1dXJitEPTFe2ceTkauLJqrJgnER4iUrsjr26T8YgWvpY9wkkWFSviQW6wV5RASTCUasVEcrDiaKj8EQMkgyDoe9HyKitSVg67vMWJFpUXpQobseWJUs5FTWWzmfHmFp8FZ","meta":{"err":null,"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}},"id":1}
{"jsonrpc":"2.0","result":{"meta":{"err":null,"fee":5000,"postBalances":[499998932500,26858640,1,1,1],"preBalances":[499998937500,26858640,1,1,1],"status":{"Ok":null}},"slot":430,"transaction":["AVj7dxHlQ9IrvdYVIjuiRFs1jLaDMHixgrv+qtHBwz51L4/ImLZhszwiyEJDIp7xeBSpm/TX5B7mYzxa+fPOMw0BAAMFJMJVqLw+hJYheizSoYlLm53KzgT82cDVmazarqQKG2GQsLgiqktA+a+FDR4/7xnDX7rsusMwryYVUdixfz1B1Qan1RcZLwqvxvJl4/t3zHragsUp0L47E24tAFUgAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAHYUgdNXR0u3xNdiTr072z2DVec9EQQ/wNo1OAAAAAAAtxOUhPBp2WSjUNJEgfvy70BbxI00fZyEPvFHNfxrtEAQQEAQIDADUCAAAAAQAAAAAAAACtAQAAAAAAAAdUE18R96XTJCe+YfRfUp6WP+YKCy/72ucOL8AoBFSpAA==","base64"]},"id":1}
```
### getEpochInfo
@@ -845,9 +845,9 @@ Returns all accounts owned by the provided program Pubkey
- `<string>` - Pubkey of program, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "binary" or "binary64" encoding.
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed".
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to base64 encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
- (optional) `filters: <array>` - filter results using various [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results
##### Filters:
@@ -865,7 +865,7 @@ The result field will be an array of JSON objects, which will contain:
- `account: <object>` - a JSON object, with the following sub fields:
- `lamports: <u64>`, number of lamports assigned to this account, as a u64
- `owner: <string>`, base-58 encoded Pubkey of the program this account has been assigned to
`data: <string|object>`, data associated with the account, either as base-58 encoded binary data or JSON format `{<program>: <state>}`, depending on encoding parameter
`data: <[string,encoding]|object>`, data associated with the account, either as encoded binary data or JSON format `{<program>: <state>}`, depending on encoding parameter
- `executable: <bool>`, boolean indicating if the account contains a program \(and is strictly read-only\)
- `rentEpoch: <u64>`, the epoch at which this account will next owe rent, as u64
@@ -1100,9 +1100,9 @@ Returns all SPL Token accounts by approved Delegate. **UNSTABLE**
* `programId: <string>` - Pubkey of the Token program ID that owns the accounts, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed".
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "binary" or "binary64" encoding.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
#### Results:
@@ -1112,7 +1112,7 @@ The result will be an RpcResponse JSON object with `value` equal to an array of
- `account: <object>` - a JSON object, with the following sub fields:
- `lamports: <u64>`, number of lamports assigned to this account, as a u64
- `owner: <string>`, base-58 encoded Pubkey of the program this account has been assigned to
- `data: <object>`, Token state data associated with the account, either as base-58 encoded binary data or in JSON format `{<program>: <state>}`
- `data: <object>`, Token state data associated with the account, either as encoded binary data or in JSON format `{<program>: <state>}`
- `executable: <bool>`, boolean indicating if the account contains a program \(and is strictly read-only\)
- `rentEpoch: <u64>`, the epoch at which this account will next owe rent, as u64
@@ -1137,9 +1137,9 @@ Returns all SPL Token accounts by token owner. **UNSTABLE**
* `programId: <string>` - Pubkey of the Token program ID that owns the accounts, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed".
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "binary" or "binary64" encoding.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
#### Results:
@@ -1149,7 +1149,7 @@ The result will be an RpcResponse JSON object with `value` equal to an array of
- `account: <object>` - a JSON object, with the following sub fields:
- `lamports: <u64>`, number of lamports assigned to this account, as a u64
- `owner: <string>`, base-58 encoded Pubkey of the program this account has been assigned to
- `data: <object>`, Token state data associated with the account, either as base-58 encoded binary data or in JSON format `{<program>: <state>}`
- `data: <object>`, Token state data associated with the account, either as encoded binary data or in JSON format `{<program>: <state>}`
- `executable: <bool>`, boolean indicating if the account contains a program \(and is strictly read-only\)
- `rentEpoch: <u64>`, the epoch at which this account will next owe rent, as u64
@@ -1257,7 +1257,7 @@ The result field will be a JSON object with the following fields:
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"solana-core": "1.2.22"},"id":1}
{"jsonrpc":"2.0","result":{"solana-core": "1.2.26"},"id":1}
```
### getVoteAccounts
@@ -1457,7 +1457,7 @@ Subscribe to an account to receive notifications when the lamports or data for a
- `<string>` - account Pubkey, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed".
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
#### Results:
@@ -1468,9 +1468,9 @@ Subscribe to an account to receive notifications when the lamports or data for a
```bash
// Request
{"jsonrpc":"2.0", "id":1, "method":"accountSubscribe", "params":["CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12"]}
{"jsonrpc":"2.0", "id":1, "method":"accountSubscribe", "params":["CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12", {"encoding":"base58"}]}
{"jsonrpc":"2.0", "id":1, "method":"accountSubscribe", "params":["CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12", {"commitment": "single"}]}
{"jsonrpc":"2.0", "id":1, "method":"accountSubscribe", "params":["CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12", {"encoding":"base64", "commitment": "single"}]}
{"jsonrpc":"2.0", "id":1, "method":"accountSubscribe", "params":["CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12", {"encoding":"jsonParsed"}]}
@@ -1481,7 +1481,7 @@ Subscribe to an account to receive notifications when the lamports or data for a
#### Notification Format:
```bash
// Binary encoding
// Base58 encoding
{
"jsonrpc": "2.0",
"method": "accountNotification",
@@ -1491,7 +1491,7 @@ Subscribe to an account to receive notifications when the lamports or data for a
"slot": 5199307
},
"value": {
"data": "11116bv5nS2h3y12kD1yUKeMZvGcKLSjQgX6BeV7u1FrjeJcKfsHPXHRDEHrBesJhZyqnnq9qJeUuF7WHxiuLuL5twc38w2TXNLxnDbjmuR",
"data": ["11116bv5nS2h3y12kD1yUKeMZvGcKLSjQgX6BeV7u1FrjeJcKfsHPXHRDEHrBesJhZyqnnq9qJeUuF7WHxiuLuL5twc38w2TXNLxnDbjmuR", "base58"],
"executable": false,
"lamports": 33594,
"owner": "11111111111111111111111111111111",
@@ -1567,8 +1567,8 @@ Subscribe to a program to receive notifications when the lamports or data for a
- `<string>` - program_id Pubkey, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed".
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to base64 encoding, detectable when the `data` field is type `<string>`. **jsonParsed encoding is UNSTABLE**
- (optional) `filters: <array>` - filter results using various [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results
#### Results:
@@ -1579,13 +1579,11 @@ Subscribe to a program to receive notifications when the lamports or data for a
```bash
// Request
{"jsonrpc":"2.0", "id":1, "method":"programSubscribe", "params":["11111111111111111111111111111111"]}
{"jsonrpc":"2.0", "id":1, "method":"programSubscribe", "params":["11111111111111111111111111111111", {"commitment": "single"}]}
{"jsonrpc":"2.0", "id":1, "method":"programSubscribe", "params":["11111111111111111111111111111111", {"encoding":"base64", "commitment": "single"}]}
{"jsonrpc":"2.0", "id":1, "method":"programSubscribe", "params":["11111111111111111111111111111111", {"encoding":"jsonParsed"}]}
{"jsonrpc":"2.0", "id":1, "method":"programSubscribe", "params":["11111111111111111111111111111111", {"filters":[{"dataSize":80}]}]}
{"jsonrpc":"2.0", "id":1, "method":"programSubscribe", "params":["11111111111111111111111111111111", {"encoding":"base64", "filters":[{"dataSize":80}]}]}
// Result
{"jsonrpc": "2.0","result": 24040,"id": 1}
@@ -1594,7 +1592,7 @@ Subscribe to a program to receive notifications when the lamports or data for a
#### Notification Format:
```bash
// Binary encoding
// Base58 encoding
{
"jsonrpc": "2.0",
"method": "programNotification",
@@ -1606,7 +1604,7 @@ Subscribe to a program to receive notifications when the lamports or data for a
"value": {
"pubkey": "H4vnBqifaSACnKa7acsxstsY1iV1bvJNxsCY7enrd1hq"
"account": {
"data": "11116bv5nS2h3y12kD1yUKeMZvGcKLSjQgX6BeV7u1FrjeJcKfsHPXHRDEHrBesJhZyqnnq9qJeUuF7WHxiuLuL5twc38w2TXNLxnDbjmuR",
"data": ["11116bv5nS2h3y12kD1yUKeMZvGcKLSjQgX6BeV7u1FrjeJcKfsHPXHRDEHrBesJhZyqnnq9qJeUuF7WHxiuLuL5twc38w2TXNLxnDbjmuR", "base58"],
"executable": false,
"lamports": 33594,
"owner": "11111111111111111111111111111111",
@@ -1686,8 +1684,6 @@ Subscribe to a transaction signature to receive notification when the transactio
- `<string>` - Transaction Signature, as base-58 encoded string
- `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
Default: 0, Max: `MAX_LOCKOUT_HISTORY` \(greater integers rounded down\)
#### Results:
- `integer` - subscription id \(needed to unsubscribe\)

View File

@@ -18,17 +18,17 @@ On the contrary, rent collection isn't applied to accounts that are directly man
- The distribution of rent collection itself (Otherwise, it may cause recursive rent collection handling)
- The distribution of staking rewards at the start of every epoch (To reduce as much as processing spike at the start of new epoch)
- The distribution of transaction fee at the end of every epoch
- The distribution of transaction fee at the end of every slot
Even if those processes are out of scope of rent collection, all of manipulated accounts will eventually be handled by the \(2\) mechanism.
## Actual processing of collecting rent
Rent is due for one epoch's worth of time, and accounts always have `Account::rent_epoch` of `current_epoch + 1`.
Rent is due for one epoch's worth of time, and accounts have `Account::rent_epoch` of `current_epoch` or `current_epoch + 1` depending on the rent regime.
If the account is in the exempt regime, `Account::rent_epoch` is simply pushed to `current_epoch + 1`.
If the account is in the exempt regime, `Account::rent_epoch` is simply updated to `current_epoch`.
If the account is non-exempt, the difference between the next epoch and `Account::rent_epoch` is used to calculate the amount of rent owed by this account \(via `Rent::due()`\). Any fractional lamports of the calculation are truncated. Rent due is deducted from `Account::lamports` and `Account::rent_epoch` is updated to the next epoch. If the amount of rent due is less than one lamport, no changes are made to the account.
If the account is non-exempt, the difference between the next epoch and `Account::rent_epoch` is used to calculate the amount of rent owed by this account \(via `Rent::due()`\). Any fractional lamports of the calculation are truncated. Rent due is deducted from `Account::lamports` and `Account::rent_epoch` is updated to `current_epoch + 1` (= next epoch). If the amount of rent due is less than one lamport, no changes are made to the account.
Accounts whose balance is insufficient to satisfy the rent that would be due simply fail to load.

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
use clap::{crate_description, crate_name, App, Arg};
use solana_clap_utils::input_parsers::{lamports_of_sol, value_of};
use solana_faucet::{
faucet::{run_faucet, Faucet, FAUCET_PORT},
socketaddr,
@@ -34,36 +35,36 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.help("Time slice over which to limit requests to faucet"),
)
.arg(
Arg::with_name("cap")
.long("cap")
Arg::with_name("per_time_cap")
.long("per-time-cap")
.alias("cap")
.value_name("NUM")
.takes_value(true)
.help("Request limit for time slice"),
.help("Request limit for time slice, in SOL"),
)
.arg(
Arg::with_name("per_request_cap")
.long("per-request-cap")
.value_name("NUM")
.takes_value(true)
.help("Request limit for a single request, in SOL"),
)
.get_matches();
let mint_keypair = read_keypair_file(matches.value_of("keypair").unwrap())
.expect("failed to read client keypair");
let time_slice: Option<u64>;
if let Some(secs) = matches.value_of("slice") {
time_slice = Some(secs.to_string().parse().expect("failed to parse slice"));
} else {
time_slice = None;
}
let request_cap: Option<u64>;
if let Some(c) = matches.value_of("cap") {
request_cap = Some(c.to_string().parse().expect("failed to parse cap"));
} else {
request_cap = None;
}
let time_slice = value_of(&matches, "slice");
let per_time_cap = lamports_of_sol(&matches, "per_time_cap");
let per_request_cap = lamports_of_sol(&matches, "per_request_cap");
let faucet_addr = socketaddr!(0, FAUCET_PORT);
let faucet = Arc::new(Mutex::new(Faucet::new(
mint_keypair,
time_slice,
request_cap,
per_time_cap,
per_request_cap,
)));
let faucet1 = faucet.clone();

View File

@@ -62,7 +62,8 @@ pub struct Faucet {
mint_keypair: Keypair,
ip_cache: Vec<IpAddr>,
pub time_slice: Duration,
request_cap: u64,
per_time_cap: u64,
per_request_cap: Option<u64>,
pub request_current: u64,
}
@@ -70,27 +71,23 @@ impl Faucet {
pub fn new(
mint_keypair: Keypair,
time_input: Option<u64>,
request_cap_input: Option<u64>,
per_time_cap: Option<u64>,
per_request_cap: Option<u64>,
) -> Faucet {
let time_slice = match time_input {
Some(time) => Duration::new(time, 0),
None => Duration::new(TIME_SLICE, 0),
};
let request_cap = match request_cap_input {
Some(cap) => cap,
None => REQUEST_CAP,
};
let time_slice = Duration::new(time_input.unwrap_or(TIME_SLICE), 0);
let per_time_cap = per_time_cap.unwrap_or(REQUEST_CAP);
Faucet {
mint_keypair,
ip_cache: Vec::new(),
time_slice,
request_cap,
per_time_cap,
per_request_cap,
request_current: 0,
}
}
pub fn check_request_limit(&mut self, request_amount: u64) -> bool {
(self.request_current + request_amount) <= self.request_cap
pub fn check_time_request_limit(&mut self, request_amount: u64) -> bool {
(self.request_current + request_amount) <= self.per_time_cap
}
pub fn clear_request_count(&mut self) {
@@ -116,7 +113,15 @@ impl Faucet {
to,
blockhash,
} => {
if self.check_request_limit(lamports) {
if let Some(cap) = self.per_request_cap {
if lamports > cap {
return Err(Error::new(
ErrorKind::Other,
format!("request too large; req: {} cap: {}", lamports, cap),
));
}
}
if self.check_time_request_limit(lamports) {
self.request_current += lamports;
datapoint_info!(
"faucet-airdrop",
@@ -135,7 +140,7 @@ impl Faucet {
ErrorKind::Other,
format!(
"token limit reached; req: {} current: {} cap: {}",
lamports, self.request_current, self.request_cap
lamports, self.request_current, self.per_time_cap
),
))
}
@@ -248,14 +253,15 @@ pub fn request_airdrop_transaction(
pub fn run_local_faucet(
mint_keypair: Keypair,
sender: Sender<SocketAddr>,
request_cap_input: Option<u64>,
per_time_cap: Option<u64>,
) {
thread::spawn(move || {
let faucet_addr = socketaddr!(0, 0);
let faucet = Arc::new(Mutex::new(Faucet::new(
mint_keypair,
None,
request_cap_input,
per_time_cap,
None,
)));
run_faucet(faucet, faucet_addr, Some(sender));
});
@@ -312,18 +318,18 @@ mod tests {
use std::time::Duration;
#[test]
fn test_check_request_limit() {
fn test_check_time_request_limit() {
let keypair = Keypair::new();
let mut faucet = Faucet::new(keypair, None, Some(3));
assert!(faucet.check_request_limit(1));
let mut faucet = Faucet::new(keypair, None, Some(3), None);
assert!(faucet.check_time_request_limit(1));
faucet.request_current = 3;
assert!(!faucet.check_request_limit(1));
assert!(!faucet.check_time_request_limit(1));
}
#[test]
fn test_clear_request_count() {
let keypair = Keypair::new();
let mut faucet = Faucet::new(keypair, None, None);
let mut faucet = Faucet::new(keypair, None, None, None);
faucet.request_current += 256;
assert_eq!(faucet.request_current, 256);
faucet.clear_request_count();
@@ -333,7 +339,7 @@ mod tests {
#[test]
fn test_add_ip_to_cache() {
let keypair = Keypair::new();
let mut faucet = Faucet::new(keypair, None, None);
let mut faucet = Faucet::new(keypair, None, None, None);
let ip = "127.0.0.1".parse().expect("create IpAddr from string");
assert_eq!(faucet.ip_cache.len(), 0);
faucet.add_ip_to_cache(ip);
@@ -344,7 +350,7 @@ mod tests {
#[test]
fn test_clear_ip_cache() {
let keypair = Keypair::new();
let mut faucet = Faucet::new(keypair, None, None);
let mut faucet = Faucet::new(keypair, None, None, None);
let ip = "127.0.0.1".parse().expect("create IpAddr from string");
assert_eq!(faucet.ip_cache.len(), 0);
faucet.add_ip_to_cache(ip);
@@ -359,9 +365,10 @@ mod tests {
let keypair = Keypair::new();
let time_slice: Option<u64> = None;
let request_cap: Option<u64> = None;
let faucet = Faucet::new(keypair, time_slice, request_cap);
let faucet = Faucet::new(keypair, time_slice, request_cap, Some(100));
assert_eq!(faucet.time_slice, Duration::new(TIME_SLICE, 0));
assert_eq!(faucet.request_cap, REQUEST_CAP);
assert_eq!(faucet.per_time_cap, REQUEST_CAP);
assert_eq!(faucet.per_request_cap, Some(100));
}
#[test]
@@ -376,7 +383,7 @@ mod tests {
let mint = Keypair::new();
let mint_pubkey = mint.pubkey();
let mut faucet = Faucet::new(mint, None, None);
let mut faucet = Faucet::new(mint, None, None, None);
let tx = faucet.build_airdrop_transaction(request).unwrap();
let message = tx.message();
@@ -392,8 +399,15 @@ mod tests {
let instruction: SystemInstruction = deserialize(&message.instructions[0].data).unwrap();
assert_eq!(instruction, SystemInstruction::Transfer { lamports: 2 });
// Test per-time request cap
let mint = Keypair::new();
faucet = Faucet::new(mint, None, Some(1));
faucet = Faucet::new(mint, None, Some(1), None);
let tx = faucet.build_airdrop_transaction(request);
assert!(tx.is_err());
// Test per-request cap
let mint = Keypair::new();
faucet = Faucet::new(mint, None, None, Some(1));
let tx = faucet.build_airdrop_transaction(request);
assert!(tx.is_err());
}
@@ -421,7 +435,7 @@ mod tests {
LittleEndian::write_u16(&mut expected_vec_with_length, expected_bytes.len() as u16);
expected_vec_with_length.extend_from_slice(&expected_bytes);
let mut faucet = Faucet::new(keypair, None, None);
let mut faucet = Faucet::new(keypair, None, None, None);
let response = faucet.process_faucet_request(&bytes);
let response_vec = response.unwrap().to_vec();
assert_eq!(expected_vec_with_length, response_vec);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -134,7 +134,7 @@ async fn upload(
for (i, slot) in blocks_to_upload.iter().enumerate() {
let _ = match blockstore.get_confirmed_block(
*slot,
Some(solana_transaction_status::UiTransactionEncoding::Binary),
Some(solana_transaction_status::UiTransactionEncoding::Base64),
) {
Ok(confirmed_block) => sender.send((*slot, Some(confirmed_block))),
Err(err) => {
@@ -231,7 +231,7 @@ async fn block(slot: Slot) -> Result<(), Box<dyn std::error::Error>> {
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
let block = bigtable
.get_confirmed_block(slot, UiTransactionEncoding::Binary)
.get_confirmed_block(slot, UiTransactionEncoding::Base64)
.await?;
println!("Slot: {}", slot);
@@ -276,7 +276,7 @@ async fn confirm(signature: &Signature, verbose: bool) -> Result<(), Box<dyn std
if verbose {
match bigtable
.get_confirmed_transaction(signature, UiTransactionEncoding::Binary)
.get_confirmed_transaction(signature, UiTransactionEncoding::Base64)
.await
{
Ok(Some(confirmed_transaction)) => {
@@ -310,13 +310,19 @@ pub async fn transaction_history(
address: &Pubkey,
mut limit: usize,
mut before: Option<Signature>,
until: Option<Signature>,
verbose: bool,
) -> Result<(), Box<dyn std::error::Error>> {
let bigtable = solana_storage_bigtable::LedgerStorage::new(true).await?;
while limit > 0 {
let results = bigtable
.get_confirmed_signatures_for_address(address, before.as_ref(), limit.min(1000))
.get_confirmed_signatures_for_address(
address,
before.as_ref(),
until.as_ref(),
limit.min(1000),
)
.await?;
if results.is_empty() {
@@ -480,6 +486,13 @@ impl BigTableSubCommand for App<'_, '_> {
.takes_value(true)
.help("Start with the first signature older than this one"),
)
.arg(
Arg::with_name("until")
.long("until")
.value_name("TRANSACTION_SIGNATURE")
.takes_value(true)
.help("End with the last signature newer than this one"),
)
.arg(
Arg::with_name("verbose")
.short("v")
@@ -537,9 +550,12 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
let before = arg_matches
.value_of("before")
.map(|signature| signature.parse().expect("Invalid signature"));
let until = arg_matches
.value_of("until")
.map(|signature| signature.parse().expect("Invalid signature"));
let verbose = arg_matches.is_present("verbose");
runtime.block_on(transaction_history(&address, limit, before, verbose))
runtime.block_on(transaction_history(&address, limit, before, until, verbose))
}
_ => unreachable!(),
};

View File

@@ -942,8 +942,7 @@ fn main() {
Arg::with_name("end_slot")
.index(2)
.value_name("SLOT")
.required(true)
.help("Ending slot to stop purging (inclusive)"),
.help("Ending slot to stop purging (inclusive) [default: the highest slot in the ledger]"),
)
)
.subcommand(
@@ -1518,9 +1517,36 @@ fn main() {
}
("purge", Some(arg_matches)) => {
let start_slot = value_t_or_exit!(arg_matches, "start_slot", Slot);
let end_slot = value_t_or_exit!(arg_matches, "end_slot", Slot);
let end_slot = value_t!(arg_matches, "end_slot", Slot).ok();
let blockstore =
open_blockstore(&ledger_path, AccessType::PrimaryOnly, wal_recovery_mode);
let end_slot = match end_slot {
Some(end_slot) => end_slot,
None => match blockstore.slot_meta_iterator(start_slot) {
Ok(metas) => {
let slots: Vec<_> = metas.map(|(slot, _)| slot).collect();
if slots.is_empty() {
eprintln!("Purge range is empty");
exit(1);
}
*slots.last().unwrap()
}
Err(err) => {
eprintln!("Unable to read the Ledger: {:?}", err);
exit(1);
}
},
};
if end_slot < start_slot {
eprintln!(
"end slot {} is less than start slot {}",
end_slot, start_slot
);
exit(1);
}
println!("Purging data from slots {} to {}", start_slot, end_slot);
blockstore.purge_and_compact_slots(start_slot, end_slot);
blockstore.purge_from_next_slots(start_slot, end_slot);
}

View File

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

View File

@@ -350,18 +350,39 @@ impl Blockstore {
Ok((blockstore, signal_receiver, completed_slots_receiver))
}
pub fn add_tree(&self, forks: Tree<Slot>, is_orphan: bool, is_slot_complete: bool) {
pub fn add_tree(
&self,
forks: Tree<Slot>,
is_orphan: bool,
is_slot_complete: bool,
num_ticks: u64,
starting_hash: Hash,
) {
let mut walk = TreeWalk::from(forks);
let mut blockhashes = HashMap::new();
while let Some(visit) = walk.get() {
let slot = visit.node().data;
if self.meta(slot).unwrap().is_some() && self.orphan(slot).unwrap().is_none() {
// If slot exists and is not an orphan, then skip it
// If slot exists in blockstore and is not an orphan, then skip it
walk.forward();
continue;
}
let parent = walk.get_parent().map(|n| n.data);
if parent.is_some() || !is_orphan {
let entries = create_ticks(2, 0, Hash::default());
let parent_hash = parent
// parent won't exist for first node in a tree where
// `is_orphan == true`
.and_then(|parent| blockhashes.get(&parent))
.unwrap_or(&starting_hash);
let mut entries = create_ticks(
num_ticks * (std::cmp::max(1, slot - parent.unwrap_or(slot))),
0,
*parent_hash,
);
blockhashes.insert(slot, entries.last().unwrap().hash);
if !is_slot_complete {
entries.pop().unwrap();
}
let shreds = entries_to_test_shreds(
entries.clone(),
slot,
@@ -407,6 +428,16 @@ impl Blockstore {
self.orphans_cf.get(slot)
}
// Get max root or 0 if it doesn't exist
pub fn max_root(&self) -> Slot {
self.db
.iter::<cf::Root>(IteratorMode::End)
.expect("Couldn't get rooted iterator for max_root()")
.next()
.map(|(slot, _)| slot)
.unwrap_or(0)
}
pub fn slot_meta_iterator<'a>(
&'a self,
slot: Slot,
@@ -1935,6 +1966,7 @@ impl Blockstore {
address: Pubkey,
highest_confirmed_root: Slot,
before: Option<Signature>,
until: Option<Signature>,
limit: usize,
) -> Result<Vec<ConfirmedTransactionStatusWithSignature>> {
datapoint_info!(
@@ -1950,7 +1982,7 @@ impl Blockstore {
// `before` signature if present. Also generate a HashSet of signatures that should
// be excluded from the results.
let mut get_before_slot_timer = Measure::start("get_before_slot_timer");
let (slot, mut excluded_signatures) = match before {
let (slot, mut before_excluded_signatures) = match before {
None => (highest_confirmed_root, None),
Some(before) => {
let transaction_status = self.get_transaction_status(before)?;
@@ -1958,7 +1990,7 @@ impl Blockstore {
None => return Ok(vec![]),
Some((slot, _)) => {
let confirmed_block = self
.get_confirmed_block(slot, Some(UiTransactionEncoding::Binary))
.get_confirmed_block(slot, Some(UiTransactionEncoding::Base64))
.map_err(|err| {
BlockstoreError::IO(IOError::new(
ErrorKind::Other,
@@ -2001,6 +2033,57 @@ impl Blockstore {
};
get_before_slot_timer.stop();
// Generate a HashSet of signatures that should be excluded from the results based on
// `until` signature
let mut get_until_slot_timer = Measure::start("get_until_slot_timer");
let (lowest_slot, until_excluded_signatures) = match until {
None => (0, HashSet::new()),
Some(until) => {
let transaction_status = self.get_transaction_status(until)?;
match transaction_status {
None => (0, HashSet::new()),
Some((slot, _)) => {
let confirmed_block = self
.get_confirmed_block(slot, Some(UiTransactionEncoding::Base64))
.map_err(|err| {
BlockstoreError::IO(IOError::new(
ErrorKind::Other,
format!("Unable to get confirmed block: {}", err),
))
})?;
// Load all signatures for the block
let mut slot_signatures: Vec<_> = confirmed_block
.transactions
.iter()
.filter_map(|transaction_with_meta| {
if let Some(transaction) =
transaction_with_meta.transaction.decode()
{
transaction.signatures.into_iter().next()
} else {
None
}
})
.collect();
// Sort signatures as a way to entire a stable ordering within a slot, as
// the AddressSignatures column is ordered by signatures within a slot,
// not by block ordering
slot_signatures.sort();
slot_signatures.reverse();
if let Some(pos) = slot_signatures.iter().position(|&x| x == until) {
slot_signatures = slot_signatures.split_off(pos);
}
(slot, slot_signatures.into_iter().collect::<HashSet<_>>())
}
}
}
};
get_until_slot_timer.stop();
// Fetch the list of signatures that affect the given address
let first_available_block = self.get_first_available_block()?;
let mut address_signatures = vec![];
@@ -2009,7 +2092,7 @@ impl Blockstore {
let mut get_initial_slot_timer = Measure::start("get_initial_slot_timer");
let mut signatures = self.find_address_signatures(address, slot, slot)?;
signatures.reverse();
if let Some(excluded_signatures) = excluded_signatures.take() {
if let Some(excluded_signatures) = before_excluded_signatures.take() {
address_signatures.extend(
signatures
.into_iter()
@@ -2040,14 +2123,16 @@ impl Blockstore {
// Iterate through starting_iterator until limit is reached
while address_signatures.len() < limit {
if let Some(((i, key_address, slot, signature), _)) = starting_iterator.next() {
if slot == next_max_slot {
if slot == next_max_slot || slot < lowest_slot {
break;
}
if i == starting_primary_index
&& key_address == address
&& slot >= first_available_block
{
address_signatures.push((slot, signature));
if self.is_root(slot) {
address_signatures.push((slot, signature));
}
continue;
}
}
@@ -2055,10 +2140,12 @@ impl Blockstore {
}
// Handle slots that cross primary indexes
let mut signatures =
self.find_address_signatures(address, next_max_slot, next_max_slot)?;
signatures.reverse();
address_signatures.append(&mut signatures);
if next_max_slot >= lowest_slot {
let mut signatures =
self.find_address_signatures(address, next_max_slot, next_max_slot)?;
signatures.reverse();
address_signatures.append(&mut signatures);
}
}
starting_primary_index_iter_timer.stop();
@@ -2074,17 +2161,26 @@ impl Blockstore {
if slot == next_max_slot {
continue;
}
if slot < lowest_slot {
break;
}
if i == next_primary_index
&& key_address == address
&& slot >= first_available_block
{
address_signatures.push((slot, signature));
if self.is_root(slot) {
address_signatures.push((slot, signature));
}
continue;
}
}
break;
}
next_primary_index_iter_timer.stop();
let mut address_signatures: Vec<(Slot, Signature)> = address_signatures
.into_iter()
.filter(|(_, signature)| !until_excluded_signatures.contains(&signature))
.collect();
address_signatures.truncate(limit);
// Fill in the status information for each found transaction
@@ -2131,6 +2227,11 @@ impl Blockstore {
"get_status_info_us",
get_status_info_timer.as_us() as i64,
i64
),
(
"get_until_slot_us",
get_until_slot_timer.as_us() as i64,
i64
)
);
@@ -6344,7 +6445,7 @@ pub mod tests {
let address0 = Pubkey::new_rand();
let address1 = Pubkey::new_rand();
for slot in 2..=7 {
for slot in 2..=8 {
let entries = make_slot_entries_with_transaction_addresses(&[
address0, address1, address0, address1,
]);
@@ -6370,8 +6471,9 @@ pub mod tests {
}
}
}
blockstore.set_roots(&[1, 2, 3, 4, 5, 6, 7]).unwrap();
let highest_confirmed_root = 7;
// Leave one slot unrooted to test only returns confirmed signatures
blockstore.set_roots(&[1, 2, 4, 5, 6, 7, 8]).unwrap();
let highest_confirmed_root = 8;
// Fetch all signatures for address 0 at once...
let all0 = blockstore
@@ -6379,6 +6481,7 @@ pub mod tests {
address0,
highest_confirmed_root,
None,
None,
usize::MAX,
)
.unwrap();
@@ -6390,6 +6493,7 @@ pub mod tests {
address1,
highest_confirmed_root,
None,
None,
usize::MAX,
)
.unwrap();
@@ -6408,23 +6512,58 @@ pub mod tests {
} else {
Some(all0[i - 1].signature)
},
None,
1,
)
.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0], all0[i], "Unexpected result for {}", i);
}
// Fetch all signatures for address 0 individually using `until`
for i in 0..all0.len() {
let results = blockstore
.get_confirmed_signatures_for_address2(
address0,
highest_confirmed_root,
if i == 0 {
None
} else {
Some(all0[i - 1].signature)
},
if i == all0.len() - 1 || i == all0.len() {
None
} else {
Some(all0[i + 1].signature)
},
10,
)
.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0], all0[i], "Unexpected result for {}", i);
}
assert!(blockstore
.get_confirmed_signatures_for_address2(
address0,
highest_confirmed_root,
Some(all0[all0.len() - 1].signature),
None,
1,
)
.unwrap()
.is_empty());
assert!(blockstore
.get_confirmed_signatures_for_address2(
address0,
highest_confirmed_root,
None,
Some(all0[0].signature),
2,
)
.unwrap()
.is_empty());
// Fetch all signatures for address 0, three at a time
assert!(all0.len() % 3 == 0);
for i in (0..all0.len()).step_by(3) {
@@ -6437,6 +6576,7 @@ pub mod tests {
} else {
Some(all0[i - 1].signature)
},
None,
3,
)
.unwrap();
@@ -6458,6 +6598,7 @@ pub mod tests {
} else {
Some(all1[i - 1].signature)
},
None,
2,
)
.unwrap();
@@ -6468,18 +6609,30 @@ pub mod tests {
assert_eq!(results[1], all1[i + 1]);
}
// A search for address 0 with a `before` signature from address1 should also work
// A search for address 0 with `before` and/or `until` signatures from address1 should also work
let results = blockstore
.get_confirmed_signatures_for_address2(
address0,
highest_confirmed_root,
Some(all1[0].signature),
None,
usize::MAX,
)
.unwrap();
// The exact number of results returned is variable, based on the sort order of the
// random signatures that are generated
assert!(!results.is_empty());
let results2 = blockstore
.get_confirmed_signatures_for_address2(
address0,
highest_confirmed_root,
Some(all1[0].signature),
Some(all1[4].signature),
usize::MAX,
)
.unwrap();
assert!(results2.len() < results.len());
}
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}

View File

@@ -749,6 +749,7 @@ where
bank.rc = bankrc;
bank.operating_mode = Some(genesis_config.operating_mode);
bank.init_rent_collector_after_deserialize(genesis_config);
bank.finish_init();
Ok(bank)
})?;

View File

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

View File

@@ -16,11 +16,10 @@ use solana_ledger::{
use solana_sdk::{
client::SyncClient,
clock::{
self, Slot, DEFAULT_MS_PER_SLOT, DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT,
NUM_CONSECUTIVE_LEADER_SLOTS,
self, Slot, DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT, NUM_CONSECUTIVE_LEADER_SLOTS,
},
commitment_config::CommitmentConfig,
epoch_schedule::{EpochSchedule, MINIMUM_SLOTS_PER_EPOCH},
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
hash::Hash,
poh_config::PohConfig,
pubkey::Pubkey,
@@ -172,11 +171,6 @@ pub fn verify_ledger_ticks(ledger_path: &Path, ticks_per_slot: usize) {
}
}
pub fn time_until_nth_epoch(epoch: u64, slots_per_epoch: u64, stakers_slot_offset: u64) -> u64 {
let epoch_schedule = EpochSchedule::custom(slots_per_epoch, stakers_slot_offset, true);
epoch_schedule.get_last_slot_in_epoch(epoch) * DEFAULT_MS_PER_SLOT
}
pub fn sleep_n_epochs(
num_epochs: f64,
config: &PohConfig,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -131,7 +131,8 @@ fn do_get_packet_offsets(
}
// read the length of Transaction.signatures (serialized with short_vec)
let (sig_len_untrusted, sig_size) = decode_len(&packet.data)?;
let (sig_len_untrusted, sig_size) =
decode_len(&packet.data).map_err(|_| PacketError::InvalidShortVec)?;
// Using msg_start_offset which is based on sig_len_untrusted introduces uncertainty.
// Ultimately, the actual sigverify will determine the uncertainty.
@@ -156,8 +157,8 @@ fn do_get_packet_offsets(
}
// read the length of Message.account_keys (serialized with short_vec)
let (pubkey_len, pubkey_len_size) =
decode_len(&packet.data[message_account_keys_len_offset..])?;
let (pubkey_len, pubkey_len_size) = decode_len(&packet.data[message_account_keys_len_offset..])
.map_err(|_| PacketError::InvalidShortVec)?;
if (message_account_keys_len_offset + pubkey_len * size_of::<Pubkey>() + pubkey_len_size)
> packet.meta.size

View File

@@ -1565,7 +1565,7 @@ dependencies = [
[[package]]
name = "solana-bpf-loader-program"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bincode",
"byteorder 1.3.4",
@@ -1582,7 +1582,7 @@ dependencies = [
[[package]]
name = "solana-bpf-programs"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bincode",
"byteorder 1.3.4",
@@ -1597,7 +1597,7 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-128bit"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-bpf-rust-128bit-dep",
"solana-sdk",
@@ -1605,21 +1605,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-128bit-dep"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-alloc"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-dep-crate"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"byteorder 1.3.4",
"solana-sdk",
@@ -1627,14 +1627,14 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-dup-accounts"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-error-handling"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"num-derive 0.2.5",
"num-traits",
@@ -1644,14 +1644,14 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-external-spend"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-invoke"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-bpf-rust-invoked",
"solana-sdk",
@@ -1659,21 +1659,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-invoked"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-iter"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-bpf-rust-many-args-dep",
"solana-sdk",
@@ -1681,28 +1681,28 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-many-args-dep"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-noop"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-panic"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-param-passing"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-bpf-rust-param-passing-dep",
"solana-sdk",
@@ -1710,21 +1710,21 @@ dependencies = [
[[package]]
name = "solana-bpf-rust-param-passing-dep"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"solana-sdk",
]
[[package]]
name = "solana-config-program"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bincode",
"chrono",
@@ -1736,7 +1736,7 @@ dependencies = [
[[package]]
name = "solana-crate-features"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"backtrace",
"bytes 0.4.12",
@@ -1759,7 +1759,7 @@ dependencies = [
[[package]]
name = "solana-logger"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"env_logger",
"lazy_static",
@@ -1768,7 +1768,7 @@ dependencies = [
[[package]]
name = "solana-measure"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"jemalloc-ctl",
"jemallocator",
@@ -1779,7 +1779,7 @@ dependencies = [
[[package]]
name = "solana-metrics"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"env_logger",
"gethostname",
@@ -1791,7 +1791,7 @@ dependencies = [
[[package]]
name = "solana-rayon-threadlimit"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"lazy_static",
"num_cpus",
@@ -1799,7 +1799,7 @@ dependencies = [
[[package]]
name = "solana-runtime"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bincode",
"bv",
@@ -1833,7 +1833,7 @@ dependencies = [
[[package]]
name = "solana-sdk"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"assert_matches",
"bincode",
@@ -1869,7 +1869,7 @@ dependencies = [
[[package]]
name = "solana-sdk-macro"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bs58",
"proc-macro2 1.0.18",
@@ -1880,7 +1880,7 @@ dependencies = [
[[package]]
name = "solana-stake-program"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bincode",
"log",
@@ -1897,7 +1897,7 @@ dependencies = [
[[package]]
name = "solana-vote-program"
version = "1.2.21"
version = "1.2.26"
dependencies = [
"bincode",
"log",

View File

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

View File

@@ -36,7 +36,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_assert(accounts[ARGUMENT_INDEX].data_len == 100);
sol_assert(accounts[ARGUMENT_INDEX].is_signer);
sol_assert(accounts[ARGUMENT_INDEX].is_writable);
sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 1);
sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 0);
sol_assert(!accounts[ARGUMENT_INDEX].executable);
for (int i = 0; i < accounts[ARGUMENT_INDEX].data_len; i++) {
sol_assert(accounts[ARGUMENT_INDEX].data[i] == i);
@@ -48,7 +48,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].data_len == 10);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].is_signer);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].is_writable);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].rent_epoch == 1);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].rent_epoch == 0);
sol_assert(!accounts[INVOKED_ARGUMENT_INDEX].executable);
sol_assert(
@@ -57,7 +57,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
&bpf_loader_id));
sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_signer);
sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_writable);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].rent_epoch == 1);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].rent_epoch == 0);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].executable);
sol_assert(SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].key,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -42,7 +42,7 @@ fn process_instruction(
assert_eq!(accounts[ARGUMENT_INDEX].data_len(), 100);
assert!(accounts[ARGUMENT_INDEX].is_signer);
assert!(accounts[ARGUMENT_INDEX].is_writable);
assert_eq!(accounts[ARGUMENT_INDEX].rent_epoch, 1);
assert_eq!(accounts[ARGUMENT_INDEX].rent_epoch, 0);
assert!(!accounts[ARGUMENT_INDEX].executable);
{
let data = accounts[ARGUMENT_INDEX].try_borrow_data()?;
@@ -59,14 +59,14 @@ fn process_instruction(
assert_eq!(accounts[INVOKED_ARGUMENT_INDEX].data_len(), 10);
assert!(accounts[INVOKED_ARGUMENT_INDEX].is_signer);
assert!(accounts[INVOKED_ARGUMENT_INDEX].is_writable);
assert_eq!(accounts[INVOKED_ARGUMENT_INDEX].rent_epoch, 1);
assert_eq!(accounts[INVOKED_ARGUMENT_INDEX].rent_epoch, 0);
assert!(!accounts[INVOKED_ARGUMENT_INDEX].executable);
assert_eq!(accounts[INVOKED_PROGRAM_INDEX].key, program_id);
assert_eq!(accounts[INVOKED_PROGRAM_INDEX].owner, &bpf_loader::id());
assert!(!accounts[INVOKED_PROGRAM_INDEX].is_signer);
assert!(!accounts[INVOKED_PROGRAM_INDEX].is_writable);
assert_eq!(accounts[INVOKED_PROGRAM_INDEX].rent_epoch, 1);
assert_eq!(accounts[INVOKED_PROGRAM_INDEX].rent_epoch, 0);
assert!(accounts[INVOKED_PROGRAM_INDEX].executable);
assert_eq!(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-exchange-program"
version = "1.2.22"
version = "1.2.26"
description = "Solana Exchange program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,13 +15,13 @@ num-derive = { version = "0.3" }
num-traits = { version = "0.2" }
serde = "1.0.110"
serde_derive = "1.0.103"
solana-logger = { path = "../../logger", version = "1.2.22" }
solana-metrics = { path = "../../metrics", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-logger = { path = "../../logger", version = "1.2.26" }
solana-metrics = { path = "../../metrics", version = "1.2.26" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.2.22" }
solana-runtime = { path = "../../runtime", version = "1.2.26" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-failure-program"
version = "1.2.22"
version = "1.2.26"
description = "Solana failure program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,10 +9,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.2.22" }
solana-runtime = { path = "../../runtime", version = "1.2.26" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-noop-program"
version = "1.2.22"
version = "1.2.26"
description = "Solana Noop program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,8 +10,8 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-logger = { path = "../../logger", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-logger = { path = "../../logger", version = "1.2.26" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ownable"
version = "1.2.22"
version = "1.2.26"
description = "ownable program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,13 +10,13 @@ edition = "2018"
[dependencies]
bincode = "1.2.1"
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
num-derive = "0.3"
num-traits = "0.2"
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.2.22" }
solana-runtime = { path = "../../runtime", version = "1.2.26" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-stake-program"
version = "1.2.22"
version = "1.2.26"
description = "Solana Stake program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,14 +15,14 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.110"
serde_derive = "1.0.103"
solana-metrics = { path = "../../metrics", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-vote-program = { path = "../vote", version = "1.2.22" }
solana-config-program = { path = "../config", version = "1.2.22" }
solana-metrics = { path = "../../metrics", version = "1.2.26" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
solana-vote-program = { path = "../vote", version = "1.2.26" }
solana-config-program = { path = "../config", version = "1.2.26" }
thiserror = "1.0"
[dev-dependencies]
solana-logger = { path = "../../logger", version = "1.2.22" }
solana-logger = { path = "../../logger", version = "1.2.26" }
[lib]
crate-type = ["lib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-vest-program"
version = "1.2.22"
version = "1.2.26"
description = "Solana Vest program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,12 +15,12 @@ num-derive = "0.2"
num-traits = "0.2"
serde = "1.0.110"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-config-program = { path = "../config", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
solana-config-program = { path = "../config", version = "1.2.26" }
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.2.22" }
solana-runtime = { path = "../../runtime", version = "1.2.26" }
[lib]
crate-type = ["lib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-vote-program"
version = "1.2.22"
version = "1.2.26"
description = "Solana Vote program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,8 +15,8 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.110"
serde_derive = "1.0.103"
solana-metrics = { path = "../../metrics", version = "1.2.22" }
solana-sdk = { path = "../../sdk", version = "1.2.22" }
solana-metrics = { path = "../../metrics", version = "1.2.26" }
solana-sdk = { path = "../../sdk", version = "1.2.26" }
thiserror = "1.0"
[lib]

View File

@@ -544,7 +544,7 @@ impl VoteState {
timestamp: UnixTimestamp,
) -> Result<(), VoteError> {
if (slot < self.last_timestamp.slot || timestamp < self.last_timestamp.timestamp)
|| ((slot == self.last_timestamp.slot || timestamp == self.last_timestamp.timestamp)
|| (slot == self.last_timestamp.slot
&& BlockTimestamp { slot, timestamp } != self.last_timestamp
&& self.last_timestamp.slot != 0)
{
@@ -1729,10 +1729,6 @@ mod tests {
vote_state.process_timestamp(slot + 1, timestamp - 1),
Err(VoteError::TimestampTooOld)
);
assert_eq!(
vote_state.process_timestamp(slot + 1, timestamp),
Err(VoteError::TimestampTooOld)
);
assert_eq!(
vote_state.process_timestamp(slot, timestamp + 1),
Err(VoteError::TimestampTooOld)
@@ -1742,14 +1738,22 @@ mod tests {
vote_state.last_timestamp,
BlockTimestamp { slot, timestamp }
);
assert_eq!(vote_state.process_timestamp(slot + 1, timestamp), Ok(()));
assert_eq!(
vote_state.process_timestamp(slot + 1, timestamp + 1),
vote_state.last_timestamp,
BlockTimestamp {
slot: slot + 1,
timestamp
}
);
assert_eq!(
vote_state.process_timestamp(slot + 2, timestamp + 1),
Ok(())
);
assert_eq!(
vote_state.last_timestamp,
BlockTimestamp {
slot: slot + 1,
slot: slot + 2,
timestamp: timestamp + 1
}
);

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-ramp-tps"
description = "Solana Tour de SOL - TPS ramp up"
version = "1.2.22"
version = "1.2.26"
repository = "https://github.com/solana-labs/tour-de-sol"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -16,12 +16,12 @@ reqwest = { version = "0.10.4", default-features = false }
serde = "1.0.110"
serde_json = "1.0.53"
serde_yaml = "0.8.12"
solana-core = { path = "../core", version = "1.2.22" }
solana-client = { path = "../client", version = "1.2.22" }
solana-logger = { path = "../logger", version = "1.2.22" }
solana-metrics = { path = "../metrics", version = "1.2.22" }
solana-net-utils = { path = "../net-utils", version = "1.2.22" }
solana-notifier = { path = "../notifier", version = "1.2.22" }
solana-sdk = { path = "../sdk", version = "1.2.22" }
solana-stake-program = { path = "../programs/stake", version = "1.2.22" }
solana-core = { path = "../core", version = "1.2.26" }
solana-client = { path = "../client", version = "1.2.26" }
solana-logger = { path = "../logger", version = "1.2.26" }
solana-metrics = { path = "../metrics", version = "1.2.26" }
solana-net-utils = { path = "../net-utils", version = "1.2.26" }
solana-notifier = { path = "../notifier", version = "1.2.26" }
solana-sdk = { path = "../sdk", version = "1.2.26" }
solana-stake-program = { path = "../programs/stake", version = "1.2.26" }
tar = "0.4.28"

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