Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
bdb77b0c98 | ||
|
58bef3a94b | ||
|
52dfb4a09c | ||
|
c734db59cb | ||
|
3b36e8e285 | ||
|
cdbc77bf97 | ||
|
8ab358ce78 | ||
|
5193ba2062 | ||
|
7e5767f926 | ||
|
e5e6829d20 | ||
|
3976816b79 | ||
|
9732157f0c | ||
|
ed18d6d38d | ||
|
ef336a44a1 | ||
|
de5f503a76 | ||
|
b5b1ed2a55 | ||
|
caea9c99cd | ||
|
1495b94f7a | ||
|
f55bb78307 | ||
|
fa5a71dbf0 | ||
|
80a6479c47 | ||
|
a492de1bea | ||
|
43b414b0df | ||
|
6f31882260 | ||
|
5042808ecf | ||
|
1c9d0521ca | ||
|
ddda94e486 | ||
|
73ed9f56d7 | ||
|
ab5d032634 | ||
|
03b930515b | ||
|
c9f763ea6e | ||
|
422044f375 | ||
|
7584262f47 | ||
|
894f121d0e | ||
|
4b133509d9 | ||
|
e8040a828d | ||
|
78086329be | ||
|
6deeedd886 | ||
|
1a0146f21d | ||
|
7d0a9e0381 | ||
|
0f7b84197f | ||
|
bb06502d24 | ||
|
b7f1f19d8e |
1042
Cargo.lock
generated
1042
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana account decoder"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,9 +19,9 @@ lazy_static = "1.4.0"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.56"
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
spl-token-v2-0 = { package = "spl-token", version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
zstd = "0.5.1"
|
||||
|
@@ -28,6 +28,7 @@ use {
|
||||
|
||||
pub type StringAmount = String;
|
||||
pub type StringDecimals = String;
|
||||
pub const MAX_BASE58_BYTES: usize = 128;
|
||||
|
||||
/// A duplicate representation of an Account for pretty JSON serialization
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
@@ -60,6 +61,17 @@ pub enum UiAccountEncoding {
|
||||
}
|
||||
|
||||
impl UiAccount {
|
||||
fn encode_bs58<T: ReadableAccount>(
|
||||
account: &T,
|
||||
data_slice_config: Option<UiDataSliceConfig>,
|
||||
) -> String {
|
||||
if account.data().len() <= MAX_BASE58_BYTES {
|
||||
bs58::encode(slice_data(account.data(), data_slice_config)).into_string()
|
||||
} else {
|
||||
"error: data too large for bs58 encoding".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode<T: ReadableAccount>(
|
||||
pubkey: &Pubkey,
|
||||
account: &T,
|
||||
@@ -68,13 +80,14 @@ impl UiAccount {
|
||||
data_slice_config: Option<UiDataSliceConfig>,
|
||||
) -> Self {
|
||||
let data = match encoding {
|
||||
UiAccountEncoding::Binary => UiAccountData::LegacyBinary(
|
||||
bs58::encode(slice_data(account.data(), data_slice_config)).into_string(),
|
||||
),
|
||||
UiAccountEncoding::Base58 => UiAccountData::Binary(
|
||||
bs58::encode(slice_data(account.data(), data_slice_config)).into_string(),
|
||||
encoding,
|
||||
),
|
||||
UiAccountEncoding::Binary => {
|
||||
let data = Self::encode_bs58(account, data_slice_config);
|
||||
UiAccountData::LegacyBinary(data)
|
||||
}
|
||||
UiAccountEncoding::Base58 => {
|
||||
let data = Self::encode_bs58(account, data_slice_config);
|
||||
UiAccountData::Binary(data, encoding)
|
||||
}
|
||||
UiAccountEncoding::Base64 => UiAccountData::Binary(
|
||||
base64::encode(slice_data(account.data(), data_slice_config)),
|
||||
encoding,
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-accounts-bench"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -11,11 +11,11 @@ publish = false
|
||||
[dependencies]
|
||||
log = "0.4.11"
|
||||
rayon = "1.5.0"
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
rand = "0.7.0"
|
||||
clap = "2.33.1"
|
||||
crossbeam-channel = "0.4"
|
||||
|
@@ -122,6 +122,7 @@ fn main() {
|
||||
&ancestors,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
);
|
||||
time_store.stop();
|
||||
if results != results_store {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-accounts-cluster-bench"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,24 +13,24 @@ clap = "2.33.1"
|
||||
log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.4.1"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
spl-token-v2-0 = { package = "spl-token", version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.7.9" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-banking-bench"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,18 +14,18 @@ crossbeam-channel = "0.4"
|
||||
log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.0"
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.9" }
|
||||
solana-poh = { path = "../poh", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.11" }
|
||||
solana-poh = { path = "../poh", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-client"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana banks client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,16 +15,16 @@ borsh = "0.9.0"
|
||||
borsh-derive = "0.9.0"
|
||||
futures = "0.3"
|
||||
mio = "0.7.6"
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.7.9" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.7.11" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
tarpc = { version = "0.24.1", features = ["full"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-serde = { version = "0.8", features = ["bincode"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.7.11" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -69,7 +69,7 @@ impl BanksClient {
|
||||
&mut self,
|
||||
ctx: Context,
|
||||
commitment: CommitmentLevel,
|
||||
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, Slot)>> + '_ {
|
||||
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, u64)>> + '_ {
|
||||
self.inner
|
||||
.get_fees_with_commitment_and_context(ctx, commitment)
|
||||
}
|
||||
@@ -91,6 +91,14 @@ impl BanksClient {
|
||||
self.inner.get_slot_with_context(ctx, commitment)
|
||||
}
|
||||
|
||||
pub fn get_block_height_with_context(
|
||||
&mut self,
|
||||
ctx: Context,
|
||||
commitment: CommitmentLevel,
|
||||
) -> impl Future<Output = io::Result<Slot>> + '_ {
|
||||
self.inner.get_block_height_with_context(ctx, commitment)
|
||||
}
|
||||
|
||||
pub fn process_transaction_with_commitment_and_context(
|
||||
&mut self,
|
||||
ctx: Context,
|
||||
@@ -137,7 +145,7 @@ impl BanksClient {
|
||||
/// use them to calculate the transaction fee.
|
||||
pub fn get_fees(
|
||||
&mut self,
|
||||
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, Slot)>> + '_ {
|
||||
) -> impl Future<Output = io::Result<(FeeCalculator, Hash, u64)>> + '_ {
|
||||
self.get_fees_with_commitment_and_context(context::current(), CommitmentLevel::default())
|
||||
}
|
||||
|
||||
@@ -213,12 +221,18 @@ impl BanksClient {
|
||||
self.process_transactions_with_commitment(transactions, CommitmentLevel::default())
|
||||
}
|
||||
|
||||
/// Return the most recent rooted slot height. All transactions at or below this height
|
||||
/// are said to be finalized. The cluster will not fork to a higher slot height.
|
||||
/// Return the most recent rooted slot. All transactions at or below this slot
|
||||
/// are said to be finalized. The cluster will not fork to a higher slot.
|
||||
pub fn get_root_slot(&mut self) -> impl Future<Output = io::Result<Slot>> + '_ {
|
||||
self.get_slot_with_context(context::current(), CommitmentLevel::default())
|
||||
}
|
||||
|
||||
/// Return the most recent rooted block height. All transactions at or below this height
|
||||
/// are said to be finalized. The cluster will not fork to a higher block height.
|
||||
pub fn get_root_block_height(&mut self) -> impl Future<Output = io::Result<Slot>> + '_ {
|
||||
self.get_block_height_with_context(context::current(), CommitmentLevel::default())
|
||||
}
|
||||
|
||||
/// Return the account at the given address at the slot corresponding to the given
|
||||
/// commitment level. If the account is not found, None is returned.
|
||||
pub fn get_account_with_commitment(
|
||||
@@ -404,7 +418,7 @@ mod tests {
|
||||
Runtime::new()?.block_on(async {
|
||||
let client_transport = start_local_server(bank_forks, block_commitment_cache).await;
|
||||
let mut banks_client = start_client(client_transport).await?;
|
||||
let (_, recent_blockhash, last_valid_slot) = banks_client.get_fees().await?;
|
||||
let (_, recent_blockhash, last_valid_block_height) = banks_client.get_fees().await?;
|
||||
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
||||
let signature = transaction.signatures[0];
|
||||
banks_client.send_transaction(transaction).await?;
|
||||
@@ -412,8 +426,8 @@ mod tests {
|
||||
let mut status = banks_client.get_transaction_status(signature).await?;
|
||||
|
||||
while status.is_none() {
|
||||
let root_slot = banks_client.get_root_slot().await?;
|
||||
if root_slot > last_valid_slot {
|
||||
let root_block_height = banks_client.get_root_block_height().await?;
|
||||
if root_block_height > last_valid_block_height {
|
||||
break;
|
||||
}
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-interface"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana banks RPC interface"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
mio = "0.7.6"
|
||||
serde = { version = "1.0.122", features = ["derive"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
tarpc = { version = "0.24.1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -34,6 +34,7 @@ pub trait Banks {
|
||||
async fn get_transaction_status_with_context(signature: Signature)
|
||||
-> Option<TransactionStatus>;
|
||||
async fn get_slot_with_context(commitment: CommitmentLevel) -> Slot;
|
||||
async fn get_block_height_with_context(commitment: CommitmentLevel) -> u64;
|
||||
async fn process_transaction_with_commitment_and_context(
|
||||
transaction: Transaction,
|
||||
commitment: CommitmentLevel,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-server"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana banks server"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,10 +14,10 @@ bincode = "1.3.1"
|
||||
futures = "0.3"
|
||||
log = "0.4.11"
|
||||
mio = "0.7.6"
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
tarpc = { version = "0.24.1", features = ["full"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-serde = { version = "0.8", features = ["bincode"] }
|
||||
|
@@ -113,7 +113,7 @@ impl BanksServer {
|
||||
self,
|
||||
signature: &Signature,
|
||||
blockhash: &Hash,
|
||||
last_valid_slot: Slot,
|
||||
last_valid_block_height: u64,
|
||||
commitment: CommitmentLevel,
|
||||
) -> Option<transaction::Result<()>> {
|
||||
let mut status = self
|
||||
@@ -122,7 +122,7 @@ impl BanksServer {
|
||||
while status.is_none() {
|
||||
sleep(Duration::from_millis(200)).await;
|
||||
let bank = self.bank(commitment);
|
||||
if bank.slot() > last_valid_slot {
|
||||
if bank.block_height() > last_valid_block_height {
|
||||
break;
|
||||
}
|
||||
status = bank.get_signature_status_with_blockhash(signature, blockhash);
|
||||
@@ -148,16 +148,19 @@ fn verify_transaction(
|
||||
impl Banks for BanksServer {
|
||||
async fn send_transaction_with_context(self, _: Context, transaction: Transaction) {
|
||||
let blockhash = &transaction.message.recent_blockhash;
|
||||
let last_valid_slot = self
|
||||
let last_valid_block_height = self
|
||||
.bank_forks
|
||||
.read()
|
||||
.unwrap()
|
||||
.root_bank()
|
||||
.get_blockhash_last_valid_slot(blockhash)
|
||||
.get_blockhash_last_valid_block_height(blockhash)
|
||||
.unwrap();
|
||||
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
||||
let info =
|
||||
TransactionInfo::new(signature, serialize(&transaction).unwrap(), last_valid_slot);
|
||||
let info = TransactionInfo::new(
|
||||
signature,
|
||||
serialize(&transaction).unwrap(),
|
||||
last_valid_block_height,
|
||||
);
|
||||
self.transaction_sender.send(info).unwrap();
|
||||
}
|
||||
|
||||
@@ -165,11 +168,13 @@ impl Banks for BanksServer {
|
||||
self,
|
||||
_: Context,
|
||||
commitment: CommitmentLevel,
|
||||
) -> (FeeCalculator, Hash, Slot) {
|
||||
) -> (FeeCalculator, Hash, u64) {
|
||||
let bank = self.bank(commitment);
|
||||
let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator();
|
||||
let last_valid_slot = bank.get_blockhash_last_valid_slot(&blockhash).unwrap();
|
||||
(fee_calculator, blockhash, last_valid_slot)
|
||||
let last_valid_block_height = bank
|
||||
.get_blockhash_last_valid_block_height(&blockhash)
|
||||
.unwrap();
|
||||
(fee_calculator, blockhash, last_valid_block_height)
|
||||
}
|
||||
|
||||
async fn get_transaction_status_with_context(
|
||||
@@ -212,6 +217,10 @@ impl Banks for BanksServer {
|
||||
self.slot(commitment)
|
||||
}
|
||||
|
||||
async fn get_block_height_with_context(self, _: Context, commitment: CommitmentLevel) -> u64 {
|
||||
self.bank(commitment).block_height()
|
||||
}
|
||||
|
||||
async fn process_transaction_with_commitment_and_context(
|
||||
self,
|
||||
_: Context,
|
||||
@@ -226,18 +235,21 @@ impl Banks for BanksServer {
|
||||
}
|
||||
|
||||
let blockhash = &transaction.message.recent_blockhash;
|
||||
let last_valid_slot = self
|
||||
let last_valid_block_height = self
|
||||
.bank_forks
|
||||
.read()
|
||||
.unwrap()
|
||||
.root_bank()
|
||||
.get_blockhash_last_valid_slot(blockhash)
|
||||
.get_blockhash_last_valid_block_height(blockhash)
|
||||
.unwrap();
|
||||
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
||||
let info =
|
||||
TransactionInfo::new(signature, serialize(&transaction).unwrap(), last_valid_slot);
|
||||
let info = TransactionInfo::new(
|
||||
signature,
|
||||
serialize(&transaction).unwrap(),
|
||||
last_valid_block_height,
|
||||
);
|
||||
self.transaction_sender.send(info).unwrap();
|
||||
self.poll_signature_status(&signature, blockhash, last_valid_slot, commitment)
|
||||
self.poll_signature_status(&signature, blockhash, last_valid_block_height, commitment)
|
||||
.await
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
use log::*;
|
||||
use solana_metrics::{datapoint_warn, inc_new_counter_info};
|
||||
use solana_runtime::{bank::Bank, bank_forks::BankForks};
|
||||
use solana_sdk::{clock::Slot, signature::Signature};
|
||||
use solana_sdk::signature::Signature;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::{SocketAddr, UdpSocket},
|
||||
@@ -24,15 +24,19 @@ pub struct SendTransactionService {
|
||||
pub struct TransactionInfo {
|
||||
pub signature: Signature,
|
||||
pub wire_transaction: Vec<u8>,
|
||||
pub last_valid_slot: Slot,
|
||||
pub last_valid_block_height: u64,
|
||||
}
|
||||
|
||||
impl TransactionInfo {
|
||||
pub fn new(signature: Signature, wire_transaction: Vec<u8>, last_valid_slot: Slot) -> Self {
|
||||
pub fn new(
|
||||
signature: Signature,
|
||||
wire_transaction: Vec<u8>,
|
||||
last_valid_block_height: u64,
|
||||
) -> Self {
|
||||
Self {
|
||||
signature,
|
||||
wire_transaction,
|
||||
last_valid_slot,
|
||||
last_valid_block_height,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,7 +128,7 @@ impl SendTransactionService {
|
||||
result.rooted += 1;
|
||||
inc_new_counter_info!("send_transaction_service-rooted", 1);
|
||||
false
|
||||
} else if transaction_info.last_valid_slot < root_bank.slot() {
|
||||
} else if transaction_info.last_valid_block_height < root_bank.block_height() {
|
||||
info!("Dropping expired transaction: {}", signature);
|
||||
result.expired += 1;
|
||||
inc_new_counter_info!("send_transaction_service-expired", 1);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-exchange"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -18,23 +18,23 @@ rand = "0.7.0"
|
||||
rayon = "1.5.0"
|
||||
serde_json = "1.0.56"
|
||||
serde_yaml = "0.8.13"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "=1.7.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "=1.7.11" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.7.9" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-streamer"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -10,11 +10,11 @@ publish = false
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-tps"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,24 +15,24 @@ log = "0.4.11"
|
||||
rayon = "1.5.0"
|
||||
serde_json = "1.0.56"
|
||||
serde_yaml = "0.8.13"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.4.0"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.7.9" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -28,16 +28,23 @@ cargo_audit_ignores=(
|
||||
# Blocked on multiple crates updating `time` to >= 0.2.23
|
||||
--ignore RUSTSEC-2020-0071
|
||||
|
||||
# difference is unmaintained
|
||||
#
|
||||
# Blocked on predicates v1.0.6 removing its dependency on `difference`
|
||||
--ignore RUSTSEC-2020-0095
|
||||
|
||||
# generic-array: arr! macro erases lifetimes
|
||||
#
|
||||
# Blocked on libsecp256k1 releasing with upgraded dependencies
|
||||
# https://github.com/paritytech/libsecp256k1/issues/66
|
||||
--ignore RUSTSEC-2020-0146
|
||||
|
||||
# hyper: Lenient `hyper` header parsing of `Content-Length` could allow request smuggling
|
||||
#
|
||||
# Blocked on jsonrpc removing dependency on unmaintained `websocket`
|
||||
# https://github.com/paritytech/jsonrpc/issues/605
|
||||
--ignore RUSTSEC-2021-0078
|
||||
|
||||
# hyper: Integer overflow in `hyper`'s parsing of the `Transfer-Encoding` header leads to data loss
|
||||
#
|
||||
# Blocked on jsonrpc removing dependency on unmaintained `websocket`
|
||||
# https://github.com/paritytech/jsonrpc/issues/605
|
||||
--ignore RUSTSEC-2021-0079
|
||||
|
||||
)
|
||||
scripts/cargo-for-all-lock-files.sh stable audit "${cargo_audit_ignores[@]}"
|
||||
|
@@ -76,7 +76,7 @@ RestartForceExitStatus=SIGPIPE
|
||||
TimeoutStartSec=10
|
||||
TimeoutStopSec=0
|
||||
KillMode=process
|
||||
LimitNOFILE=700000
|
||||
LimitNOFILE=1000000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@@ -8,5 +8,5 @@ source "$HERE"/utils.sh
|
||||
ensure_env || exit 1
|
||||
|
||||
# Allow more files to be opened by a user
|
||||
echo "* - nofile 700000" > /etc/security/limits.d/90-solana-nofiles.conf
|
||||
echo "* - nofile 1000000" > /etc/security/limits.d/90-solana-nofiles.conf
|
||||
|
||||
|
@@ -75,6 +75,7 @@ test-stable-bpf)
|
||||
bpf_dump_archive="bpf-dumps.tar.bz2"
|
||||
rm -f "$bpf_dump_archive"
|
||||
tar cjvf "$bpf_dump_archive" "${bpf_target_path}"/{deploy/*.txt,bpfel-unknown-unknown/release/*.so}
|
||||
exit 0
|
||||
;;
|
||||
test-stable-perf)
|
||||
if [[ $(uname) = Linux ]]; then
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana utilities for the clap"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ edition = "2018"
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
rpassword = "4.0"
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
thiserror = "1.0.21"
|
||||
tiny-bip39 = "0.8.0"
|
||||
uriparse = "0.6.3"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli-config"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli-output"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -20,12 +20,12 @@ indicatif = "0.15.0"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.56"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -1954,6 +1954,29 @@ impl fmt::Display for CliUpgradeableProgram {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CliUpgradeableProgramClosed {
|
||||
pub program_id: String,
|
||||
pub lamports: u64,
|
||||
#[serde(skip_serializing)]
|
||||
pub use_lamports_unit: bool,
|
||||
}
|
||||
impl QuietDisplay for CliUpgradeableProgramClosed {}
|
||||
impl VerboseDisplay for CliUpgradeableProgramClosed {}
|
||||
impl fmt::Display for CliUpgradeableProgramClosed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f)?;
|
||||
writeln!(
|
||||
f,
|
||||
"Closed Program Id {}, {} reclaimed",
|
||||
&self.program_id,
|
||||
&build_balance_message(self.lamports, self.use_lamports_unit, true)
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CliUpgradeableBuffer {
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -29,30 +29,30 @@ reqwest = { version = "0.11.2", default-features = false, features = ["blocking"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.56"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.9" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.9" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.11" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.11" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.11" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana_rbpf = "=0.2.11"
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0.21"
|
||||
tiny-bip39 = "0.7.0"
|
||||
url = "2.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -1,7 +1,6 @@
|
||||
use crate::{
|
||||
cli::{CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult},
|
||||
spend_utils::{resolve_spend_tx_and_check_account_balance, SpendAmount},
|
||||
stake::is_stake_program_v2_enabled,
|
||||
};
|
||||
use clap::{value_t, value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||
use console::{style, Emoji};
|
||||
@@ -1750,8 +1749,6 @@ pub fn process_show_stakes(
|
||||
let stake_history = from_account(&stake_history_account).ok_or_else(|| {
|
||||
CliError::RpcRequestError("Failed to deserialize stake history".to_string())
|
||||
})?;
|
||||
// At v1.6, this check can be removed and simply passed as `true`
|
||||
let stake_program_v2_enabled = is_stake_program_v2_enabled(rpc_client)?;
|
||||
|
||||
let mut stake_accounts: Vec<CliKeyedStakeState> = vec![];
|
||||
for (stake_pubkey, stake_account) in all_stake_accounts {
|
||||
@@ -1767,7 +1764,6 @@ pub fn process_show_stakes(
|
||||
use_lamports_unit,
|
||||
&stake_history,
|
||||
&clock,
|
||||
stake_program_v2_enabled,
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -1786,7 +1782,6 @@ pub fn process_show_stakes(
|
||||
use_lamports_unit,
|
||||
&stake_history,
|
||||
&clock,
|
||||
stake_program_v2_enabled,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ use solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*}
|
||||
use solana_cli_output::{
|
||||
display::new_spinner_progress_bar, CliProgram, CliProgramAccountType, CliProgramAuthority,
|
||||
CliProgramBuffer, CliProgramId, CliUpgradeableBuffer, CliUpgradeableBuffers,
|
||||
CliUpgradeableProgram,
|
||||
CliUpgradeableProgram, CliUpgradeableProgramClosed,
|
||||
};
|
||||
use solana_client::{
|
||||
client_error::ClientErrorKind,
|
||||
@@ -23,6 +23,7 @@ use solana_client::{
|
||||
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
|
||||
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
|
||||
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
||||
rpc_response::Fees,
|
||||
tpu_client::{TpuClient, TpuClientConfig},
|
||||
};
|
||||
use solana_rbpf::vm::{Config, Executable};
|
||||
@@ -32,7 +33,6 @@ use solana_sdk::{
|
||||
account_utils::StateMut,
|
||||
bpf_loader, bpf_loader_deprecated,
|
||||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||
clock::Slot,
|
||||
commitment_config::CommitmentConfig,
|
||||
instruction::Instruction,
|
||||
instruction::InstructionError,
|
||||
@@ -330,29 +330,31 @@ impl ProgramSubCommands for App<'_, '_> {
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("close")
|
||||
.about("Close an account and withdraw all lamports")
|
||||
.about("Close a program or buffer account and withdraw all lamports")
|
||||
.arg(
|
||||
Arg::with_name("account")
|
||||
.index(1)
|
||||
.value_name("BUFFER_ACCOUNT_ADDRESS")
|
||||
.value_name("ACCOUNT_ADDRESS")
|
||||
.takes_value(true)
|
||||
.help("Address of the buffer account to close"),
|
||||
.help("Address of the program or buffer account to close"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("buffers")
|
||||
.long("buffers")
|
||||
.conflicts_with("account")
|
||||
.required_unless("account")
|
||||
.help("Close every buffer accounts that match the authority")
|
||||
.help("Close all buffer accounts that match the authority")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("buffer_authority")
|
||||
.long("buffer-authority")
|
||||
Arg::with_name("authority")
|
||||
.long("authority")
|
||||
.alias("buffer-authority")
|
||||
.value_name("AUTHORITY_SIGNER")
|
||||
.takes_value(true)
|
||||
.validator(is_valid_signer)
|
||||
.help("Authority [default: the default configured keypair]")
|
||||
.help("Upgrade or buffer authority [default: the default configured keypair]")
|
||||
)
|
||||
|
||||
.arg(
|
||||
pubkey!(Arg::with_name("recipient_account")
|
||||
.long("recipient")
|
||||
@@ -623,7 +625,7 @@ pub fn parse_program_subcommand(
|
||||
};
|
||||
|
||||
let (authority_signer, authority_pubkey) =
|
||||
signer_of(matches, "buffer_authority", wallet_manager)?;
|
||||
signer_of(matches, "authority", wallet_manager)?;
|
||||
|
||||
let signer_info = default_signer.generate_unique_signers(
|
||||
vec![
|
||||
@@ -857,15 +859,17 @@ fn process_program_deploy(
|
||||
false
|
||||
} else {
|
||||
return Err(format!(
|
||||
"{} is not an upgradeable loader ProgramData account",
|
||||
programdata_address
|
||||
"Program {} has been closed, use a new Program Id",
|
||||
program_pubkey
|
||||
)
|
||||
.into());
|
||||
}
|
||||
} else {
|
||||
return Err(
|
||||
format!("ProgramData account {} does not exist", programdata_address).into(),
|
||||
);
|
||||
return Err(format!(
|
||||
"Program {} has been closed, use a new Program Id",
|
||||
program_pubkey
|
||||
)
|
||||
.into());
|
||||
}
|
||||
} else {
|
||||
return Err(format!("{} is not an upgradeable program", program_pubkey).into());
|
||||
@@ -1193,17 +1197,10 @@ fn process_show(
|
||||
- UpgradeableLoaderState::programdata_data_offset()?,
|
||||
}))
|
||||
} else {
|
||||
Err(format!("Invalid associated ProgramData account {} found for the program {}",
|
||||
programdata_address, account_pubkey)
|
||||
.into(),
|
||||
)
|
||||
Err(format!("Program {} has been closed", account_pubkey).into())
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"Failed to find associated ProgramData account {} for the program {}",
|
||||
programdata_address, account_pubkey
|
||||
)
|
||||
.into())
|
||||
Err(format!("Program {} has been closed", account_pubkey).into())
|
||||
}
|
||||
} else if let Ok(UpgradeableLoaderState::Buffer { authority_address }) =
|
||||
account.state()
|
||||
@@ -1295,18 +1292,10 @@ fn process_dump(
|
||||
f.write_all(program_data)?;
|
||||
Ok(format!("Wrote program to {}", output_location))
|
||||
} else {
|
||||
Err(
|
||||
format!("Invalid associated ProgramData account {} found for the program {}",
|
||||
programdata_address, account_pubkey)
|
||||
.into(),
|
||||
)
|
||||
Err(format!("Program {} has been closed", account_pubkey).into())
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"Failed to find associated ProgramData account {} for the program {}",
|
||||
programdata_address, account_pubkey
|
||||
)
|
||||
.into())
|
||||
Err(format!("Program {} has been closed", account_pubkey).into())
|
||||
}
|
||||
} else if let Ok(UpgradeableLoaderState::Buffer { .. }) = account.state() {
|
||||
let offset = UpgradeableLoaderState::buffer_data_offset().unwrap_or(0);
|
||||
@@ -1338,14 +1327,16 @@ fn close(
|
||||
account_pubkey: &Pubkey,
|
||||
recipient_pubkey: &Pubkey,
|
||||
authority_signer: &dyn Signer,
|
||||
program_pubkey: Option<&Pubkey>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (blockhash, _) = rpc_client.get_recent_blockhash()?;
|
||||
|
||||
let mut tx = Transaction::new_unsigned(Message::new(
|
||||
&[bpf_loader_upgradeable::close(
|
||||
&[bpf_loader_upgradeable::close_any(
|
||||
account_pubkey,
|
||||
recipient_pubkey,
|
||||
&authority_signer.pubkey(),
|
||||
Some(&authority_signer.pubkey()),
|
||||
program_pubkey,
|
||||
)],
|
||||
Some(&config.signers[0].pubkey()),
|
||||
));
|
||||
@@ -1390,64 +1381,92 @@ fn process_close(
|
||||
.get_account_with_commitment(&account_pubkey, config.commitment)?
|
||||
.value
|
||||
{
|
||||
if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state() {
|
||||
if authority_address != Some(authority_signer.pubkey()) {
|
||||
return Err(format!(
|
||||
"Buffer account authority {:?} does not match {:?}",
|
||||
authority_address,
|
||||
Some(authority_signer.pubkey())
|
||||
)
|
||||
.into());
|
||||
} else {
|
||||
close(
|
||||
rpc_client,
|
||||
config,
|
||||
&account_pubkey,
|
||||
&recipient_pubkey,
|
||||
authority_signer,
|
||||
)?;
|
||||
match account.state() {
|
||||
Ok(UpgradeableLoaderState::Buffer { authority_address }) => {
|
||||
if authority_address != Some(authority_signer.pubkey()) {
|
||||
return Err(format!(
|
||||
"Buffer account authority {:?} does not match {:?}",
|
||||
authority_address,
|
||||
Some(authority_signer.pubkey())
|
||||
)
|
||||
.into());
|
||||
} else {
|
||||
close(
|
||||
rpc_client,
|
||||
config,
|
||||
&account_pubkey,
|
||||
&recipient_pubkey,
|
||||
authority_signer,
|
||||
None,
|
||||
)?;
|
||||
|
||||
buffers.push(CliUpgradeableBuffer {
|
||||
address: account_pubkey.to_string(),
|
||||
authority: authority_address
|
||||
.map(|pubkey| pubkey.to_string())
|
||||
.unwrap_or_else(|| "none".to_string()),
|
||||
data_len: 0,
|
||||
lamports: account.lamports,
|
||||
use_lamports_unit,
|
||||
});
|
||||
buffers.push(CliUpgradeableBuffer {
|
||||
address: account_pubkey.to_string(),
|
||||
authority: authority_address
|
||||
.map(|pubkey| pubkey.to_string())
|
||||
.unwrap_or_else(|| "none".to_string()),
|
||||
data_len: 0,
|
||||
lamports: account.lamports,
|
||||
use_lamports_unit,
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(UpgradeableLoaderState::Program {
|
||||
programdata_address: programdata_pubkey,
|
||||
}) => {
|
||||
if let Some(account) = rpc_client
|
||||
.get_account_with_commitment(&programdata_pubkey, config.commitment)?
|
||||
.value
|
||||
{
|
||||
if let Ok(UpgradeableLoaderState::ProgramData {
|
||||
slot: _,
|
||||
upgrade_authority_address: authority_pubkey,
|
||||
}) = account.state()
|
||||
{
|
||||
if authority_pubkey != Some(authority_signer.pubkey()) {
|
||||
return Err(format!(
|
||||
"Program authority {:?} does not match {:?}",
|
||||
authority_pubkey,
|
||||
Some(authority_signer.pubkey())
|
||||
)
|
||||
.into());
|
||||
} else {
|
||||
close(
|
||||
rpc_client,
|
||||
config,
|
||||
&programdata_pubkey,
|
||||
&recipient_pubkey,
|
||||
authority_signer,
|
||||
Some(&account_pubkey),
|
||||
)?;
|
||||
return Ok(config.output_format.formatted_string(
|
||||
&CliUpgradeableProgramClosed {
|
||||
program_id: account_pubkey.to_string(),
|
||||
lamports: account.lamports,
|
||||
use_lamports_unit,
|
||||
},
|
||||
));
|
||||
}
|
||||
} else {
|
||||
return Err(
|
||||
format!("Program {} has been closed", account_pubkey).into()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Err(format!("Program {} has been closed", account_pubkey).into());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(
|
||||
format!("{} is not a Program or Buffer account", account_pubkey).into(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Err(format!(
|
||||
"{} is not an upgradeble loader buffer account",
|
||||
account_pubkey
|
||||
)
|
||||
.into());
|
||||
}
|
||||
} else {
|
||||
return Err(format!("Unable to find the account {}", account_pubkey).into());
|
||||
}
|
||||
} else {
|
||||
let mut bytes = vec![1, 0, 0, 0, 1];
|
||||
bytes.extend_from_slice(authority_signer.pubkey().as_ref());
|
||||
let length = bytes.len();
|
||||
|
||||
let results = rpc_client.get_program_accounts_with_config(
|
||||
&bpf_loader_upgradeable::id(),
|
||||
RpcProgramAccountsConfig {
|
||||
filters: Some(vec![RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary(bs58::encode(bytes).into_string()),
|
||||
encoding: None,
|
||||
})]),
|
||||
account_config: RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::Base64),
|
||||
data_slice: Some(UiDataSliceConfig { offset: 0, length }),
|
||||
..RpcAccountInfoConfig::default()
|
||||
},
|
||||
..RpcProgramAccountsConfig::default()
|
||||
},
|
||||
)?;
|
||||
let results = get_buffers(rpc_client, Some(authority_signer.pubkey()))?;
|
||||
|
||||
for (address, account) in results.iter() {
|
||||
if close(
|
||||
@@ -1456,6 +1475,7 @@ fn process_close(
|
||||
address,
|
||||
&recipient_pubkey,
|
||||
authority_signer,
|
||||
None,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
@@ -1933,8 +1953,12 @@ fn send_deploy_messages(
|
||||
if let Some(write_messages) = write_messages {
|
||||
if let Some(write_signer) = write_signer {
|
||||
trace!("Writing program data");
|
||||
let (blockhash, _, last_valid_slot) = rpc_client
|
||||
.get_recent_blockhash_with_commitment(config.commitment)?
|
||||
let Fees {
|
||||
blockhash,
|
||||
last_valid_block_height,
|
||||
..
|
||||
} = rpc_client
|
||||
.get_fees_with_commitment(config.commitment)?
|
||||
.value;
|
||||
let mut write_transactions = vec![];
|
||||
for message in write_messages.iter() {
|
||||
@@ -1949,7 +1973,7 @@ fn send_deploy_messages(
|
||||
write_transactions,
|
||||
&[payer_signer, write_signer],
|
||||
config.commitment,
|
||||
last_valid_slot,
|
||||
last_valid_block_height,
|
||||
)
|
||||
.map_err(|err| format!("Data writes to account failed: {}", err))?;
|
||||
}
|
||||
@@ -2019,7 +2043,7 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||
mut transactions: Vec<Transaction>,
|
||||
signer_keys: &T,
|
||||
commitment: CommitmentConfig,
|
||||
mut last_valid_slot: Slot,
|
||||
mut last_valid_block_height: u64,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
let progress_bar = new_spinner_progress_bar();
|
||||
let mut send_retries = 5;
|
||||
@@ -2059,7 +2083,7 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||
|
||||
// Collect statuses for all the transactions, drop those that are confirmed
|
||||
loop {
|
||||
let mut slot = 0;
|
||||
let mut block_height = 0;
|
||||
let pending_signatures = pending_transactions.keys().cloned().collect::<Vec<_>>();
|
||||
for pending_signatures_chunk in
|
||||
pending_signatures.chunks(MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS)
|
||||
@@ -2084,12 +2108,12 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||
}
|
||||
}
|
||||
|
||||
slot = rpc_client.get_slot()?;
|
||||
block_height = rpc_client.get_block_height()?;
|
||||
progress_bar.set_message(&format!(
|
||||
"[{}/{}] Transactions confirmed. Retrying in {} slots",
|
||||
"[{}/{}] Transactions confirmed. Retrying in {} blocks",
|
||||
num_transactions - pending_transactions.len(),
|
||||
num_transactions,
|
||||
last_valid_slot.saturating_sub(slot)
|
||||
last_valid_block_height.saturating_sub(block_height)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2097,7 +2121,7 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if slot > last_valid_slot {
|
||||
if block_height > last_valid_block_height {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2127,10 +2151,12 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
||||
send_retries -= 1;
|
||||
|
||||
// Re-sign any failed transactions with a new blockhash and retry
|
||||
let (blockhash, _fee_calculator, new_last_valid_slot) = rpc_client
|
||||
.get_recent_blockhash_with_commitment(commitment)?
|
||||
.value;
|
||||
last_valid_slot = new_last_valid_slot;
|
||||
let Fees {
|
||||
blockhash,
|
||||
last_valid_block_height: new_last_valid_block_height,
|
||||
..
|
||||
} = rpc_client.get_fees_with_commitment(commitment)?.value;
|
||||
last_valid_block_height = new_last_valid_block_height;
|
||||
transactions = vec![];
|
||||
for (_, mut transaction) in pending_transactions.into_iter() {
|
||||
transaction.try_sign(signer_keys, blockhash)?;
|
||||
|
@@ -33,7 +33,6 @@ use solana_sdk::{
|
||||
account_utils::StateMut,
|
||||
clock::{Clock, UnixTimestamp, SECONDS_PER_DAY},
|
||||
epoch_schedule::EpochSchedule,
|
||||
feature, feature_set,
|
||||
message::Message,
|
||||
pubkey::Pubkey,
|
||||
stake::{
|
||||
@@ -1957,7 +1956,6 @@ pub fn build_stake_state(
|
||||
use_lamports_unit: bool,
|
||||
stake_history: &StakeHistory,
|
||||
clock: &Clock,
|
||||
stake_program_v2_enabled: bool,
|
||||
) -> CliStakeState {
|
||||
match stake_state {
|
||||
StakeState::Stake(
|
||||
@@ -1969,12 +1967,9 @@ pub fn build_stake_state(
|
||||
stake,
|
||||
) => {
|
||||
let current_epoch = clock.epoch;
|
||||
let (active_stake, activating_stake, deactivating_stake) =
|
||||
stake.delegation.stake_activating_and_deactivating(
|
||||
current_epoch,
|
||||
Some(stake_history),
|
||||
stake_program_v2_enabled,
|
||||
);
|
||||
let (active_stake, activating_stake, deactivating_stake) = stake
|
||||
.delegation
|
||||
.stake_activating_and_deactivating(current_epoch, Some(stake_history));
|
||||
let lockup = if lockup.is_in_force(clock, None) {
|
||||
Some(lockup.into())
|
||||
} else {
|
||||
@@ -2163,7 +2158,6 @@ pub fn process_show_stake_account(
|
||||
use_lamports_unit,
|
||||
&stake_history,
|
||||
&clock,
|
||||
is_stake_program_v2_enabled(rpc_client)?, // At v1.6, this check can be removed and simply passed as `true`
|
||||
);
|
||||
|
||||
if state.stake_type == CliStakeType::Stake && state.activation_epoch.is_some() {
|
||||
@@ -2346,15 +2340,6 @@ pub fn process_delegate_stake(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_stake_program_v2_enabled(
|
||||
rpc_client: &RpcClient,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let feature_account = rpc_client.get_account(&feature_set::stake_program_v2::id())?;
|
||||
Ok(feature::from_account(&feature_account)
|
||||
.and_then(|feature| feature.activated_at)
|
||||
.is_some())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@@ -525,7 +525,7 @@ fn test_cli_program_deploy_with_authority() {
|
||||
{
|
||||
assert_eq!(upgrade_authority_address, None);
|
||||
} else {
|
||||
panic!("not a buffer account");
|
||||
panic!("not a ProgramData account");
|
||||
}
|
||||
|
||||
// Get buffer authority
|
||||
@@ -548,6 +548,88 @@ fn test_cli_program_deploy_with_authority() {
|
||||
assert_eq!("none", authority_pubkey_str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cli_program_close_program() {
|
||||
solana_logger::setup();
|
||||
|
||||
let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
pathbuf.push("tests");
|
||||
pathbuf.push("fixtures");
|
||||
pathbuf.push("noop");
|
||||
pathbuf.set_extension("so");
|
||||
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
let test_validator =
|
||||
TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified);
|
||||
|
||||
let rpc_client =
|
||||
RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed());
|
||||
|
||||
let mut file = File::open(pathbuf.to_str().unwrap()).unwrap();
|
||||
let mut program_data = Vec::new();
|
||||
file.read_to_end(&mut program_data).unwrap();
|
||||
let max_len = program_data.len();
|
||||
let minimum_balance_for_programdata = rpc_client
|
||||
.get_minimum_balance_for_rent_exemption(
|
||||
UpgradeableLoaderState::programdata_len(max_len).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let minimum_balance_for_program = rpc_client
|
||||
.get_minimum_balance_for_rent_exemption(UpgradeableLoaderState::program_len().unwrap())
|
||||
.unwrap();
|
||||
let upgrade_authority = Keypair::new();
|
||||
|
||||
let mut config = CliConfig::recent_for_tests();
|
||||
let keypair = Keypair::new();
|
||||
config.json_rpc_url = test_validator.rpc_url();
|
||||
config.signers = vec![&keypair];
|
||||
config.command = CliCommand::Airdrop {
|
||||
pubkey: None,
|
||||
lamports: 100 * minimum_balance_for_programdata + minimum_balance_for_program,
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
|
||||
// Deploy the upgradeable program
|
||||
let program_keypair = Keypair::new();
|
||||
config.signers = vec![&keypair, &upgrade_authority, &program_keypair];
|
||||
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
|
||||
program_location: Some(pathbuf.to_str().unwrap().to_string()),
|
||||
program_signer_index: Some(2),
|
||||
program_pubkey: Some(program_keypair.pubkey()),
|
||||
buffer_signer_index: None,
|
||||
buffer_pubkey: None,
|
||||
allow_excessive_balance: false,
|
||||
upgrade_authority_signer_index: 1,
|
||||
is_final: false,
|
||||
max_len: Some(max_len),
|
||||
});
|
||||
config.output_format = OutputFormat::JsonCompact;
|
||||
process_command(&config).unwrap();
|
||||
|
||||
let (programdata_pubkey, _) = Pubkey::find_program_address(
|
||||
&[program_keypair.pubkey().as_ref()],
|
||||
&bpf_loader_upgradeable::id(),
|
||||
);
|
||||
|
||||
// Close program
|
||||
let close_account = rpc_client.get_account(&programdata_pubkey).unwrap();
|
||||
let programdata_lamports = close_account.lamports;
|
||||
let recipient_pubkey = Pubkey::new_unique();
|
||||
config.signers = vec![&keypair, &upgrade_authority];
|
||||
config.command = CliCommand::Program(ProgramCliCommand::Close {
|
||||
account_pubkey: Some(program_keypair.pubkey()),
|
||||
recipient_pubkey,
|
||||
authority_index: 1,
|
||||
use_lamports_unit: false,
|
||||
});
|
||||
process_command(&config).unwrap();
|
||||
rpc_client.get_account(&programdata_pubkey).unwrap_err();
|
||||
let recipient_account = rpc_client.get_account(&recipient_pubkey).unwrap();
|
||||
assert_eq!(programdata_lamports, recipient_account.lamports);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cli_program_write_buffer() {
|
||||
solana_logger::setup();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,7 +15,7 @@ bincode = "1.3.1"
|
||||
bs58 = "0.3.1"
|
||||
clap = "2.33.0"
|
||||
indicatif = "0.15.0"
|
||||
jsonrpc-core = "17.0.0"
|
||||
jsonrpc-core = "18.0.0"
|
||||
log = "0.4.11"
|
||||
net2 = "0.2.37"
|
||||
rayon = "1.5.0"
|
||||
@@ -24,14 +24,14 @@ semver = "0.11.0"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.56"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tungstenite = "0.10.1"
|
||||
@@ -39,8 +39,8 @@ url = "2.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
jsonrpc-http-server = "17.0.0"
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
jsonrpc-http-server = "18.0.0"
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -122,10 +122,10 @@ mod tests {
|
||||
use crate::{
|
||||
blockhash_query,
|
||||
rpc_request::RpcRequest,
|
||||
rpc_response::{Response, RpcFeeCalculator, RpcResponseContext},
|
||||
rpc_response::{Response, RpcFeeCalculator, RpcFees, RpcResponseContext},
|
||||
};
|
||||
use clap::App;
|
||||
use serde_json::{self, json, Value};
|
||||
use serde_json::{self, json};
|
||||
use solana_account_decoder::{UiAccount, UiAccountEncoding};
|
||||
use solana_sdk::{account::Account, hash::hash, nonce, system_program};
|
||||
use std::collections::HashMap;
|
||||
@@ -288,10 +288,12 @@ mod tests {
|
||||
let rpc_fee_calc = FeeCalculator::new(42);
|
||||
let get_recent_blockhash_response = json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: json!((
|
||||
Value::String(rpc_blockhash.to_string()),
|
||||
serde_json::to_value(rpc_fee_calc.clone()).unwrap()
|
||||
)),
|
||||
value: json!(RpcFees {
|
||||
blockhash: rpc_blockhash.to_string(),
|
||||
fee_calculator: rpc_fee_calc.clone(),
|
||||
last_valid_slot: 42,
|
||||
last_valid_block_height: 42,
|
||||
}),
|
||||
});
|
||||
let get_fee_calculator_for_blockhash_response = json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
@@ -300,10 +302,7 @@ mod tests {
|
||||
}),
|
||||
});
|
||||
let mut mocks = HashMap::new();
|
||||
mocks.insert(
|
||||
RpcRequest::GetRecentBlockhash,
|
||||
get_recent_blockhash_response.clone(),
|
||||
);
|
||||
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response.clone());
|
||||
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
||||
assert_eq!(
|
||||
BlockhashQuery::default()
|
||||
@@ -312,10 +311,7 @@ mod tests {
|
||||
(rpc_blockhash, rpc_fee_calc.clone()),
|
||||
);
|
||||
let mut mocks = HashMap::new();
|
||||
mocks.insert(
|
||||
RpcRequest::GetRecentBlockhash,
|
||||
get_recent_blockhash_response.clone(),
|
||||
);
|
||||
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response.clone());
|
||||
mocks.insert(
|
||||
RpcRequest::GetFeeCalculatorForBlockhash,
|
||||
get_fee_calculator_for_blockhash_response,
|
||||
@@ -328,10 +324,7 @@ mod tests {
|
||||
(test_blockhash, rpc_fee_calc),
|
||||
);
|
||||
let mut mocks = HashMap::new();
|
||||
mocks.insert(
|
||||
RpcRequest::GetRecentBlockhash,
|
||||
get_recent_blockhash_response,
|
||||
);
|
||||
mocks.insert(RpcRequest::GetFees, get_recent_blockhash_response);
|
||||
let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks);
|
||||
assert_eq!(
|
||||
BlockhashQuery::None(test_blockhash)
|
||||
|
@@ -1,9 +0,0 @@
|
||||
use crate::{fee_calculator::FeeCalculator, hash::Hash};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Fees {
|
||||
pub blockhash: Hash,
|
||||
pub fee_calculator: FeeCalculator,
|
||||
pub last_valid_block_height: u64,
|
||||
}
|
@@ -1,3 +1,5 @@
|
||||
//! The standard [`RpcSender`] over HTTP.
|
||||
|
||||
use {
|
||||
crate::{
|
||||
client_error::Result,
|
||||
@@ -28,11 +30,19 @@ pub struct HttpSender {
|
||||
request_id: AtomicU64,
|
||||
}
|
||||
|
||||
/// The standard [`RpcSender`] over HTTP.
|
||||
impl HttpSender {
|
||||
/// Create an HTTP RPC sender.
|
||||
///
|
||||
/// The URL is an HTTP URL, usually for port 8899, as in
|
||||
/// "http://localhost:8899". The sender has a default timeout of 30 seconds.
|
||||
pub fn new(url: String) -> Self {
|
||||
Self::new_with_timeout(url, Duration::from_secs(30))
|
||||
}
|
||||
|
||||
/// Create an HTTP RPC sender.
|
||||
///
|
||||
/// The URL is an HTTP URL, usually for port 8899.
|
||||
pub fn new_with_timeout(url: String, timeout: Duration) -> Self {
|
||||
// `reqwest::blocking::Client` panics if run in a tokio async context. Shuttle the
|
||||
// request to a different tokio thread to avoid this
|
||||
@@ -57,7 +67,6 @@ impl HttpSender {
|
||||
struct RpcErrorObject {
|
||||
code: i64,
|
||||
message: String,
|
||||
data: serde_json::Value,
|
||||
}
|
||||
|
||||
impl RpcSender for HttpSender {
|
||||
|
@@ -1,24 +1,37 @@
|
||||
//! An [`RpcSender`] used for unit testing [`RpcClient`](crate::rpc_client::RpcClient).
|
||||
|
||||
use {
|
||||
crate::{
|
||||
client_error::Result,
|
||||
rpc_config::RpcBlockProductionConfig,
|
||||
rpc_request::RpcRequest,
|
||||
rpc_response::{
|
||||
Response, RpcBlockProduction, RpcBlockProductionRange, RpcResponseContext,
|
||||
RpcVersionInfo,
|
||||
Response, RpcAccountBalance, RpcBlockProduction, RpcBlockProductionRange,
|
||||
RpcConfirmedTransactionStatusWithSignature, RpcContactInfo, RpcFees, RpcPerfSample,
|
||||
RpcResponseContext, RpcSimulateTransactionResult, RpcStakeActivation, RpcSupply,
|
||||
RpcVersionInfo, RpcVoteAccountInfo, RpcVoteAccountStatus, StakeActivationState,
|
||||
},
|
||||
rpc_sender::RpcSender,
|
||||
},
|
||||
serde_json::{json, Number, Value},
|
||||
solana_sdk::{
|
||||
clock::{Slot, UnixTimestamp},
|
||||
epoch_info::EpochInfo,
|
||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||
instruction::InstructionError,
|
||||
message::MessageHeader,
|
||||
signature::Signature,
|
||||
sysvar::epoch_schedule::EpochSchedule,
|
||||
transaction::{self, Transaction, TransactionError},
|
||||
},
|
||||
solana_transaction_status::{TransactionConfirmationStatus, TransactionStatus},
|
||||
solana_transaction_status::{
|
||||
EncodedConfirmedBlock, EncodedConfirmedTransaction, EncodedTransaction,
|
||||
EncodedTransactionWithStatusMeta, Rewards, TransactionConfirmationStatus,
|
||||
TransactionStatus, UiCompiledInstruction, UiMessage, UiRawMessage, UiTransaction,
|
||||
UiTransactionEncoding, UiTransactionStatusMeta,
|
||||
},
|
||||
solana_version::Version,
|
||||
std::{collections::HashMap, sync::RwLock},
|
||||
std::{collections::HashMap, net::SocketAddr, sync::RwLock},
|
||||
};
|
||||
|
||||
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
|
||||
@@ -31,6 +44,31 @@ pub struct MockSender {
|
||||
url: String,
|
||||
}
|
||||
|
||||
/// An [`RpcSender`] used for unit testing [`RpcClient`](crate::rpc_client::RpcClient).
|
||||
///
|
||||
/// This is primarily for internal use.
|
||||
///
|
||||
/// Unless directed otherwise, it will generally return a reasonable default
|
||||
/// response, at least for [`RpcRequest`] values for which responses have been
|
||||
/// implemented.
|
||||
///
|
||||
/// The behavior can be customized in two ways:
|
||||
///
|
||||
/// 1) The `url` constructor argument is not actually a URL, but a simple string
|
||||
/// directive that changes `MockSender`s behavior in specific scenarios.
|
||||
///
|
||||
/// If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
|
||||
///
|
||||
/// It is customary to set the `url` to "succeeds" for mocks that should
|
||||
/// return sucessfully, though this value is not actually interpreted.
|
||||
///
|
||||
/// Other possible values of `url` are specific to different `RpcRequest`
|
||||
/// values. Read the implementation for specifics.
|
||||
///
|
||||
/// 2) Custom responses can be configured by providing [`Mocks`] to the
|
||||
/// [`MockSender::new_with_mocks`] constructor. This type is a [`HashMap`]
|
||||
/// from [`RpcRequest`] to a JSON [`Value`] response, Any entries in this map
|
||||
/// override the default behavior for the given request.
|
||||
impl MockSender {
|
||||
pub fn new(url: String) -> Self {
|
||||
Self::new_with_mocks(url, Mocks::default())
|
||||
@@ -94,6 +132,16 @@ impl RpcSender for MockSender {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
|
||||
})?,
|
||||
"getFees" => serde_json::to_value(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: serde_json::to_value(RpcFees {
|
||||
blockhash: PUBKEY.to_string(),
|
||||
fee_calculator: FeeCalculator::default(),
|
||||
last_valid_slot: 42,
|
||||
last_valid_block_height: 42,
|
||||
})
|
||||
.unwrap(),
|
||||
})?,
|
||||
"getSignatureStatuses" => {
|
||||
let status: transaction::Result<()> = if self.url == "account_in_use" {
|
||||
Err(TransactionError::AccountInUse)
|
||||
@@ -128,10 +176,132 @@ impl RpcSender for MockSender {
|
||||
value: statuses,
|
||||
})?
|
||||
}
|
||||
"getTransaction" => serde_json::to_value(EncodedConfirmedTransaction {
|
||||
slot: 2,
|
||||
transaction: EncodedTransactionWithStatusMeta {
|
||||
transaction: EncodedTransaction::Json(
|
||||
UiTransaction {
|
||||
signatures: vec!["3AsdoALgZFuq2oUVWrDYhg2pNeaLJKPLf8hU2mQ6U8qJxeJ6hsrPVpMn9ma39DtfYCrDQSvngWRP8NnTpEhezJpE".to_string()],
|
||||
message: UiMessage::Raw(
|
||||
UiRawMessage {
|
||||
header: MessageHeader {
|
||||
num_required_signatures: 1,
|
||||
num_readonly_signed_accounts: 0,
|
||||
num_readonly_unsigned_accounts: 1,
|
||||
},
|
||||
account_keys: vec![
|
||||
"C6eBmAXKg6JhJWkajGa5YRGUfG4YKXwbxF5Ufv7PtExZ".to_string(),
|
||||
"2Gd5eoR5J4BV89uXbtunpbNhjmw3wa1NbRHxTHzDzZLX".to_string(),
|
||||
"11111111111111111111111111111111".to_string(),
|
||||
],
|
||||
recent_blockhash: "D37n3BSG71oUWcWjbZ37jZP7UfsxG2QMKeuALJ1PYvM6".to_string(),
|
||||
instructions: vec![UiCompiledInstruction {
|
||||
program_id_index: 2,
|
||||
accounts: vec![0, 1],
|
||||
data: "3Bxs49DitAvXtoDR".to_string(),
|
||||
}],
|
||||
})
|
||||
}),
|
||||
meta: Some(UiTransactionStatusMeta {
|
||||
err: None,
|
||||
status: Ok(()),
|
||||
fee: 0,
|
||||
pre_balances: vec![499999999999999950, 50, 1],
|
||||
post_balances: vec![499999999999999950, 50, 1],
|
||||
inner_instructions: None,
|
||||
log_messages: None,
|
||||
pre_token_balances: None,
|
||||
post_token_balances: None,
|
||||
rewards: None,
|
||||
}),
|
||||
},
|
||||
block_time: Some(1628633791),
|
||||
})?,
|
||||
"getTransactionCount" => json![1234],
|
||||
"getSlot" => json![0],
|
||||
"getMaxShredInsertSlot" => json![0],
|
||||
"requestAirdrop" => Value::String(Signature::new(&[8; 64]).to_string()),
|
||||
"getSnapshotSlot" => Value::Number(Number::from(0)),
|
||||
"getBlockHeight" => Value::Number(Number::from(1234)),
|
||||
"getSlotLeaders" => json!([PUBKEY]),
|
||||
"getBlockProduction" => {
|
||||
if params.is_null() {
|
||||
json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: RpcBlockProduction {
|
||||
by_identity: HashMap::new(),
|
||||
range: RpcBlockProductionRange {
|
||||
first_slot: 1,
|
||||
last_slot: 2,
|
||||
},
|
||||
},
|
||||
})
|
||||
} else {
|
||||
let config: Vec<RpcBlockProductionConfig> =
|
||||
serde_json::from_value(params).unwrap();
|
||||
let config = config[0].clone();
|
||||
let mut by_identity = HashMap::new();
|
||||
by_identity.insert(config.identity.unwrap(), (1, 123));
|
||||
let config_range = config.range.unwrap_or_default();
|
||||
|
||||
json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: RpcBlockProduction {
|
||||
by_identity,
|
||||
range: RpcBlockProductionRange {
|
||||
first_slot: config_range.first_slot,
|
||||
last_slot: {
|
||||
if let Some(last_slot) = config_range.last_slot {
|
||||
last_slot
|
||||
} else {
|
||||
2
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
"getStakeActivation" => json!(RpcStakeActivation {
|
||||
state: StakeActivationState::Activating,
|
||||
active: 123,
|
||||
inactive: 12,
|
||||
}),
|
||||
"getSupply" => json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: RpcSupply {
|
||||
total: 100000000,
|
||||
circulating: 50000,
|
||||
non_circulating: 20000,
|
||||
non_circulating_accounts: vec![PUBKEY.to_string()],
|
||||
},
|
||||
}),
|
||||
"getLargestAccounts" => {
|
||||
let rpc_account_balance = RpcAccountBalance {
|
||||
address: PUBKEY.to_string(),
|
||||
lamports: 10000,
|
||||
};
|
||||
|
||||
json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: vec![rpc_account_balance],
|
||||
})
|
||||
}
|
||||
"getVoteAccounts" => {
|
||||
json!(RpcVoteAccountStatus {
|
||||
current: vec![],
|
||||
delinquent: vec![RpcVoteAccountInfo {
|
||||
vote_pubkey: PUBKEY.to_string(),
|
||||
node_pubkey: PUBKEY.to_string(),
|
||||
activated_stake: 0,
|
||||
commission: 0,
|
||||
epoch_vote_account: false,
|
||||
epoch_credits: vec![],
|
||||
last_vote: 0,
|
||||
root_slot: Slot::default(),
|
||||
}],
|
||||
})
|
||||
}
|
||||
"sendTransaction" => {
|
||||
let signature = if self.url == "malicious" {
|
||||
Signature::new(&[8; 64]).to_string()
|
||||
@@ -143,6 +313,14 @@ impl RpcSender for MockSender {
|
||||
};
|
||||
Value::String(signature)
|
||||
}
|
||||
"simulateTransaction" => serde_json::to_value(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: RpcSimulateTransactionResult {
|
||||
err: None,
|
||||
logs: None,
|
||||
accounts: None,
|
||||
},
|
||||
})?,
|
||||
"getMinimumBalanceForRentExemption" => json![20],
|
||||
"getVersion" => {
|
||||
let version = Version::default();
|
||||
@@ -151,19 +329,54 @@ impl RpcSender for MockSender {
|
||||
feature_set: Some(version.feature_set),
|
||||
})
|
||||
}
|
||||
"getBlockProduction" => {
|
||||
let map = vec![(PUBKEY.to_string(), (1, 1))].into_iter().collect();
|
||||
json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: RpcBlockProduction {
|
||||
by_identity: map,
|
||||
range: RpcBlockProductionRange {
|
||||
first_slot: 0,
|
||||
last_slot: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
"getClusterNodes" => serde_json::to_value(vec![RpcContactInfo {
|
||||
pubkey: PUBKEY.to_string(),
|
||||
gossip: Some(SocketAddr::from(([10, 239, 6, 48], 8899))),
|
||||
tpu: Some(SocketAddr::from(([10, 239, 6, 48], 8856))),
|
||||
rpc: Some(SocketAddr::from(([10, 239, 6, 48], 8899))),
|
||||
version: Some("1.0.0 c375ce1f".to_string()),
|
||||
feature_set: None,
|
||||
shred_version: None,
|
||||
}])?,
|
||||
"getBlock" => serde_json::to_value(EncodedConfirmedBlock {
|
||||
previous_blockhash: "mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B".to_string(),
|
||||
blockhash: "3Eq21vXNB5s86c62bVuUfTeaMif1N2kUqRPBmGRJhyTA".to_string(),
|
||||
parent_slot: 429,
|
||||
transactions: vec![EncodedTransactionWithStatusMeta {
|
||||
transaction: EncodedTransaction::Binary(
|
||||
"ju9xZWuDBX4pRxX2oZkTjxU5jB4SSTgEGhX8bQ8PURNzyzqKMPPpNvWihx8zUe\
|
||||
FfrbVNoAaEsNKZvGzAnTDy5bhNT9kt6KFCTBixpvrLCzg4M5UdFUQYrn1gdgjX\
|
||||
pLHxcaShD81xBNaFDgnA2nkkdHnKtZt4hVSfKAmw3VRZbjrZ7L2fKZBx21CwsG\
|
||||
hD6onjM2M3qZW5C8J6d1pj41MxKmZgPBSha3MyKkNLkAGFASK"
|
||||
.to_string(),
|
||||
UiTransactionEncoding::Base58,
|
||||
),
|
||||
meta: None,
|
||||
}],
|
||||
rewards: Rewards::new(),
|
||||
block_time: None,
|
||||
block_height: Some(428),
|
||||
})?,
|
||||
"getBlocks" => serde_json::to_value(vec![1, 2, 3])?,
|
||||
"getBlocksWithLimit" => serde_json::to_value(vec![1, 2, 3])?,
|
||||
"getSignaturesForAddress" => {
|
||||
serde_json::to_value(vec![RpcConfirmedTransactionStatusWithSignature {
|
||||
signature: SIGNATURE.to_string(),
|
||||
slot: 123,
|
||||
err: None,
|
||||
memo: None,
|
||||
block_time: None,
|
||||
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||
}])?
|
||||
}
|
||||
"getBlockTime" => serde_json::to_value(UnixTimestamp::default())?,
|
||||
"getEpochSchedule" => serde_json::to_value(EpochSchedule::default())?,
|
||||
"getRecentPerformanceSamples" => serde_json::to_value(vec![RpcPerfSample {
|
||||
slot: 347873,
|
||||
num_transactions: 125,
|
||||
num_slots: 123,
|
||||
sample_period_secs: 60,
|
||||
}])?,
|
||||
_ => Value::Null,
|
||||
};
|
||||
Ok(val)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ pub struct RpcSendTransactionConfig {
|
||||
pub skip_preflight: bool,
|
||||
pub preflight_commitment: Option<CommitmentLevel>,
|
||||
pub encoding: Option<UiTransactionEncoding>,
|
||||
pub max_retries: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
@@ -116,6 +117,15 @@ pub struct RpcLargestAccountsConfig {
|
||||
pub filter: Option<RpcLargestAccountsFilter>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcSupplyConfig {
|
||||
#[serde(flatten)]
|
||||
pub commitment: Option<CommitmentConfig>,
|
||||
#[serde(default)]
|
||||
pub exclude_non_circulating_accounts_list: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcEpochConfig {
|
||||
|
@@ -1,5 +1,18 @@
|
||||
//! A transport for RPC calls.
|
||||
|
||||
use crate::{client_error::Result, rpc_request::RpcRequest};
|
||||
|
||||
/// A transport for RPC calls.
|
||||
///
|
||||
/// `RpcSender` implements the underlying transport of requests to, and
|
||||
/// responses from, a Solana node, and is used primarily by [`RpcClient`].
|
||||
///
|
||||
/// It is typically implemented by [`HttpSender`] in production, and
|
||||
/// [`MockSender`] in unit tests.
|
||||
///
|
||||
/// [`RpcClient`]: crate::rpc_client::RpcClient
|
||||
/// [`HttpSender`]: crate::http_sender::HttpSender
|
||||
/// [`MockSender`]: crate::mock_sender::MockSender
|
||||
pub trait RpcSender {
|
||||
fn send(&self, request: RpcRequest, params: serde_json::Value) -> Result<serde_json::Value>;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-core"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-core"
|
||||
readme = "../README.md"
|
||||
@@ -43,48 +43,48 @@ retain_mut = "0.1.2"
|
||||
serde = "1.0.122"
|
||||
serde_bytes = "0.11"
|
||||
serde_derive = "1.0.103"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.9" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.9" }
|
||||
solana-poh = { path = "../poh", version = "=1.7.9" }
|
||||
solana-program-test = { path = "../program-test", version = "=1.7.9" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.11" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.11" }
|
||||
solana-poh = { path = "../poh", version = "=1.7.11" }
|
||||
solana-program-test = { path = "../program-test", version = "=1.7.11" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.11" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
spl-token-v2-0 = { package = "spl-token", version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.11" }
|
||||
trees = "0.2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
jsonrpc-core = "17.1.0"
|
||||
jsonrpc-core-client = { version = "17.1.0", features = ["ipc", "ws"] }
|
||||
jsonrpc-core = "18.0.0"
|
||||
jsonrpc-core-client = { version = "18.0.0", features = ["ipc", "ws"] }
|
||||
matches = "0.1.6"
|
||||
num_cpus = "1.13.0"
|
||||
reqwest = { version = "0.11.2", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
serde_json = "1.0.56"
|
||||
serial_test = "0.4.0"
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
symlink = "0.1.0"
|
||||
systemstat = "0.1.5"
|
||||
tokio_02 = { version = "0.2", package = "tokio", features = ["full"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.2"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Service to verify accounts hashes with other trusted validator nodes.
|
||||
//
|
||||
// Each interval, publish the snapshat hash which is the full accounts state
|
||||
// hash on gossip. Monitor gossip for messages from validators in the --trusted-validators
|
||||
// hash on gossip. Monitor gossip for messages from validators in the `--known-validator`s
|
||||
// set and halt the node if a mismatch is detected.
|
||||
|
||||
use crate::snapshot_packager_service::PendingSnapshotPackage;
|
||||
|
@@ -1,20 +1,24 @@
|
||||
use crate::serve_repair::RepairType;
|
||||
use itertools::Itertools;
|
||||
use solana_gossip::{
|
||||
cluster_info::ClusterInfo, contact_info::ContactInfo, crds::Cursor, epoch_slots::EpochSlots,
|
||||
};
|
||||
use solana_runtime::{bank_forks::BankForks, epoch_stakes::NodeIdToVoteAccounts};
|
||||
use solana_sdk::{clock::Slot, pubkey::Pubkey};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap, HashSet},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
use {
|
||||
itertools::Itertools,
|
||||
solana_gossip::{
|
||||
cluster_info::ClusterInfo, contact_info::ContactInfo, crds::Cursor, epoch_slots::EpochSlots,
|
||||
},
|
||||
solana_runtime::{bank::Bank, epoch_stakes::NodeIdToVoteAccounts},
|
||||
solana_sdk::{
|
||||
clock::{Slot, DEFAULT_SLOTS_PER_EPOCH},
|
||||
pubkey::Pubkey,
|
||||
},
|
||||
std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
},
|
||||
};
|
||||
|
||||
// Limit the size of cluster-slots map in case
|
||||
// of receiving bogus epoch slots values.
|
||||
const CLUSTER_SLOTS_TRIM_SIZE: usize = 524_288; // 512K
|
||||
|
||||
pub type SlotPubkeys = HashMap<Pubkey, u64>;
|
||||
pub(crate) type SlotPubkeys = HashMap</*node:*/ Pubkey, /*stake:*/ u64>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ClusterSlots {
|
||||
@@ -25,20 +29,21 @@ pub struct ClusterSlots {
|
||||
}
|
||||
|
||||
impl ClusterSlots {
|
||||
pub fn lookup(&self, slot: Slot) -> Option<Arc<RwLock<SlotPubkeys>>> {
|
||||
pub(crate) fn lookup(&self, slot: Slot) -> Option<Arc<RwLock<SlotPubkeys>>> {
|
||||
self.cluster_slots.read().unwrap().get(&slot).cloned()
|
||||
}
|
||||
|
||||
pub fn update(&self, root: Slot, cluster_info: &ClusterInfo, bank_forks: &RwLock<BankForks>) {
|
||||
self.update_peers(bank_forks);
|
||||
pub(crate) fn update(&self, root_bank: &Bank, cluster_info: &ClusterInfo) {
|
||||
self.update_peers(root_bank);
|
||||
let epoch_slots = {
|
||||
let mut cursor = self.cursor.lock().unwrap();
|
||||
cluster_info.get_epoch_slots(&mut cursor)
|
||||
};
|
||||
self.update_internal(root, epoch_slots);
|
||||
let num_epoch_slots = root_bank.get_slots_in_epoch(root_bank.epoch());
|
||||
self.update_internal(root_bank.slot(), epoch_slots, num_epoch_slots);
|
||||
}
|
||||
|
||||
fn update_internal(&self, root: Slot, epoch_slots_list: Vec<EpochSlots>) {
|
||||
fn update_internal(&self, root: Slot, epoch_slots_list: Vec<EpochSlots>, num_epoch_slots: u64) {
|
||||
// Attach validator's total stake.
|
||||
let epoch_slots_list: Vec<_> = {
|
||||
let validator_stakes = self.validator_stakes.read().unwrap();
|
||||
@@ -53,13 +58,20 @@ impl ClusterSlots {
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
// Discard slots at or before current root or epochs ahead.
|
||||
let slot_range = (root + 1)
|
||||
..root.saturating_add(
|
||||
num_epoch_slots
|
||||
.max(DEFAULT_SLOTS_PER_EPOCH)
|
||||
.saturating_mul(2),
|
||||
);
|
||||
let slot_nodes_stakes = epoch_slots_list
|
||||
.into_iter()
|
||||
.flat_map(|(epoch_slots, stake)| {
|
||||
epoch_slots
|
||||
.to_slots(root)
|
||||
.into_iter()
|
||||
.filter(|slot| *slot > root)
|
||||
.filter(|slot| slot_range.contains(slot))
|
||||
.zip(std::iter::repeat((epoch_slots.from, stake)))
|
||||
})
|
||||
.into_group_map();
|
||||
@@ -89,16 +101,6 @@ impl ClusterSlots {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect(&self, id: &Pubkey) -> HashSet<Slot> {
|
||||
self.cluster_slots
|
||||
.read()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|(_, keys)| keys.read().unwrap().contains_key(id))
|
||||
.map(|(slot, _)| *slot)
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn insert_node_id(&self, slot: Slot, node_id: Pubkey) {
|
||||
let balance = self
|
||||
@@ -118,8 +120,7 @@ impl ClusterSlots {
|
||||
slot_pubkeys.write().unwrap().insert(node_id, balance);
|
||||
}
|
||||
|
||||
fn update_peers(&self, bank_forks: &RwLock<BankForks>) {
|
||||
let root_bank = bank_forks.read().unwrap().root_bank();
|
||||
fn update_peers(&self, root_bank: &Bank) {
|
||||
let root_epoch = root_bank.epoch();
|
||||
let my_epoch = *self.epoch.read().unwrap();
|
||||
|
||||
@@ -135,7 +136,7 @@ impl ClusterSlots {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_weights(&self, slot: Slot, repair_peers: &[ContactInfo]) -> Vec<u64> {
|
||||
pub(crate) fn compute_weights(&self, slot: Slot, repair_peers: &[ContactInfo]) -> Vec<u64> {
|
||||
if repair_peers.is_empty() {
|
||||
return Vec::default();
|
||||
}
|
||||
@@ -165,7 +166,7 @@ impl ClusterSlots {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn compute_weights_exclude_noncomplete(
|
||||
pub(crate) fn compute_weights_exclude_noncomplete(
|
||||
&self,
|
||||
slot: Slot,
|
||||
repair_peers: &[ContactInfo],
|
||||
@@ -181,21 +182,6 @@ impl ClusterSlots {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn generate_repairs_for_missing_slots(
|
||||
&self,
|
||||
self_id: &Pubkey,
|
||||
root: Slot,
|
||||
) -> Vec<RepairType> {
|
||||
let my_slots = self.collect(self_id);
|
||||
self.cluster_slots
|
||||
.read()
|
||||
.unwrap()
|
||||
.keys()
|
||||
.filter(|x| **x > root && !my_slots.contains(*x))
|
||||
.map(|x| RepairType::HighestShred(*x, 0))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -212,7 +198,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_update_noop() {
|
||||
let cs = ClusterSlots::default();
|
||||
cs.update_internal(0, vec![]);
|
||||
cs.update_internal(0, vec![], DEFAULT_SLOTS_PER_EPOCH);
|
||||
assert!(cs.cluster_slots.read().unwrap().is_empty());
|
||||
}
|
||||
|
||||
@@ -220,7 +206,7 @@ mod tests {
|
||||
fn test_update_empty() {
|
||||
let cs = ClusterSlots::default();
|
||||
let epoch_slot = EpochSlots::default();
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
cs.update_internal(0, vec![epoch_slot], DEFAULT_SLOTS_PER_EPOCH);
|
||||
assert!(cs.lookup(0).is_none());
|
||||
}
|
||||
|
||||
@@ -230,7 +216,7 @@ mod tests {
|
||||
let cs = ClusterSlots::default();
|
||||
let mut epoch_slot = EpochSlots::default();
|
||||
epoch_slot.fill(&[0], 0);
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
cs.update_internal(0, vec![epoch_slot], DEFAULT_SLOTS_PER_EPOCH);
|
||||
assert!(cs.lookup(0).is_none());
|
||||
}
|
||||
|
||||
@@ -239,7 +225,7 @@ mod tests {
|
||||
let cs = ClusterSlots::default();
|
||||
let mut epoch_slot = EpochSlots::default();
|
||||
epoch_slot.fill(&[1], 0);
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
cs.update_internal(0, vec![epoch_slot], DEFAULT_SLOTS_PER_EPOCH);
|
||||
assert!(cs.lookup(0).is_none());
|
||||
assert!(cs.lookup(1).is_some());
|
||||
assert_eq!(
|
||||
@@ -369,7 +355,7 @@ mod tests {
|
||||
);
|
||||
|
||||
*cs.validator_stakes.write().unwrap() = map;
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
cs.update_internal(0, vec![epoch_slot], DEFAULT_SLOTS_PER_EPOCH);
|
||||
assert!(cs.lookup(1).is_some());
|
||||
assert_eq!(
|
||||
cs.lookup(1)
|
||||
@@ -380,40 +366,4 @@ mod tests {
|
||||
Some(&1)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_repairs() {
|
||||
let cs = ClusterSlots::default();
|
||||
let mut epoch_slot = EpochSlots::default();
|
||||
epoch_slot.fill(&[1], 0);
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
let self_id = solana_sdk::pubkey::new_rand();
|
||||
assert_eq!(
|
||||
cs.generate_repairs_for_missing_slots(&self_id, 0),
|
||||
vec![RepairType::HighestShred(1, 0)]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect_my_slots() {
|
||||
let cs = ClusterSlots::default();
|
||||
let mut epoch_slot = EpochSlots::default();
|
||||
epoch_slot.fill(&[1], 0);
|
||||
let self_id = epoch_slot.from;
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
let slots: Vec<Slot> = cs.collect(&self_id).into_iter().collect();
|
||||
assert_eq!(slots, vec![1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_repairs_existing() {
|
||||
let cs = ClusterSlots::default();
|
||||
let mut epoch_slot = EpochSlots::default();
|
||||
epoch_slot.fill(&[1], 0);
|
||||
let self_id = epoch_slot.from;
|
||||
cs.update_internal(0, vec![epoch_slot]);
|
||||
assert!(cs
|
||||
.generate_repairs_for_missing_slots(&self_id, 0)
|
||||
.is_empty());
|
||||
}
|
||||
}
|
||||
|
@@ -91,7 +91,6 @@ impl ClusterSlotsService {
|
||||
break;
|
||||
}
|
||||
};
|
||||
let new_root = bank_forks.read().unwrap().root();
|
||||
let mut lowest_slot_elapsed = Measure::start("lowest_slot_elapsed");
|
||||
let lowest_slot = blockstore.lowest_slot();
|
||||
Self::update_lowest_slot(lowest_slot, &cluster_info);
|
||||
@@ -105,7 +104,8 @@ impl ClusterSlotsService {
|
||||
&cluster_info,
|
||||
);
|
||||
}
|
||||
cluster_slots.update(new_root, &cluster_info, &bank_forks);
|
||||
let root_bank = bank_forks.read().unwrap().root_bank();
|
||||
cluster_slots.update(&root_bank, &cluster_info);
|
||||
process_cluster_slots_updates_elapsed.stop();
|
||||
|
||||
cluster_slots_service_timing.update(
|
||||
|
@@ -275,7 +275,20 @@ impl TestValidatorGenesis {
|
||||
/// created at genesis.
|
||||
///
|
||||
/// This function panics on initialization failure.
|
||||
pub fn start(&self, socket_addr_space: SocketAddrSpace) -> (TestValidator, Keypair) {
|
||||
pub fn start(&self) -> (TestValidator, Keypair) {
|
||||
self.start_with_socket_addr_space(SocketAddrSpace::new(/*allow_private_addr=*/ true))
|
||||
}
|
||||
|
||||
/// Start a test validator with the given `SocketAddrSpace`
|
||||
///
|
||||
/// Returns a new `TestValidator` as well as the keypair for the mint account that will receive tokens
|
||||
/// created at genesis.
|
||||
///
|
||||
/// This function panics on initialization failure.
|
||||
pub fn start_with_socket_addr_space(
|
||||
&self,
|
||||
socket_addr_space: SocketAddrSpace,
|
||||
) -> (TestValidator, Keypair) {
|
||||
let mint_keypair = Keypair::new();
|
||||
TestValidator::start(mint_keypair.pubkey(), self, socket_addr_space)
|
||||
.map(|test_validator| (test_validator, mint_keypair))
|
||||
|
@@ -135,6 +135,7 @@ pub struct ValidatorConfig {
|
||||
pub accounts_db_caching_enabled: bool,
|
||||
pub warp_slot: Option<Slot>,
|
||||
pub accounts_db_test_hash_calculation: bool,
|
||||
pub accounts_db_skip_shrink: bool,
|
||||
pub accounts_db_use_index_hash_calculation: bool,
|
||||
pub tpu_coalesce_ms: u64,
|
||||
pub validator_exit: Arc<RwLock<Exit>>,
|
||||
@@ -191,6 +192,7 @@ impl Default for ValidatorConfig {
|
||||
accounts_db_caching_enabled: false,
|
||||
warp_slot: None,
|
||||
accounts_db_test_hash_calculation: false,
|
||||
accounts_db_skip_shrink: false,
|
||||
accounts_db_use_index_hash_calculation: true,
|
||||
tpu_coalesce_ms: DEFAULT_TPU_COALESCE_MS,
|
||||
validator_exit: Arc::new(RwLock::new(Exit::default())),
|
||||
@@ -1112,6 +1114,8 @@ fn new_banks_from_ledger(
|
||||
account_indexes: config.account_indexes.clone(),
|
||||
accounts_db_caching_enabled: config.accounts_db_caching_enabled,
|
||||
shrink_ratio: config.accounts_shrink_ratio,
|
||||
accounts_db_test_hash_calculation: config.accounts_db_test_hash_calculation,
|
||||
accounts_db_skip_shrink: config.accounts_db_skip_shrink,
|
||||
..blockstore_processor::ProcessOptions::default()
|
||||
};
|
||||
|
||||
|
@@ -6,8 +6,10 @@ use reqwest::{self, header::CONTENT_TYPE};
|
||||
use serde_json::{json, Value};
|
||||
use solana_account_decoder::UiAccount;
|
||||
use solana_client::{
|
||||
client_error::{ClientErrorKind, Result as ClientResult},
|
||||
rpc_client::RpcClient,
|
||||
rpc_config::{RpcAccountInfoConfig, RpcSignatureSubscribeConfig},
|
||||
rpc_request::RpcError,
|
||||
rpc_response::{Response, RpcSignatureResult, SlotUpdate},
|
||||
tpu_client::{TpuClient, TpuClientConfig},
|
||||
};
|
||||
@@ -30,7 +32,7 @@ use std::{
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio_02::runtime::Runtime;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
macro_rules! json_req {
|
||||
($method: expr, $params: expr) => {{
|
||||
@@ -169,7 +171,7 @@ fn test_rpc_slot_updates() {
|
||||
let connect = ws::try_connect::<PubsubClient>(&rpc_pubsub_url).unwrap();
|
||||
let client = connect.await.unwrap();
|
||||
|
||||
tokio_02::spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
let mut update_sub = client.slots_updates_subscribe().unwrap();
|
||||
loop {
|
||||
let response = update_sub.next().await.unwrap();
|
||||
@@ -279,7 +281,7 @@ fn test_rpc_subscriptions() {
|
||||
)
|
||||
.unwrap_or_else(|err| panic!("sig sub err: {:#?}", err));
|
||||
|
||||
tokio_02::spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
let response = sig_sub.next().await.unwrap();
|
||||
status_sender
|
||||
.send((sig.clone(), response.unwrap()))
|
||||
@@ -299,7 +301,7 @@ fn test_rpc_subscriptions() {
|
||||
}),
|
||||
)
|
||||
.unwrap_or_else(|err| panic!("acct sub err: {:#?}", err));
|
||||
tokio_02::spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
let response = client_sub.next().await.unwrap();
|
||||
account_sender.send(response.unwrap()).unwrap();
|
||||
});
|
||||
@@ -309,7 +311,7 @@ fn test_rpc_subscriptions() {
|
||||
let mut slot_sub = client
|
||||
.slot_subscribe()
|
||||
.unwrap_or_else(|err| panic!("sig sub err: {:#?}", err));
|
||||
tokio_02::spawn(async move {
|
||||
tokio::spawn(async move {
|
||||
let _response = slot_sub.next().await.unwrap();
|
||||
ready_sender.send(()).unwrap();
|
||||
});
|
||||
@@ -420,3 +422,34 @@ fn test_tpu_send_transaction() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_rpc_error() -> ClientResult<()> {
|
||||
solana_logger::setup();
|
||||
|
||||
let alice = Keypair::new();
|
||||
let validator = TestValidator::with_no_fees(alice.pubkey(), None, SocketAddrSpace::Unspecified);
|
||||
let rpc_client = RpcClient::new(validator.rpc_url());
|
||||
|
||||
let bob = Keypair::new();
|
||||
let lamports = 50;
|
||||
let (recent_blockhash, _) = rpc_client.get_recent_blockhash()?;
|
||||
let mut tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, recent_blockhash);
|
||||
|
||||
// This will cause an error
|
||||
tx.signatures.clear();
|
||||
|
||||
let err = rpc_client.send_transaction(&tx);
|
||||
let err = err.unwrap_err();
|
||||
|
||||
match err.kind {
|
||||
ClientErrorKind::RpcError(RpcError::RpcRequestError { .. }) => {
|
||||
// This is what used to happen
|
||||
panic!()
|
||||
}
|
||||
ClientErrorKind::RpcError(RpcError::RpcResponseError { .. }) => Ok(()),
|
||||
_ => {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -171,6 +171,7 @@ mod tests {
|
||||
None,
|
||||
accounts_db::AccountShrinkThreshold::default(),
|
||||
check_hash_calculation,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-crate-features"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Crate Features"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -25,7 +25,6 @@ serde = { version = "1.0.100", features = ["rc"] }
|
||||
ed25519-dalek = { version = "=1.0.1", features = ["serde"] }
|
||||
syn_0_15 = { package = "syn", version = "0.15.42", features = ["extra-traits", "fold", "full"] }
|
||||
syn_1_0 = { package = "syn", version = "1.0.3", features = ["extra-traits", "fold", "full"] }
|
||||
tokio = { version = "0.1.22",features=["bytes", "codec", "default", "fs", "io", "mio", "num_cpus", "reactor", "rt-full", "sync", "tcp", "timer", "tokio-codec", "tokio-current-thread", "tokio-executor", "tokio-io", "tokio-io", "tokio-reactor", "tokio-tcp", "tokio-tcp", "tokio-threadpool", "tokio-timer", "tokio-udp", "tokio-uds", "udp", "uds"] }
|
||||
winapi = { version = "0.3.8", features=["basetsd", "consoleapi", "errhandlingapi", "fileapi", "handleapi", "impl-debug", "impl-default", "knownfolders", "libloaderapi", "memoryapi", "minwinbase", "minwindef", "ntdef", "ntsecapi", "ntstatus", "objbase", "processenv", "processthreadsapi", "profileapi", "shlobj", "std", "synchapi", "sysinfoapi", "timezoneapi", "utilapiset", "winbase", "wincon", "windef", "winerror", "winnls", "winnt", "winreg", "winsock2", "winuser", "ws2def", "ws2ipdef", "ws2tcpip", "wtypesbase"] }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -44,18 +44,26 @@ solana config set --url https://api.devnet.solana.com
|
||||
$ solana-validator \
|
||||
--identity validator-keypair.json \
|
||||
--vote-account vote-account-keypair.json \
|
||||
--trusted-validator dv1LfzJvDF7S1fBKpFgKoKXK5yoSosmkAdfbxBo1GqJ \
|
||||
--no-untrusted-rpc \
|
||||
--known-validator dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92 \
|
||||
--known-validator dv2eQHeP4RFrJZ6UeiZWoc3XTtmtZCUKxxCApCDcRNV \
|
||||
--known-validator dv4ACNkpYPcE3aKmYDqZm9G5EB3J4MRoeE7WNDRBVJB \
|
||||
--known-validator dv3qDFk1DTF36Z62bNvrCXe9sKATA6xvVy6A798xxAS \
|
||||
--only-known-rpc \
|
||||
--ledger ledger \
|
||||
--rpc-port 8899 \
|
||||
--dynamic-port-range 8000-8010 \
|
||||
--entrypoint entrypoint.devnet.solana.com:8001 \
|
||||
--entrypoint entrypoint2.devnet.solana.com:8001 \
|
||||
--entrypoint entrypoint3.devnet.solana.com:8001 \
|
||||
--entrypoint entrypoint4.devnet.solana.com:8001 \
|
||||
--entrypoint entrypoint5.devnet.solana.com:8001 \
|
||||
--expected-genesis-hash EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG \
|
||||
--wal-recovery-mode skip_any_corrupted_record \
|
||||
--limit-ledger-size
|
||||
```
|
||||
|
||||
The `--trusted-validator`s is operated by Solana
|
||||
The [`--known-validator`s](running-validator/validator-start.md#known-validators)
|
||||
are operated by Solana Labs
|
||||
|
||||
## Testnet
|
||||
|
||||
@@ -88,11 +96,11 @@ solana config set --url https://api.testnet.solana.com
|
||||
$ solana-validator \
|
||||
--identity validator-keypair.json \
|
||||
--vote-account vote-account-keypair.json \
|
||||
--trusted-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \
|
||||
--trusted-validator 7XSY3MrYnK8vq693Rju17bbPkCN3Z7KvvfvJx4kdrsSY \
|
||||
--trusted-validator Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN \
|
||||
--trusted-validator 9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv \
|
||||
--no-untrusted-rpc \
|
||||
--known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \
|
||||
--known-validator 7XSY3MrYnK8vq693Rju17bbPkCN3Z7KvvfvJx4kdrsSY \
|
||||
--known-validator Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN \
|
||||
--known-validator 9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv \
|
||||
--only-known-rpc \
|
||||
--ledger ledger \
|
||||
--rpc-port 8899 \
|
||||
--dynamic-port-range 8000-8010 \
|
||||
@@ -104,17 +112,16 @@ $ solana-validator \
|
||||
--limit-ledger-size
|
||||
```
|
||||
|
||||
The identity of the `--trusted-validator`s are:
|
||||
The identities of the
|
||||
[`--known-validator`s](running-validator/validator-start.md#known-validators) are:
|
||||
|
||||
- `5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on` - Solana Foundation (testnet.solana.com)
|
||||
- `7XSY3MrYnK8vq693Rju17bbPkCN3Z7KvvfvJx4kdrsSY` - Solana Foundation (Break RPC node)
|
||||
- `5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on` - Solana Labs (testnet.solana.com)
|
||||
- `Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN` - Certus One
|
||||
- `9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv` - Algo|Stake
|
||||
|
||||
## Mainnet Beta
|
||||
|
||||
A permissionless, persistent cluster for early token holders and launch partners.
|
||||
Currently, rewards and inflation are disabled.
|
||||
|
||||
- Tokens that are issued on Mainnet Beta are **real** SOL
|
||||
- If you have paid money to purchase/be issued tokens, such as through our
|
||||
@@ -143,11 +150,11 @@ solana config set --url https://api.mainnet-beta.solana.com
|
||||
$ solana-validator \
|
||||
--identity ~/validator-keypair.json \
|
||||
--vote-account ~/vote-account-keypair.json \
|
||||
--trusted-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \
|
||||
--trusted-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ \
|
||||
--trusted-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ \
|
||||
--trusted-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S \
|
||||
--no-untrusted-rpc \
|
||||
--known-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \
|
||||
--known-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ \
|
||||
--known-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ \
|
||||
--known-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S \
|
||||
--only-known-rpc \
|
||||
--ledger ledger \
|
||||
--rpc-port 8899 \
|
||||
--private-rpc \
|
||||
@@ -162,4 +169,5 @@ $ solana-validator \
|
||||
--limit-ledger-size
|
||||
```
|
||||
|
||||
All four `--trusted-validator`s are operated by Solana
|
||||
All four [`--known-validator`s](running-validator/validator-start.md#known-validators)
|
||||
are operated by Solana Labs
|
||||
|
@@ -205,11 +205,11 @@ health-check mechanism for use by load balancers or other network
|
||||
infrastructure. This request will always return a HTTP 200 OK response with a body of
|
||||
"ok", "behind" or "unknown" based on the following conditions:
|
||||
|
||||
1. If one or more `--trusted-validator` arguments are provided to `solana-validator`, "ok" is returned
|
||||
1. If one or more `--known-validator` arguments are provided to `solana-validator`, "ok" is returned
|
||||
when the node has within `HEALTH_CHECK_SLOT_DISTANCE` slots of the highest
|
||||
trusted validator, otherwise "behind". "unknown" is returned when no slot
|
||||
information from trusted validators is not yet available.
|
||||
2. "ok" is always returned if no trusted validators are provided.
|
||||
known validator, otherwise "behind". "unknown" is returned when no slot
|
||||
information from known validators is not yet available.
|
||||
2. "ok" is always returned if no known validators are provided.
|
||||
|
||||
## JSON RPC API Reference
|
||||
|
||||
@@ -1195,10 +1195,10 @@ Result:
|
||||
|
||||
Returns the current health of the node.
|
||||
|
||||
If one or more `--trusted-validator` arguments are provided to
|
||||
If one or more `--known-validator` arguments are provided to
|
||||
`solana-validator`, "ok" is returned when the node has within
|
||||
`HEALTH_CHECK_SLOT_DISTANCE` slots of the highest trusted validator, otherwise
|
||||
an error is returned. "ok" is always returned if no trusted validators are
|
||||
`HEALTH_CHECK_SLOT_DISTANCE` slots of the highest known validator, otherwise
|
||||
an error is returned. "ok" is always returned if no known validators are
|
||||
provided.
|
||||
|
||||
#### Parameters:
|
||||
@@ -2247,7 +2247,7 @@ Result:
|
||||
|
||||
### getSlot
|
||||
|
||||
Returns the current slot the node is processing
|
||||
Returns the slot that has reached the [given or default commitment level](jsonrpc-api.md#configuring-state-commitment)
|
||||
|
||||
#### Parameters:
|
||||
|
||||
@@ -2413,7 +2413,9 @@ Returns information about the current supply.
|
||||
|
||||
#### Parameters:
|
||||
|
||||
- `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||
- (optional) `excludeNonCirculatingAccountsList: <bool>` - exclude non circulating accounts list from response
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -2422,7 +2424,7 @@ The result will be an RpcResponse JSON object with `value` equal to a JSON objec
|
||||
- `total: <u64>` - Total supply in lamports
|
||||
- `circulating: <u64>` - Circulating supply in lamports
|
||||
- `nonCirculating: <u64>` - Non-circulating supply in lamports
|
||||
- `nonCirculatingAccounts: <array>` - an array of account addresses of non-circulating accounts, as strings
|
||||
- `nonCirculatingAccounts: <array>` - an array of account addresses of non-circulating accounts, as strings. If `excludeNonCirculatingAccountsList` is enabled, the returned array will be empty.
|
||||
|
||||
#### Example:
|
||||
|
||||
@@ -3037,7 +3039,7 @@ curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
||||
|
||||
Result:
|
||||
```json
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.7.9"},"id":1}
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.7.11"},"id":1}
|
||||
```
|
||||
|
||||
### getVoteAccounts
|
||||
@@ -3244,6 +3246,8 @@ submission.
|
||||
- `skipPreflight: <bool>` - if true, skip the preflight transaction checks (default: false)
|
||||
- `preflightCommitment: <string>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) level to use for preflight (default: `"finalized"`).
|
||||
- `encoding: <string>` - (optional) Encoding used for the transaction data. Either `"base58"` (*slow*, **DEPRECATED**), or `"base64"`. (default: `"base58"`).
|
||||
- `maxRetries: <usize>` - (optional) Maximum number of times for the RPC node to retry sending the transaction to the leader.
|
||||
If this parameter not provided, the RPC node will retry the transaction until it is finalized or until the blockhash expires.
|
||||
|
||||
#### Results:
|
||||
|
||||
|
@@ -8,7 +8,7 @@ Storage rent can be paid via one of two methods:
|
||||
|
||||
Method 1: Set it and forget it
|
||||
|
||||
With this approach, accounts with two-years worth of rent deposits secured are exempt from network rent charges. By maintaining this minimum-balance, the broader network benefits from reduced liquidity and the account holder can trust that their `Account::data` will be retained for continual access/usage.
|
||||
With this approach, accounts with two-years worth of rent deposits secured are exempt from network rent charges. By maintaining this minimum-balance, the broader network benefits from reduced liquidity and the account holder can rest assured that their `Account::data` will be retained for continual access/usage.
|
||||
|
||||
Method 2: Pay per byte
|
||||
|
||||
|
@@ -23,6 +23,6 @@ Running a Solana validation-client required relatively modest upfront hardware c
|
||||
|
||||
**Table 2** example high-end hardware setup for running a Solana client.
|
||||
|
||||
Despite the low-barrier to entry as a validation-client, from a capital investment perspective, as in any developing economy, there will be much opportunity and need for trusted validation services as evidenced by node reliability, UX/UI, APIs and other software accessibility tools. Additionally, although Solana’s validator node startup costs are nominal when compared to similar networks, they may still be somewhat restrictive for some potential participants. In the spirit of developing a true decentralized, permissionless network, these interested parties can become involved in the Solana network/economy via delegation of previously acquired tokens with a reliable validation node to earn a portion of the interest generated.
|
||||
Despite the low-barrier to entry as a validation-client, from a capital investment perspective, as in any developing economy, there will be much opportunity and need for competent validation services as evidenced by node reliability, UX/UI, APIs and other software accessibility tools. Additionally, although Solana’s validator node startup costs are nominal when compared to similar networks, they may still be somewhat restrictive for some potential participants. In the spirit of developing a true decentralized, permissionless network, these interested parties can become involved in the Solana network/economy via delegation of previously acquired tokens with a reliable validation node to earn a portion of the interest generated.
|
||||
|
||||
Delegation of tokens to validation-clients provides a way for passive Solana token holders to become part of the active Solana economy and earn interest rates proportional to the interest rate generated by the delegated validation-client. Additionally, this feature intends to create a healthy validation-client market, with potential validation-client nodes competing to build reliable, transparent and profitable delegation services.
|
||||
|
@@ -4,7 +4,7 @@ title: Cluster Software Installation and Updates
|
||||
|
||||
Currently users are required to build the solana cluster software themselves from the git repository and manually update it, which is error prone and inconvenient.
|
||||
|
||||
This document proposes an easy to use software install and updater that can be used to deploy pre-built binaries for supported platforms. Users may elect to use binaries supplied by Solana or any other party they trust. Deployment of updates is managed using an on-chain update manifest program.
|
||||
This document proposes an easy to use software install and updater that can be used to deploy pre-built binaries for supported platforms. Users may elect to use binaries supplied by Solana or any other party provider. Deployment of updates is managed using an on-chain update manifest program.
|
||||
|
||||
## Motivating Examples
|
||||
|
||||
|
@@ -24,7 +24,7 @@ A deterministic description of token issuance over time. The Solana Foundation i
|
||||
|
||||
The inflation rate actually observed on the Solana network after accounting for other factors that might decrease the _Total Current Supply_. Note that it is not possible for tokens to be created outside of what is described by the _Inflation Schedule_.
|
||||
|
||||
- While the _Inflation Schedule_ determines how the protocol issues SOL, this neglects the concurrent elimination of tokens in the ecosystem due to various factors. The primary token burning mechanism is the burning of a portion of each transaction fee. While $100\%$ of each transaction fee is currently being destroyed, it is planned on reducing this burn rate to $50\%$ of each transaction fee, with the remaining fee to be retained by the validator that processes the transaction.
|
||||
- While the _Inflation Schedule_ determines how the protocol issues SOL, this neglects the concurrent elimination of tokens in the ecosystem due to various factors. The primary token burning mechanism is the burning of a portion of each transaction fee. $50\%$ of each transaction fee is burned, with the remaining fee retained by the validator that processes the transaction.
|
||||
- Additional factors such as loss of private keys and slashing events should also be considered in a holistic analysis of the _Effective Inflation Rate_. For example, it’s estimated that $10-20\%$ of all BTC have been lost and are unrecoverable and that networks may experience similar yearly losses at the rate of $1-2\%$.
|
||||
|
||||
### Staking Yield [%]
|
||||
|
@@ -13,8 +13,8 @@ operations with a bundled monitoring tool.
|
||||
|
||||
This setup enables you:
|
||||
|
||||
- to have a trusted gateway to the Solana mainnet-beta cluster to get data and
|
||||
submit withdrawal transactions
|
||||
- to have a self-administered gateway to the Solana mainnet-beta cluster to get
|
||||
data and submit withdrawal transactions
|
||||
- to have full control over how much historical block data is retained
|
||||
- to maintain your service availability even if one node fails
|
||||
|
||||
@@ -37,8 +37,8 @@ solana-validator \
|
||||
--no-voting \
|
||||
--enable-rpc-transaction-history \
|
||||
--limit-ledger-size \
|
||||
--trusted-validator <VALIDATOR_ADDRESS> \
|
||||
--no-untrusted-rpc
|
||||
--known-validator <VALIDATOR_ADDRESS> \
|
||||
--only-known-rpc
|
||||
```
|
||||
|
||||
Customize `--ledger` to your desired ledger storage location, and `--rpc-port` to the port you want to expose.
|
||||
@@ -56,7 +56,7 @@ default limit value used by `--limit-ledger-size`. More information about
|
||||
selecting a custom limit value is [available
|
||||
here](https://github.com/solana-labs/solana/blob/583cec922b6107e0f85c7e14cb5e642bc7dfb340/core/src/ledger_cleanup_service.rs#L15-L26).
|
||||
|
||||
Specifying one or more `--trusted-validator` parameters can protect you from booting from a malicious snapshot. [More on the value of booting with trusted validators](../running-validator/validator-start.md#trusted-validators)
|
||||
Specifying one or more `--known-validator` parameters can protect you from booting from a malicious snapshot. [More on the value of booting with known validators](../running-validator/validator-start.md#known-validators)
|
||||
|
||||
Optional parameters to consider:
|
||||
|
||||
@@ -97,7 +97,7 @@ announcement. For security-related releases, more urgent action may be needed.
|
||||
### Ledger Continuity
|
||||
|
||||
By default, each of your nodes will boot from a snapshot provided by one of your
|
||||
trusted validators. This snapshot reflects the current state of the chain, but
|
||||
known validators. This snapshot reflects the current state of the chain, but
|
||||
does not contain the complete historical ledger. If one of your node exits and
|
||||
boots from a new snapshot, there may be a gap in the ledger on that node. In
|
||||
order to prevent this issue, add the `--no-snapshot-fetch` parameter to your
|
||||
@@ -112,7 +112,7 @@ It is important to note that the amount of historical ledger available to your
|
||||
nodes from the rest of the network is limited at any point in time. Once
|
||||
operational if your validators experience significant downtime they may not be
|
||||
able to catch up to the network and will need to download a new snapshot from a
|
||||
trusted validator. In doing so your validators will now have a gap in its
|
||||
known validator. In doing so your validators will now have a gap in its
|
||||
historical ledger data that cannot be filled.
|
||||
|
||||
### Minimizing Validator Port Exposure
|
||||
|
@@ -8,11 +8,11 @@ Solana is an open source project implementing a new, high-performance, permissio
|
||||
|
||||
## Why Solana?
|
||||
|
||||
It is possible for a centralized database to process 710,000 transactions per second on a standard gigabit network if the transactions are, on average, no more than 176 bytes. A centralized database can also replicate itself and maintain high availability without significantly compromising that transaction rate using the distributed system technique known as Optimistic Concurrency Control [\[H.T.Kung, J.T.Robinson (1981)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.65.4735). At Solana, we are demonstrating that these same theoretical limits apply just as well to blockchain on an adversarial network. The key ingredient? Finding a way to share time when nodes cannot trust one-another. Once nodes can trust time, suddenly ~40 years of distributed systems research becomes applicable to blockchain!
|
||||
It is possible for a centralized database to process 710,000 transactions per second on a standard gigabit network if the transactions are, on average, no more than 176 bytes. A centralized database can also replicate itself and maintain high availability without significantly compromising that transaction rate using the distributed system technique known as Optimistic Concurrency Control [\[H.T.Kung, J.T.Robinson (1981)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.65.4735). At Solana, we are demonstrating that these same theoretical limits apply just as well to blockchain on an adversarial network. The key ingredient? Finding a way to share time when nodes cannot rely upon one-another. Once nodes can rely upon time, suddenly ~40 years of distributed systems research becomes applicable to blockchain!
|
||||
|
||||
> Perhaps the most striking difference between algorithms obtained by our method and ones based upon timeout is that using timeout produces a traditional distributed algorithm in which the processes operate asynchronously, while our method produces a globally synchronous one in which every process does the same thing at (approximately) the same time. Our method seems to contradict the whole purpose of distributed processing, which is to permit different processes to operate independently and perform different functions. However, if a distributed system is really a single system, then the processes must be synchronized in some way. Conceptually, the easiest way to synchronize processes is to get them all to do the same thing at the same time. Therefore, our method is used to implement a kernel that performs the necessary synchronization--for example, making sure that two different processes do not try to modify a file at the same time. Processes might spend only a small fraction of their time executing the synchronizing kernel; the rest of the time, they can operate independently--e.g., accessing different files. This is an approach we have advocated even when fault-tolerance is not required. The method's basic simplicity makes it easier to understand the precise properties of a system, which is crucial if one is to know just how fault-tolerant the system is. [\[L.Lamport (1984)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.71.1078)
|
||||
|
||||
Furthermore, and much to our surprise, it can be implemented using a mechanism that has existed in Bitcoin since day one. The Bitcoin feature is called nLocktime and it can be used to postdate transactions using block height instead of a timestamp. As a Bitcoin client, you would use block height instead of a timestamp if you don't trust the network. Block height turns out to be an instance of what's being called a Verifiable Delay Function in cryptography circles. It's a cryptographically secure way to say time has passed. In Solana, we use a far more granular verifiable delay function, a SHA 256 hash chain, to checkpoint the ledger and coordinate consensus. With it, we implement Optimistic Concurrency Control and are now well en route towards that theoretical limit of 710,000 transactions per second.
|
||||
Furthermore, and much to our surprise, it can be implemented using a mechanism that has existed in Bitcoin since day one. The Bitcoin feature is called nLocktime and it can be used to postdate transactions using block height instead of a timestamp. As a Bitcoin client, you would use block height instead of a timestamp if you don't rely upon the network. Block height turns out to be an instance of what's being called a Verifiable Delay Function in cryptography circles. It's a cryptographically secure way to say time has passed. In Solana, we use a far more granular verifiable delay function, a SHA 256 hash chain, to checkpoint the ledger and coordinate consensus. With it, we implement Optimistic Concurrency Control and are now well en route towards that theoretical limit of 710,000 transactions per second.
|
||||
|
||||
## Documentation Overview
|
||||
|
||||
|
@@ -17,7 +17,7 @@ static content and less appealing for transaction processing. The clients poll
|
||||
for transaction status instead of being notified, giving the false impression
|
||||
of higher confirmation times. Furthermore, what clients can poll for is
|
||||
limited, preventing them from making reasonable real-time decisions, such as
|
||||
recognizing a transaction is confirmed as soon as particular, trusted
|
||||
recognizing a transaction is confirmed as soon as particular, known
|
||||
validators vote on it.
|
||||
|
||||
## Proposed Solution
|
||||
|
@@ -54,9 +54,9 @@ Post something like the following to #announcements (adjusting the text as appro
|
||||
> --hard-fork SLOT_X # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART
|
||||
> --no-snapshot-fetch # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART
|
||||
> --entrypoint entrypoint.testnet.solana.com:8001
|
||||
> --trusted-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on
|
||||
> --known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on
|
||||
> --expected-genesis-hash 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY
|
||||
> --no-untrusted-rpc
|
||||
> --only-known-rpc
|
||||
> --limit-ledger-size
|
||||
> ... # <-- your other --identity/--vote-account/etc arguments
|
||||
> ```
|
||||
@@ -68,9 +68,9 @@ Post something like the following to #announcements (adjusting the text as appro
|
||||
> --wait-for-supermajority SLOT_X # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART
|
||||
> --expected-bank-hash NEW_BANK_HASH # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART
|
||||
> --entrypoint entrypoint.testnet.solana.com:8001
|
||||
> --trusted-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on
|
||||
> --known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on
|
||||
> --expected-genesis-hash 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY
|
||||
> --no-untrusted-rpc
|
||||
> --only-known-rpc
|
||||
> --limit-ledger-size
|
||||
> ... # <-- your other --identity/--vote-account/etc arguments
|
||||
> ```
|
||||
|
@@ -89,7 +89,7 @@ sudo sysctl -p /etc/sysctl.d/20-solana-udp-buffers.conf
|
||||
```bash
|
||||
sudo bash -c "cat >/etc/sysctl.d/20-solana-mmaps.conf <<EOF
|
||||
# Increase memory mapped files limit
|
||||
vm.max_map_count = 700000
|
||||
vm.max_map_count = 1000000
|
||||
EOF"
|
||||
```
|
||||
|
||||
@@ -100,14 +100,14 @@ sudo sysctl -p /etc/sysctl.d/20-solana-mmaps.conf
|
||||
Add
|
||||
|
||||
```
|
||||
LimitNOFILE=700000
|
||||
LimitNOFILE=1000000
|
||||
```
|
||||
|
||||
to the `[Service]` section of your systemd service file, if you use one,
|
||||
otherwise add
|
||||
|
||||
```
|
||||
DefaultLimitNOFILE=700000
|
||||
DefaultLimitNOFILE=1000000
|
||||
```
|
||||
|
||||
to the `[Manager]` section of `/etc/systemd/system.conf`.
|
||||
@@ -119,7 +119,7 @@ sudo systemctl daemon-reload
|
||||
```bash
|
||||
sudo bash -c "cat >/etc/security/limits.d/90-solana-nofiles.conf <<EOF
|
||||
# Increase process file descriptor count limit
|
||||
* - nofile 700000
|
||||
* - nofile 1000000
|
||||
EOF"
|
||||
```
|
||||
|
||||
@@ -258,15 +258,15 @@ solana create-vote-account ~/vote-account-keypair.json ~/validator-keypair.json
|
||||
|
||||
Read more about [creating and managing a vote account](vote-accounts.md).
|
||||
|
||||
## Trusted validators
|
||||
## Known validators
|
||||
|
||||
If you know and trust other validator nodes, you can specify this on the command line with the `--trusted-validator <PUBKEY>`
|
||||
argument to `solana-validator`. You can specify multiple ones by repeating the argument `--trusted-validator <PUBKEY1> --trusted-validator <PUBKEY2>`.
|
||||
This has two effects, one is when the validator is booting with `--no-untrusted-rpc`, it will only ask that set of
|
||||
trusted nodes for downloading genesis and snapshot data. Another is that in combination with the `--halt-on-trusted-validator-hash-mismatch` option,
|
||||
it will monitor the merkle root hash of the entire accounts state of other trusted nodes on gossip and if the hashes produce any mismatch,
|
||||
If you know and respect other validator operators, you can specify this on the command line with the `--known-validator <PUBKEY>`
|
||||
argument to `solana-validator`. You can specify multiple ones by repeating the argument `--known-validator <PUBKEY1> --known-validator <PUBKEY2>`.
|
||||
This has two effects, one is when the validator is booting with `--only-known-rpc`, it will only ask that set of
|
||||
known nodes for downloading genesis and snapshot data. Another is that in combination with the `--halt-on-known-validator-hash-mismatch` option,
|
||||
it will monitor the merkle root hash of the entire accounts state of other known nodes on gossip and if the hashes produce any mismatch,
|
||||
the validator will halt the node to prevent the validator from voting or processing potentially incorrect state values. At the moment, the slot that
|
||||
the validator publishes the hash on is tied to the snapshot interval. For the feature to be effective, all validators in the trusted
|
||||
the validator publishes the hash on is tied to the snapshot interval. For the feature to be effective, all validators in the known
|
||||
set should be set to the same snapshot interval value or multiples of the same.
|
||||
|
||||
It is highly recommended you use these options to prevent malicious snapshot state download or
|
||||
@@ -349,7 +349,7 @@ Type=simple
|
||||
Restart=always
|
||||
RestartSec=1
|
||||
User=sol
|
||||
LimitNOFILE=700000
|
||||
LimitNOFILE=1000000
|
||||
LogRateLimitIntervalSec=0
|
||||
Environment="PATH=/bin:/usr/bin:/home/sol/.local/share/solana/install/active_release/bin"
|
||||
ExecStart=/home/sol/bin/validator.sh
|
||||
|
@@ -8,7 +8,7 @@ Storage rent can be paid via one of two methods:
|
||||
|
||||
Method 1: Set it and forget it
|
||||
|
||||
With this approach, accounts with two-years worth of rent deposits secured are exempt from network rent charges. By maintaining this minimum-balance, the broader network benefits from reduced liquidity and the account holder can trust that their `Account::data` will be retained for continual access/usage.
|
||||
With this approach, accounts with two-years worth of rent deposits secured are exempt from network rent charges. By maintaining this minimum-balance, the broader network benefits from reduced liquidity and the account holder can rest assured that their `Account::data` will be retained for continual access/usage.
|
||||
|
||||
Method 2: Pay per byte
|
||||
|
||||
|
@@ -82,6 +82,7 @@ For full usage details run:
|
||||
solana-keygen new --help
|
||||
```
|
||||
|
||||
|
||||
### Public Key Derivation
|
||||
|
||||
Public keys can be derived from a seed phrase and a passphrase if you choose to
|
||||
@@ -107,11 +108,17 @@ solana-keygen pubkey prompt:// --skip-seed-phrase-validation
|
||||
```
|
||||
|
||||
After entering your seed phrase with `solana-keygen pubkey prompt://` the console
|
||||
will display a string of base-58 character. This is the base _wallet address_
|
||||
will display a string of base-58 character. This is the [derived](#hierarchical-derivation) solana BIP44 _wallet address_
|
||||
associated with your seed phrase.
|
||||
|
||||
> Copy the derived address to a USB stick for easy usage on networked computers
|
||||
|
||||
If needed, you can access the legacy, raw keypair's pubkey by instead passing the `ASK` keyword:
|
||||
|
||||
```bash
|
||||
solana-keygen pubkey ASK
|
||||
```
|
||||
|
||||
> A common next step is to [check the balance](#checking-account-balance) of the account associated with a public key
|
||||
|
||||
For full usage details run:
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-dos"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,17 +14,17 @@ clap = "2.33.1"
|
||||
log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-download-utils"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Download Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,9 +15,9 @@ console = "0.14.1"
|
||||
indicatif = "0.15.0"
|
||||
log = "0.4.11"
|
||||
reqwest = { version = "0.11.2", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
tar = "0.4.28"
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
tar = "0.4.37"
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-faucet"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Faucet"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,12 +16,12 @@ clap = "2.33"
|
||||
log = "0.4.11"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-frozen-abi"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Frozen ABI"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,11 +16,11 @@ log = "0.4.11"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
sha2 = "0.9.2"
|
||||
solana-frozen-abi-macro = { path = "macro", version = "=1.7.9" }
|
||||
solana-frozen-abi-macro = { path = "macro", version = "=1.7.11" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
generic-array = { version = "0.14.3", default-features = false, features = ["serde", "more_lengths"]}
|
||||
memmap2 = "0.1.0"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-frozen-abi-macro"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Frozen ABI Macro"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-genesis-utils"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Genesis Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,9 +10,9 @@ documentation = "https://docs.rs/solana-download-utils"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-genesis"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -16,16 +16,16 @@ chrono = "0.4"
|
||||
serde = "1.0.122"
|
||||
serde_json = "1.0.56"
|
||||
serde_yaml = "0.8.13"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.9" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.11" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-gossip"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -26,22 +26,22 @@ rayon = "1.5.0"
|
||||
serde = "1.0.122"
|
||||
serde_bytes = "0.11"
|
||||
serde_derive = "1.0.103"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.11" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.7.11" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.11" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-install"
|
||||
description = "The solana cluster software installer"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -25,14 +25,14 @@ reqwest = { version = "0.11.2", default-features = false, features = ["blocking"
|
||||
serde = { version = "1.0.122", features = ["derive"] }
|
||||
serde_json = "1.0.62"
|
||||
serde_yaml = "0.8.13"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
semver = "0.9.0"
|
||||
tar = "0.4.28"
|
||||
tar = "0.4.37"
|
||||
tempfile = "3.1.0"
|
||||
url = "2.1.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-keygen"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana key generation utility"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,11 +14,11 @@ bs58 = "0.3.1"
|
||||
clap = "2.33"
|
||||
dirs-next = "2.0.0"
|
||||
num_cpus = "1.13.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.9" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.7.11" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
tiny-bip39 = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-ledger-tool"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -23,23 +23,23 @@ regex = "1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.56"
|
||||
serde_yaml = "0.8.13"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.9" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.11" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
tempfile = "3.1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "1.0"
|
||||
assert_cmd = "2.0"
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
signal-hook = "0.1.15"
|
||||
|
@@ -33,8 +33,6 @@ use solana_runtime::{
|
||||
use solana_sdk::{
|
||||
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
||||
clock::{Epoch, Slot},
|
||||
feature::{self, Feature},
|
||||
feature_set,
|
||||
genesis_config::{ClusterType, GenesisConfig},
|
||||
hash::Hash,
|
||||
inflation::Inflation,
|
||||
@@ -1278,14 +1276,6 @@ fn main() {
|
||||
.possible_values(&["pico", "full", "none"])
|
||||
.help("Overwrite inflation when warping"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("enable_stake_program_v2")
|
||||
.required(false)
|
||||
.long("enable-stake-program-v2")
|
||||
.takes_value(false)
|
||||
.help("Enable stake program v2 (several inflation-related staking \
|
||||
bugs are feature-gated behind this)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("recalculate_capitalization")
|
||||
.required(false)
|
||||
@@ -2281,95 +2271,6 @@ fn main() {
|
||||
.lazy_rent_collection
|
||||
.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
let feature_account_balance = std::cmp::max(
|
||||
genesis_config.rent.minimum_balance(Feature::size_of()),
|
||||
1,
|
||||
);
|
||||
if arg_matches.is_present("enable_stake_program_v2") {
|
||||
let mut force_enabled_count = 0;
|
||||
if base_bank
|
||||
.get_account(&feature_set::stake_program_v2::id())
|
||||
.is_none()
|
||||
{
|
||||
base_bank.store_account(
|
||||
&feature_set::stake_program_v2::id(),
|
||||
&feature::create_account(
|
||||
&Feature { activated_at: None },
|
||||
feature_account_balance,
|
||||
),
|
||||
);
|
||||
force_enabled_count += 1;
|
||||
}
|
||||
if base_bank
|
||||
.get_account(&feature_set::rewrite_stake::id())
|
||||
.is_none()
|
||||
{
|
||||
base_bank.store_account(
|
||||
&feature_set::rewrite_stake::id(),
|
||||
&feature::create_account(
|
||||
&Feature { activated_at: None },
|
||||
feature_account_balance,
|
||||
),
|
||||
);
|
||||
force_enabled_count += 1;
|
||||
}
|
||||
|
||||
if force_enabled_count == 0 {
|
||||
warn!("Already stake_program_v2 is activated (or scheduled)");
|
||||
}
|
||||
|
||||
let mut store_failed_count = 0;
|
||||
if force_enabled_count >= 1 {
|
||||
if base_bank
|
||||
.get_account(&feature_set::spl_token_v2_multisig_fix::id())
|
||||
.is_some()
|
||||
{
|
||||
// steal some lamports from the pretty old feature not to affect
|
||||
// capitalizaion, which doesn't affect inflation behavior!
|
||||
base_bank.store_account(
|
||||
&feature_set::spl_token_v2_multisig_fix::id(),
|
||||
&AccountSharedData::default(),
|
||||
);
|
||||
force_enabled_count -= 1;
|
||||
} else {
|
||||
store_failed_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if force_enabled_count >= 1 {
|
||||
if base_bank
|
||||
.get_account(&feature_set::instructions_sysvar_enabled::id())
|
||||
.is_some()
|
||||
{
|
||||
// steal some lamports from the pretty old feature not to affect
|
||||
// capitalizaion, which doesn't affect inflation behavior!
|
||||
base_bank.store_account(
|
||||
&feature_set::instructions_sysvar_enabled::id(),
|
||||
&AccountSharedData::default(),
|
||||
);
|
||||
force_enabled_count -= 1;
|
||||
} else {
|
||||
store_failed_count += 1;
|
||||
}
|
||||
}
|
||||
assert_eq!(force_enabled_count, store_failed_count);
|
||||
if store_failed_count >= 1 {
|
||||
// we have no choice; maybe locally created blank cluster with
|
||||
// not-Development cluster type.
|
||||
let old_cap = base_bank.set_capitalization();
|
||||
let new_cap = base_bank.capitalization();
|
||||
warn!(
|
||||
"Skewing capitalization a bit to enable stake_program_v2 as \
|
||||
requested: increasing {} from {} to {}",
|
||||
feature_account_balance, old_cap, new_cap,
|
||||
);
|
||||
assert_eq!(
|
||||
old_cap + feature_account_balance * store_failed_count,
|
||||
new_cap
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct PointDetail {
|
||||
epoch: Epoch,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ledger"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana ledger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -33,21 +33,21 @@ rayon = "1.5.0"
|
||||
serde = "1.0.122"
|
||||
serde_bytes = "0.11.5"
|
||||
sha2 = "0.9.2"
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.7.9" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.7.9" }
|
||||
solana-storage-proto = { path = "../storage-proto", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.7.11" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.11" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.11" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.7.11" }
|
||||
solana-storage-proto = { path = "../storage-proto", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
@@ -72,7 +72,7 @@ features = ["lz4"]
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
matches = "0.1.6"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.7.11" }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.2"
|
||||
|
@@ -144,6 +144,7 @@ fn load_from_snapshot(
|
||||
process_options.limit_load_slot_count_from_snapshot,
|
||||
process_options.shrink_ratio,
|
||||
process_options.accounts_db_test_hash_calculation,
|
||||
process_options.accounts_db_skip_shrink,
|
||||
)
|
||||
.expect("Load from snapshot failed");
|
||||
if let Some(shrink_paths) = shrink_paths {
|
||||
|
@@ -377,6 +377,7 @@ pub struct ProcessOptions {
|
||||
pub limit_load_slot_count_from_snapshot: Option<usize>,
|
||||
pub allow_dead_slots: bool,
|
||||
pub accounts_db_test_hash_calculation: bool,
|
||||
pub accounts_db_skip_shrink: bool,
|
||||
pub shrink_ratio: AccountShrinkThreshold,
|
||||
}
|
||||
|
||||
|
@@ -201,10 +201,7 @@ pub(crate) mod tests {
|
||||
let result: Vec<_> = epoch_stakes_and_lockouts(&bank, first_leader_schedule_epoch);
|
||||
assert_eq!(
|
||||
result,
|
||||
vec![(
|
||||
leader_stake.stake(first_leader_schedule_epoch, None, true),
|
||||
None
|
||||
)]
|
||||
vec![(leader_stake.stake(first_leader_schedule_epoch, None), None)]
|
||||
);
|
||||
|
||||
// epoch stakes and lockouts are saved off for the future epoch, should
|
||||
@@ -215,14 +212,8 @@ pub(crate) mod tests {
|
||||
from_account::<StakeHistory, _>(&bank.get_account(&stake_history::id()).unwrap())
|
||||
.unwrap();
|
||||
let mut expected = vec![
|
||||
(
|
||||
leader_stake.stake(bank.epoch(), Some(&stake_history), true),
|
||||
None,
|
||||
),
|
||||
(
|
||||
other_stake.stake(bank.epoch(), Some(&stake_history), true),
|
||||
None,
|
||||
),
|
||||
(leader_stake.stake(bank.epoch(), Some(&stake_history)), None),
|
||||
(other_stake.stake(bank.epoch(), Some(&stake_history)), None),
|
||||
];
|
||||
|
||||
expected.sort();
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-local-cluster"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -17,22 +17,22 @@ fs_extra = "1.2.0"
|
||||
log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.0"
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.9" }
|
||||
solana-core = { path = "../core", version = "=1.7.9" }
|
||||
solana-client = { path = "../client", version = "=1.7.9" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.7.9" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "=1.7.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.9" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.7.11" }
|
||||
solana-core = { path = "../core", version = "=1.7.11" }
|
||||
solana-client = { path = "../client", version = "=1.7.11" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.7.11" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "=1.7.11" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.7.11" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.11" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.7.11" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -50,6 +50,7 @@ pub fn safe_clone_config(config: &ValidatorConfig) -> ValidatorConfig {
|
||||
accounts_db_caching_enabled: config.accounts_db_caching_enabled,
|
||||
warp_slot: config.warp_slot,
|
||||
accounts_db_test_hash_calculation: config.accounts_db_test_hash_calculation,
|
||||
accounts_db_skip_shrink: config.accounts_db_skip_shrink,
|
||||
accounts_db_use_index_hash_calculation: config.accounts_db_use_index_hash_calculation,
|
||||
tpu_coalesce_ms: config.tpu_coalesce_ms,
|
||||
validator_exit: Arc::new(RwLock::new(Exit::default())),
|
||||
|
@@ -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.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,9 +14,9 @@ byte-unit = "4.0.9"
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.122"
|
||||
serde_json = "1.0.56"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
|
||||
[[bin]]
|
||||
name = "solana-log-analyzer"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-logger"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Logger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-measure"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-measure"
|
||||
readme = "../README.md"
|
||||
@@ -12,8 +12,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.11"
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-merkle-root-bench"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -10,11 +10,11 @@ publish = false
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.11"
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
clap = "2.33.1"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-merkle-tree"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Merkle Tree"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/solana-merkle-tree"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../sdk/program", version = "=1.7.9" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.7.11" }
|
||||
fast-math = "0.1"
|
||||
|
||||
# This can go once the BPF toolchain target Rust 1.42.0+
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-metrics"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Metrics"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,7 +15,7 @@ gethostname = "0.2.1"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.11"
|
||||
reqwest = { version = "0.11.2", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.0"
|
||||
|
@@ -20,6 +20,7 @@ else
|
||||
fi
|
||||
|
||||
no_restart=0
|
||||
maybeRequireTower=true
|
||||
|
||||
args=()
|
||||
while [[ -n $1 ]]; do
|
||||
@@ -75,6 +76,12 @@ while [[ -n $1 ]]; do
|
||||
elif [[ $1 == --maximum-snapshots-to-retain ]]; then
|
||||
args+=("$1" "$2")
|
||||
shift 2
|
||||
elif [[ $1 == --accounts-db-skip-shrink ]]; then
|
||||
args+=("$1")
|
||||
shift
|
||||
elif [[ $1 == --skip-require-tower ]]; then
|
||||
maybeRequireTower=false
|
||||
shift
|
||||
else
|
||||
echo "Unknown argument: $1"
|
||||
$program --help
|
||||
@@ -99,8 +106,11 @@ ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-validator
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ $maybeRequireTower = true ]]; then
|
||||
args+=(--require-tower)
|
||||
fi
|
||||
|
||||
args+=(
|
||||
--require-tower
|
||||
--ledger "$ledger_dir"
|
||||
--rpc-port 8899
|
||||
--snapshot-interval-slots 200
|
||||
|
@@ -21,9 +21,16 @@ if [[ -f $BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR ]]; then
|
||||
else
|
||||
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity.json
|
||||
fi
|
||||
|
||||
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-account.json
|
||||
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-account.json
|
||||
if [[ -f $BOOTSTRAP_VALIDATOR_STAKE_KEYPAIR ]]; then
|
||||
cp -f "$BOOTSTRAP_VALIDATOR_STAKE_KEYPAIR" "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-account.json
|
||||
else
|
||||
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-account.json
|
||||
fi
|
||||
if [[ -f $BOOTSTRAP_VALIDATOR_VOTE_KEYPAIR ]]; then
|
||||
cp -f "$BOOTSTRAP_VALIDATOR_VOTE_KEYPAIR" "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-account.json
|
||||
else
|
||||
$solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-account.json
|
||||
fi
|
||||
|
||||
args=(
|
||||
"$@"
|
||||
|
@@ -45,6 +45,8 @@ EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
maybeRequireTower=true
|
||||
|
||||
positional_args=()
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ ${1:0:1} = - ]]; then
|
||||
@@ -140,10 +142,10 @@ while [[ -n $1 ]]; do
|
||||
elif [[ $1 = --log ]]; then
|
||||
args+=("$1" "$2")
|
||||
shift 2
|
||||
elif [[ $1 = --trusted-validator ]]; then
|
||||
elif [[ $1 = --known-validator ]]; then
|
||||
args+=("$1" "$2")
|
||||
shift 2
|
||||
elif [[ $1 = --halt-on-trusted-validators-accounts-hash-mismatch ]]; then
|
||||
elif [[ $1 = --halt-on-known-validators-accounts-hash-mismatch ]]; then
|
||||
args+=("$1")
|
||||
shift
|
||||
elif [[ $1 = --max-genesis-archive-unpacked-size ]]; then
|
||||
@@ -155,6 +157,12 @@ while [[ -n $1 ]]; do
|
||||
elif [[ $1 == --expected-bank-hash ]]; then
|
||||
args+=("$1" "$2")
|
||||
shift 2
|
||||
elif [[ $1 == --accounts-db-skip-shrink ]]; then
|
||||
args+=("$1")
|
||||
shift
|
||||
elif [[ $1 == --skip-require-tower ]]; then
|
||||
maybeRequireTower=false
|
||||
shift
|
||||
elif [[ $1 = -h ]]; then
|
||||
usage "$@"
|
||||
else
|
||||
@@ -227,7 +235,10 @@ default_arg --identity "$identity"
|
||||
default_arg --vote-account "$vote_account"
|
||||
default_arg --ledger "$ledger_dir"
|
||||
default_arg --log -
|
||||
default_arg --require-tower
|
||||
|
||||
if [[ $maybeRequireTower = true ]]; then
|
||||
default_arg --require-tower
|
||||
fi
|
||||
|
||||
if [[ -n $SOLANA_CUDA ]]; then
|
||||
program=$solana_validator_cuda
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-net-shaper"
|
||||
description = "The solana cluster network shaping tool"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
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.122"
|
||||
serde_json = "1.0.56"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
rand = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-net-utils"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Network Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,10 +18,10 @@ rand = "0.7.0"
|
||||
serde = "1.0.122"
|
||||
serde_derive = "1.0.103"
|
||||
socket2 = "0.3.17"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
url = "2.1.1"
|
||||
|
||||
|
12
net/net.sh
12
net/net.sh
@@ -309,7 +309,7 @@ startBootstrapLeader() {
|
||||
${#clientIpList[@]} \"$benchTpsExtraArgs\" \
|
||||
${#clientIpList[@]} \"$benchExchangeExtraArgs\" \
|
||||
\"$genesisOptions\" \
|
||||
\"$maybeNoSnapshot $maybeSkipLedgerVerify $maybeLimitLedgerSize $maybeWaitForSupermajority\" \
|
||||
\"$maybeNoSnapshot $maybeSkipLedgerVerify $maybeLimitLedgerSize $maybeWaitForSupermajority $maybeAccountsDbSkipShrink $maybeSkipRequireTower\" \
|
||||
\"$gpuMode\" \
|
||||
\"$maybeWarpSlot\" \
|
||||
\"$waitForNodeInit\" \
|
||||
@@ -381,7 +381,7 @@ startNode() {
|
||||
${#clientIpList[@]} \"$benchTpsExtraArgs\" \
|
||||
${#clientIpList[@]} \"$benchExchangeExtraArgs\" \
|
||||
\"$genesisOptions\" \
|
||||
\"$maybeNoSnapshot $maybeSkipLedgerVerify $maybeLimitLedgerSize $maybeWaitForSupermajority\" \
|
||||
\"$maybeNoSnapshot $maybeSkipLedgerVerify $maybeLimitLedgerSize $maybeWaitForSupermajority $maybeAccountsDbSkipShrink $maybeSkipRequireTower\" \
|
||||
\"$gpuMode\" \
|
||||
\"$maybeWarpSlot\" \
|
||||
\"$waitForNodeInit\" \
|
||||
@@ -782,6 +782,8 @@ maybeLimitLedgerSize=""
|
||||
maybeSkipLedgerVerify=""
|
||||
maybeDisableAirdrops=""
|
||||
maybeWaitForSupermajority=""
|
||||
maybeAccountsDbSkipShrink=""
|
||||
maybeSkipRequireTower=""
|
||||
debugBuild=false
|
||||
doBuild=true
|
||||
gpuMode=auto
|
||||
@@ -906,6 +908,12 @@ while [[ -n $1 ]]; do
|
||||
elif [[ $1 == --extra-primordial-stakes ]]; then
|
||||
extraPrimordialStakes=$2
|
||||
shift 2
|
||||
elif [[ $1 = --accounts-db-skip-shrink ]]; then
|
||||
maybeAccountsDbSkipShrink="$1"
|
||||
shift 1
|
||||
elif [[ $1 = --skip-require-tower ]]; then
|
||||
maybeSkipRequireTower="$1"
|
||||
shift 1
|
||||
else
|
||||
usage "Unknown long option: $1"
|
||||
fi
|
||||
|
@@ -226,6 +226,12 @@ EOF
|
||||
if [[ -f net/keypairs/bootstrap-validator-identity.json ]]; then
|
||||
export BOOTSTRAP_VALIDATOR_IDENTITY_KEYPAIR=net/keypairs/bootstrap-validator-identity.json
|
||||
fi
|
||||
if [[ -f net/keypairs/bootstrap-validator-stake.json ]]; then
|
||||
export BOOTSTRAP_VALIDATOR_STAKE_KEYPAIR=net/keypairs/bootstrap-validator-stake.json
|
||||
fi
|
||||
if [[ -f net/keypairs/bootstrap-validator-vote.json ]]; then
|
||||
export BOOTSTRAP_VALIDATOR_VOTE_KEYPAIR=net/keypairs/bootstrap-validator-vote.json
|
||||
fi
|
||||
echo "remote-node.sh: Primordial stakes: $extraPrimordialStakes"
|
||||
if [[ "$extraPrimordialStakes" -gt 0 ]]; then
|
||||
if [[ "$extraPrimordialStakes" -gt "$numNodes" ]]; then
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-notifier"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Notifier"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-perf"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana Performance APIs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,10 +19,10 @@ log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.0"
|
||||
serde = "1.0.126"
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.7.11" }
|
||||
|
||||
[lib]
|
||||
name = "solana_perf"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2018"
|
||||
name = "solana-poh-bench"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,13 +13,13 @@ clap = "2.33.1"
|
||||
log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.0"
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-version = { path = "../version", version = "=1.7.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-version = { path = "../version", version = "=1.7.11" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.11" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-poh"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana PoH"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,20 +13,20 @@ edition = "2018"
|
||||
core_affinity = "0.5.10"
|
||||
crossbeam-channel = "0.4"
|
||||
log = "0.4.11"
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "=1.7.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.7.11" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "=1.7.11" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
bincode = "1.3.1"
|
||||
matches = "0.1.6"
|
||||
rand = "0.7.0"
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-perf = { path = "../perf", version = "=1.7.11" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -5,7 +5,7 @@ edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
name = "solana-program-test"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.42"
|
||||
@@ -17,13 +17,13 @@ log = "0.4.11"
|
||||
mio = "0.7.6"
|
||||
serde = "1.0.112"
|
||||
serde_derive = "1.0.103"
|
||||
solana-banks-client = { path = "../banks-client", version = "=1.7.9" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.7.9" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.7.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.9" }
|
||||
solana-banks-client = { path = "../banks-client", version = "=1.7.11" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.7.11" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.7.11" }
|
||||
solana-logger = { path = "../logger", version = "=1.7.11" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.7.11" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.7.11" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
|
@@ -277,7 +277,7 @@ async fn stake_rewards_from_warp() {
|
||||
assert_matches!(
|
||||
stake
|
||||
.delegation
|
||||
.stake_activating_and_deactivating(clock.epoch, Some(&stake_history), true,),
|
||||
.stake_activating_and_deactivating(clock.epoch, Some(&stake_history)),
|
||||
(_, 0, 0)
|
||||
);
|
||||
}
|
||||
|
793
programs/bpf/Cargo.lock
generated
793
programs/bpf/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-bpf-programs"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "README.md"
|
||||
@@ -26,15 +26,15 @@ itertools = "0.10.0"
|
||||
log = "0.4.11"
|
||||
miow = "0.2.2"
|
||||
net2 = "0.2.37"
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.7.9" }
|
||||
solana-cli-output = { path = "../../cli-output", version = "=1.7.9" }
|
||||
solana-logger = { path = "../../logger", version = "=1.7.9" }
|
||||
solana-measure = { path = "../../measure", version = "=1.7.9" }
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.7.11" }
|
||||
solana-cli-output = { path = "../../cli-output", version = "=1.7.11" }
|
||||
solana-logger = { path = "../../logger", version = "=1.7.11" }
|
||||
solana-measure = { path = "../../measure", version = "=1.7.11" }
|
||||
solana_rbpf = "=0.2.11"
|
||||
solana-runtime = { path = "../../runtime", version = "=1.7.9" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.7.9" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.7.9" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.7.9" }
|
||||
solana-runtime = { path = "../../runtime", version = "=1.7.11" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.7.11" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.7.11" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.7.11" }
|
||||
|
||||
|
||||
[[bench]]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.7.9"
|
||||
version = "1.7.11"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,8 +10,8 @@ documentation = "https://docs.rs/solana-bpf-rust-128bit"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.7.9" }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "=1.7.9" }
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.7.11" }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "=1.7.11" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user