Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
de76df0cbb | ||
|
a0190b4105 | ||
|
5255a6ebd2 | ||
|
8575514235 | ||
|
2a1946436b | ||
|
80649a9c3d | ||
|
ad74ba0eb0 | ||
|
fd41ad5d8f | ||
|
63855d5c2a | ||
|
00251f710e | ||
|
14bc623989 | ||
|
fb90fb3feb | ||
|
d6ca879d39 | ||
|
2dcde5281d | ||
|
e2626dad83 | ||
|
070fbeb69a | ||
|
497ec24754 | ||
|
1bda09bf0e | ||
|
7ca7f8604d | ||
|
e2b5f2dd9c | ||
|
3652bd57a9 | ||
|
5077d6bfb3 | ||
|
f0ee3e9deb | ||
|
babad39846 | ||
|
c15aa4a968 |
305
Cargo.lock
generated
305
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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]
|
||||
|
@@ -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,
|
||||
|
@@ -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"
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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/"
|
||||
|
@@ -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]]
|
||||
|
@@ -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(
|
||||
|
@@ -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());
|
||||
|
@@ -348,7 +348,7 @@ mod tests {
|
||||
let rpc_nonce_account = UiAccount::encode(
|
||||
&nonce_pubkey,
|
||||
nonce_account,
|
||||
UiAccountEncoding::Binary64,
|
||||
UiAccountEncoding::Base64,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@@ -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"]
|
||||
|
@@ -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
|
||||
|
@@ -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>,
|
||||
}
|
||||
|
@@ -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"] }
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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))
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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] {
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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(
|
||||
|
@@ -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..] {
|
||||
|
@@ -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,
|
||||
};
|
||||
|
@@ -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"
|
||||
|
@@ -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\)
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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"]
|
||||
|
@@ -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]
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
|
@@ -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"]
|
||||
|
@@ -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]]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"
|
||||
|
@@ -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]]
|
||||
|
@@ -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"] }
|
||||
|
||||
|
@@ -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!(),
|
||||
};
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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"]
|
||||
|
@@ -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");
|
||||
}
|
||||
|
@@ -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)
|
||||
})?;
|
||||
|
@@ -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"
|
||||
|
@@ -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,
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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]
|
||||
|
@@ -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"
|
||||
|
@@ -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]]
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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]
|
||||
|
@@ -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
|
||||
|
60
programs/bpf/Cargo.lock
generated
60
programs/bpf/Cargo.lock
generated
@@ -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",
|
||||
|
@@ -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]]
|
||||
|
@@ -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,
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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!(
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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]
|
||||
|
@@ -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"
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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]
|
||||
|
@@ -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
|
||||
}
|
||||
);
|
||||
|
@@ -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
Reference in New Issue
Block a user