Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1ff9555099 | ||
|
72a13e2a72 | ||
|
74cdfc2213 | ||
|
7b8e5a9f47 | ||
|
80525ac862 | ||
|
c14f98c6fc | ||
|
c6edfc3944 | ||
|
b95c493d66 | ||
|
5871462241 | ||
|
53bb826375 | ||
|
c769bcc418 | ||
|
f06a4c7861 | ||
|
0cae099d12 |
359
Cargo.lock
generated
359
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana account decoder"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,9 +13,9 @@ bincode = "1.2.1"
|
||||
bs58 = "0.3.1"
|
||||
Inflector = "0.11.4"
|
||||
lazy_static = "1.4.0"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.3", features = ["skip-no-mangle"] }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
|
||||
serde = "1.0.112"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.54"
|
||||
|
@@ -8,8 +8,7 @@ pub mod parse_nonce;
|
||||
pub mod parse_token;
|
||||
pub mod parse_vote;
|
||||
|
||||
use crate::parse_account_data::parse_account_data;
|
||||
use serde_json::Value;
|
||||
use crate::parse_account_data::{parse_account_data, ParsedAccount};
|
||||
use solana_sdk::{account::Account, clock::Epoch, pubkey::Pubkey};
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -28,7 +27,7 @@ pub struct UiAccount {
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
pub enum UiAccountData {
|
||||
Binary(String),
|
||||
Json(Value),
|
||||
Json(ParsedAccount),
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for UiAccountData {
|
||||
|
@@ -4,7 +4,7 @@ use crate::{
|
||||
parse_vote::parse_vote,
|
||||
};
|
||||
use inflector::Inflector;
|
||||
use serde_json::{json, Value};
|
||||
use serde_json::Value;
|
||||
use solana_sdk::{instruction::InstructionError, pubkey::Pubkey, system_program};
|
||||
use std::collections::HashMap;
|
||||
use thiserror::Error;
|
||||
@@ -37,6 +37,13 @@ pub enum ParseAccountError {
|
||||
SerdeJsonError(#[from] serde_json::error::Error),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ParsedAccount {
|
||||
pub program: String,
|
||||
pub parsed: Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ParsableAccount {
|
||||
@@ -45,7 +52,10 @@ pub enum ParsableAccount {
|
||||
Vote,
|
||||
}
|
||||
|
||||
pub fn parse_account_data(program_id: &Pubkey, data: &[u8]) -> Result<Value, ParseAccountError> {
|
||||
pub fn parse_account_data(
|
||||
program_id: &Pubkey,
|
||||
data: &[u8],
|
||||
) -> Result<ParsedAccount, ParseAccountError> {
|
||||
let program_name = PARSABLE_PROGRAM_IDS
|
||||
.get(program_id)
|
||||
.ok_or_else(|| ParseAccountError::ProgramNotParsable)?;
|
||||
@@ -54,9 +64,10 @@ pub fn parse_account_data(program_id: &Pubkey, data: &[u8]) -> Result<Value, Par
|
||||
ParsableAccount::SplToken => serde_json::to_value(parse_token(data)?)?,
|
||||
ParsableAccount::Vote => serde_json::to_value(parse_vote(data)?)?,
|
||||
};
|
||||
Ok(json!({
|
||||
format!("{:?}", program_name).to_kebab_case(): parsed_json
|
||||
}))
|
||||
Ok(ParsedAccount {
|
||||
program: format!("{:?}", program_name).to_kebab_case(),
|
||||
parsed: parsed_json,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -79,11 +90,11 @@ mod test {
|
||||
let versioned = VoteStateVersions::Current(Box::new(vote_state));
|
||||
VoteState::serialize(&versioned, &mut vote_account_data).unwrap();
|
||||
let parsed = parse_account_data(&solana_vote_program::id(), &vote_account_data).unwrap();
|
||||
assert!(parsed.as_object().unwrap().contains_key("vote"));
|
||||
assert_eq!(parsed.program, "vote".to_string());
|
||||
|
||||
let nonce_data = Versions::new_current(State::Initialized(Data::default()));
|
||||
let nonce_account_data = bincode::serialize(&nonce_data).unwrap();
|
||||
let parsed = parse_account_data(&system_program::id(), &nonce_account_data).unwrap();
|
||||
assert!(parsed.as_object().unwrap().contains_key("nonce"));
|
||||
assert_eq!(parsed.program, "nonce".to_string());
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ pub fn parse_nonce(data: &[u8]) -> Result<UiNonceState, ParseAccountError> {
|
||||
|
||||
/// A duplicate representation of NonceState for pretty JSON serialization
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(rename_all = "camelCase", tag = "type", content = "info")]
|
||||
pub enum UiNonceState {
|
||||
Uninitialized,
|
||||
Initialized(UiNonceData),
|
||||
|
@@ -3,19 +3,26 @@ use solana_sdk::pubkey::Pubkey;
|
||||
use spl_token_v1_0::{
|
||||
option::COption,
|
||||
solana_sdk::pubkey::Pubkey as SplTokenPubkey,
|
||||
state::{Account, Mint, Multisig, State},
|
||||
state::{unpack, Account, Mint, Multisig},
|
||||
};
|
||||
use std::{mem::size_of, str::FromStr};
|
||||
|
||||
// A helper function to convert spl_token_v1_0::id() as spl_sdk::pubkey::Pubkey to solana_sdk::pubkey::Pubkey
|
||||
// A helper function to convert spl_token_v1_0::id() as spl_sdk::pubkey::Pubkey to
|
||||
// solana_sdk::pubkey::Pubkey
|
||||
pub fn spl_token_id_v1_0() -> Pubkey {
|
||||
Pubkey::from_str(&spl_token_v1_0::id().to_string()).unwrap()
|
||||
}
|
||||
|
||||
// A helper function to convert spl_token_v1_0::native_mint::id() as spl_sdk::pubkey::Pubkey to
|
||||
// solana_sdk::pubkey::Pubkey
|
||||
pub fn spl_token_v1_0_native_mint() -> Pubkey {
|
||||
Pubkey::from_str(&spl_token_v1_0::native_mint::id().to_string()).unwrap()
|
||||
}
|
||||
|
||||
pub fn parse_token(data: &[u8]) -> Result<TokenAccountType, ParseAccountError> {
|
||||
let mut data = data.to_vec();
|
||||
if data.len() == size_of::<Account>() {
|
||||
let account: Account = *State::unpack(&mut data)
|
||||
let account: Account = *unpack(&mut data)
|
||||
.map_err(|_| ParseAccountError::AccountNotParsable(ParsableAccount::SplToken))?;
|
||||
Ok(TokenAccountType::Account(UiTokenAccount {
|
||||
mint: account.mint.to_string(),
|
||||
@@ -30,7 +37,7 @@ pub fn parse_token(data: &[u8]) -> Result<TokenAccountType, ParseAccountError> {
|
||||
delegated_amount: account.delegated_amount,
|
||||
}))
|
||||
} else if data.len() == size_of::<Mint>() {
|
||||
let mint: Mint = *State::unpack(&mut data)
|
||||
let mint: Mint = *unpack(&mut data)
|
||||
.map_err(|_| ParseAccountError::AccountNotParsable(ParsableAccount::SplToken))?;
|
||||
Ok(TokenAccountType::Mint(UiMint {
|
||||
owner: match mint.owner {
|
||||
@@ -41,7 +48,7 @@ pub fn parse_token(data: &[u8]) -> Result<TokenAccountType, ParseAccountError> {
|
||||
is_initialized: mint.is_initialized,
|
||||
}))
|
||||
} else if data.len() == size_of::<Multisig>() {
|
||||
let multisig: Multisig = *State::unpack(&mut data)
|
||||
let multisig: Multisig = *unpack(&mut data)
|
||||
.map_err(|_| ParseAccountError::AccountNotParsable(ParsableAccount::SplToken))?;
|
||||
Ok(TokenAccountType::Multisig(UiMultisig {
|
||||
num_required_signers: multisig.m,
|
||||
@@ -67,7 +74,7 @@ pub fn parse_token(data: &[u8]) -> Result<TokenAccountType, ParseAccountError> {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(rename_all = "camelCase", tag = "type", content = "info")]
|
||||
pub enum TokenAccountType {
|
||||
Account(UiTokenAccount),
|
||||
Mint(UiMint),
|
||||
@@ -106,13 +113,14 @@ pub struct UiMultisig {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use spl_token_v1_0::state::unpack_unchecked;
|
||||
|
||||
#[test]
|
||||
fn test_parse_token() {
|
||||
let mint_pubkey = SplTokenPubkey::new(&[2; 32]);
|
||||
let owner_pubkey = SplTokenPubkey::new(&[3; 32]);
|
||||
let mut account_data = [0; size_of::<Account>()];
|
||||
let mut account: &mut Account = State::unpack_unchecked(&mut account_data).unwrap();
|
||||
let mut account: &mut Account = unpack_unchecked(&mut account_data).unwrap();
|
||||
account.mint = mint_pubkey;
|
||||
account.owner = owner_pubkey;
|
||||
account.amount = 42;
|
||||
@@ -131,7 +139,7 @@ mod test {
|
||||
);
|
||||
|
||||
let mut mint_data = [0; size_of::<Mint>()];
|
||||
let mut mint: &mut Mint = State::unpack_unchecked(&mut mint_data).unwrap();
|
||||
let mut mint: &mut Mint = unpack_unchecked(&mut mint_data).unwrap();
|
||||
mint.owner = COption::Some(owner_pubkey);
|
||||
mint.decimals = 3;
|
||||
mint.is_initialized = true;
|
||||
@@ -148,7 +156,7 @@ mod test {
|
||||
let signer2 = SplTokenPubkey::new(&[2; 32]);
|
||||
let signer3 = SplTokenPubkey::new(&[3; 32]);
|
||||
let mut multisig_data = [0; size_of::<Multisig>()];
|
||||
let mut multisig: &mut Multisig = State::unpack_unchecked(&mut multisig_data).unwrap();
|
||||
let mut multisig: &mut Multisig = unpack_unchecked(&mut multisig_data).unwrap();
|
||||
let mut signers = [SplTokenPubkey::default(); 11];
|
||||
signers[0] = signer1;
|
||||
signers[1] = signer2;
|
||||
|
@@ -5,7 +5,7 @@ use solana_sdk::{
|
||||
};
|
||||
use solana_vote_program::vote_state::{BlockTimestamp, Lockout, VoteState};
|
||||
|
||||
pub fn parse_vote(data: &[u8]) -> Result<UiVoteState, ParseAccountError> {
|
||||
pub fn parse_vote(data: &[u8]) -> Result<VoteAccountType, ParseAccountError> {
|
||||
let mut vote_state = VoteState::deserialize(data).map_err(ParseAccountError::from)?;
|
||||
let epoch_credits = vote_state
|
||||
.epoch_credits()
|
||||
@@ -45,7 +45,7 @@ pub fn parse_vote(data: &[u8]) -> Result<UiVoteState, ParseAccountError> {
|
||||
},
|
||||
)
|
||||
.collect();
|
||||
Ok(UiVoteState {
|
||||
Ok(VoteAccountType::Vote(UiVoteState {
|
||||
node_pubkey: vote_state.node_pubkey.to_string(),
|
||||
authorized_withdrawer: vote_state.authorized_withdrawer.to_string(),
|
||||
commission: vote_state.commission,
|
||||
@@ -55,7 +55,14 @@ pub fn parse_vote(data: &[u8]) -> Result<UiVoteState, ParseAccountError> {
|
||||
prior_voters,
|
||||
epoch_credits,
|
||||
last_timestamp: vote_state.last_timestamp,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
/// A wrapper enum for consistency across programs
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase", tag = "type", content = "info")]
|
||||
pub enum VoteAccountType {
|
||||
Vote(UiVoteState),
|
||||
}
|
||||
|
||||
/// A duplicate representation of VoteState for pretty JSON serialization
|
||||
@@ -126,7 +133,10 @@ mod test {
|
||||
let mut expected_vote_state = UiVoteState::default();
|
||||
expected_vote_state.node_pubkey = Pubkey::default().to_string();
|
||||
expected_vote_state.authorized_withdrawer = Pubkey::default().to_string();
|
||||
assert_eq!(parse_vote(&vote_account_data).unwrap(), expected_vote_state,);
|
||||
assert_eq!(
|
||||
parse_vote(&vote_account_data).unwrap(),
|
||||
VoteAccountType::Vote(expected_vote_state)
|
||||
);
|
||||
|
||||
let bad_data = vec![0; 4];
|
||||
assert!(parse_vote(&bad_data).is_err());
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-accounts-bench"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -10,10 +10,10 @@ homepage = "https://solana.com/"
|
||||
[dependencies]
|
||||
log = "0.4.6"
|
||||
rayon = "1.3.0"
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
rand = "0.7.0"
|
||||
clap = "2.33.1"
|
||||
crossbeam-channel = "0.4"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-banking-bench"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,16 +13,16 @@ crossbeam-channel = "0.4"
|
||||
log = "0.4.6"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.17" }
|
||||
solana-perf = { path = "../perf", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.19" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-exchange"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -18,21 +18,21 @@ rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.17" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.17" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,18 +2,18 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-streamer"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-bench-tps"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,23 +14,23 @@ log = "0.4.8"
|
||||
rayon = "1.3.0"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-genesis = { path = "../genesis", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.4.0"
|
||||
serial_test_derive = "0.4.0"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.17" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -27,5 +27,5 @@ Alternatively, you can source it from within a script:
|
||||
local PATCH=0
|
||||
local SPECIAL=""
|
||||
|
||||
semverParseInto "1.2.17" MAJOR MINOR PATCH SPECIAL
|
||||
semverParseInto "1.2.19" MAJOR MINOR PATCH SPECIAL
|
||||
semverParseInto "3.2.1" MAJOR MINOR PATCH SPECIAL
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana utilities for the clap"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -11,8 +11,8 @@ edition = "2018"
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
rpassword = "4.0"
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
thiserror = "1.0.11"
|
||||
tiny-bip39 = "0.7.0"
|
||||
url = "2.1.0"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli-config"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-cli"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -27,29 +27,29 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.53"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.17" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.17" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.17" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.19" }
|
||||
thiserror = "1.0.19"
|
||||
url = "2.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -246,8 +246,8 @@ pub enum CliCommand {
|
||||
},
|
||||
TransactionHistory {
|
||||
address: Pubkey,
|
||||
end_slot: Option<Slot>, // None == latest slot
|
||||
slot_limit: Option<u64>, // None == search full history
|
||||
before: Option<Signature>,
|
||||
limit: usize,
|
||||
},
|
||||
// Nonce commands
|
||||
AuthorizeNonceAccount {
|
||||
@@ -1837,9 +1837,9 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
||||
} => process_show_validators(&rpc_client, config, *use_lamports_unit, *commitment_config),
|
||||
CliCommand::TransactionHistory {
|
||||
address,
|
||||
end_slot,
|
||||
slot_limit,
|
||||
} => process_transaction_history(&rpc_client, address, *end_slot, *slot_limit),
|
||||
before,
|
||||
limit,
|
||||
} => process_transaction_history(&rpc_client, config, address, *before, *limit),
|
||||
|
||||
// Nonce Commands
|
||||
|
||||
|
@@ -16,7 +16,6 @@ use solana_client::{
|
||||
pubsub_client::{PubsubClient, SlotInfoMessage},
|
||||
rpc_client::RpcClient,
|
||||
rpc_config::{RpcLargestAccountsConfig, RpcLargestAccountsFilter},
|
||||
rpc_request::MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE,
|
||||
};
|
||||
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
||||
use solana_sdk::{
|
||||
@@ -27,6 +26,7 @@ use solana_sdk::{
|
||||
message::Message,
|
||||
native_token::lamports_to_sol,
|
||||
pubkey::{self, Pubkey},
|
||||
signature::Signature,
|
||||
system_instruction, system_program,
|
||||
sysvar::{
|
||||
self,
|
||||
@@ -266,26 +266,22 @@ impl ClusterQuerySubCommands for App<'_, '_> {
|
||||
.required(true),
|
||||
"Account address"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("end_slot")
|
||||
.takes_value(false)
|
||||
.value_name("SLOT")
|
||||
.index(2)
|
||||
.validator(is_slot)
|
||||
.help(
|
||||
"Slot to start from [default: latest slot at maximum commitment]"
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("limit")
|
||||
.long("limit")
|
||||
.takes_value(true)
|
||||
.value_name("NUMBER OF SLOTS")
|
||||
.value_name("LIMIT")
|
||||
.validator(is_slot)
|
||||
.help(
|
||||
"Limit the search to this many slots"
|
||||
),
|
||||
),
|
||||
.default_value("1000")
|
||||
.help("Maximum number of transaction signatures to return"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("before")
|
||||
.long("before")
|
||||
.value_name("TRANSACTION_SIGNATURE")
|
||||
.takes_value(true)
|
||||
.help("Start with the first signature older than this one"),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -453,14 +449,22 @@ pub fn parse_transaction_history(
|
||||
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||
) -> Result<CliCommandInfo, CliError> {
|
||||
let address = pubkey_of_signer(matches, "address", wallet_manager)?.unwrap();
|
||||
let end_slot = value_t!(matches, "end_slot", Slot).ok();
|
||||
let slot_limit = value_t!(matches, "limit", u64).ok();
|
||||
|
||||
let before = match matches.value_of("before") {
|
||||
Some(signature) => Some(
|
||||
signature
|
||||
.parse()
|
||||
.map_err(|err| CliError::BadParameter(format!("Invalid signature: {}", err)))?,
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
let limit = value_t_or_exit!(matches, "limit", usize);
|
||||
|
||||
Ok(CliCommandInfo {
|
||||
command: CliCommand::TransactionHistory {
|
||||
address,
|
||||
end_slot,
|
||||
slot_limit,
|
||||
before,
|
||||
limit,
|
||||
},
|
||||
signers: vec![],
|
||||
})
|
||||
@@ -1276,41 +1280,36 @@ pub fn process_show_validators(
|
||||
|
||||
pub fn process_transaction_history(
|
||||
rpc_client: &RpcClient,
|
||||
config: &CliConfig,
|
||||
address: &Pubkey,
|
||||
end_slot: Option<Slot>, // None == use latest slot
|
||||
slot_limit: Option<u64>,
|
||||
before: Option<Signature>,
|
||||
limit: usize,
|
||||
) -> ProcessResult {
|
||||
let end_slot = {
|
||||
if let Some(end_slot) = end_slot {
|
||||
end_slot
|
||||
let results = rpc_client.get_confirmed_signatures_for_address2_with_config(
|
||||
address,
|
||||
before,
|
||||
Some(limit),
|
||||
)?;
|
||||
|
||||
let transactions_found = format!("{} transactions found", results.len());
|
||||
|
||||
for result in results {
|
||||
if config.verbose {
|
||||
println!(
|
||||
"{} [slot={} status={}] {}",
|
||||
result.signature,
|
||||
result.slot,
|
||||
match result.err {
|
||||
None => "Confirmed".to_string(),
|
||||
Some(err) => format!("Failed: {:?}", err),
|
||||
},
|
||||
result.memo.unwrap_or_else(|| "".to_string()),
|
||||
);
|
||||
} else {
|
||||
rpc_client.get_slot_with_commitment(CommitmentConfig::max())?
|
||||
println!("{}", result.signature);
|
||||
}
|
||||
};
|
||||
let mut start_slot = match slot_limit {
|
||||
Some(slot_limit) => end_slot.saturating_sub(slot_limit),
|
||||
None => rpc_client.minimum_ledger_slot()?,
|
||||
};
|
||||
|
||||
println!(
|
||||
"Transactions affecting {} within slots [{},{}]",
|
||||
address, start_slot, end_slot
|
||||
);
|
||||
|
||||
let mut transaction_count = 0;
|
||||
while start_slot < end_slot {
|
||||
let signatures = rpc_client.get_confirmed_signatures_for_address(
|
||||
address,
|
||||
start_slot,
|
||||
(start_slot + MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE).min(end_slot),
|
||||
)?;
|
||||
for signature in &signatures {
|
||||
println!("{}", signature);
|
||||
}
|
||||
transaction_count += signatures.len();
|
||||
start_slot += MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE;
|
||||
}
|
||||
Ok(format!("{} transactions found", transaction_count))
|
||||
Ok(transactions_found)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,11 +19,11 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.53"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
tungstenite = "0.10.1"
|
||||
url = "2.1.1"
|
||||
@@ -32,7 +32,7 @@ url = "2.1.1"
|
||||
assert_matches = "1.3.0"
|
||||
jsonrpc-core = "14.1.0"
|
||||
jsonrpc-http-server = "14.1.0"
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,10 @@ use crate::{
|
||||
client_error::{ClientError, ClientErrorKind, Result as ClientResult},
|
||||
http_sender::HttpSender,
|
||||
mock_sender::{MockSender, Mocks},
|
||||
rpc_config::{RpcLargestAccountsConfig, RpcSendTransactionConfig, RpcTokenAccountsFilter},
|
||||
rpc_config::{
|
||||
RpcGetConfirmedSignaturesForAddress2Config, RpcLargestAccountsConfig,
|
||||
RpcSendTransactionConfig, RpcTokenAccountsFilter,
|
||||
},
|
||||
rpc_request::{RpcError, RpcRequest, TokenAccountsFilter},
|
||||
rpc_response::*,
|
||||
rpc_sender::RpcSender,
|
||||
@@ -11,7 +14,10 @@ use bincode::serialize;
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use log::*;
|
||||
use serde_json::{json, Value};
|
||||
use solana_account_decoder::UiAccount;
|
||||
use solana_account_decoder::{
|
||||
parse_token::{parse_token, TokenAccountType, UiMint, UiMultisig, UiTokenAccount},
|
||||
UiAccount,
|
||||
};
|
||||
use solana_sdk::{
|
||||
account::Account,
|
||||
clock::{
|
||||
@@ -283,6 +289,32 @@ impl RpcClient {
|
||||
Ok(signatures)
|
||||
}
|
||||
|
||||
pub fn get_confirmed_signatures_for_address2(
|
||||
&self,
|
||||
address: &Pubkey,
|
||||
) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
|
||||
self.get_confirmed_signatures_for_address2_with_config(address, None, None)
|
||||
}
|
||||
|
||||
pub fn get_confirmed_signatures_for_address2_with_config(
|
||||
&self,
|
||||
address: &Pubkey,
|
||||
before: Option<Signature>,
|
||||
limit: Option<usize>,
|
||||
) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
|
||||
let config = RpcGetConfirmedSignaturesForAddress2Config {
|
||||
before: before.map(|signature| signature.to_string()),
|
||||
limit,
|
||||
};
|
||||
|
||||
let result: Vec<RpcConfirmedTransactionStatusWithSignature> = self.send(
|
||||
RpcRequest::GetConfirmedSignaturesForAddress2,
|
||||
json!([address.to_string(), config]),
|
||||
)?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn get_confirmed_transaction(
|
||||
&self,
|
||||
signature: &Signature,
|
||||
@@ -658,7 +690,88 @@ impl RpcClient {
|
||||
Ok(hash)
|
||||
}
|
||||
|
||||
pub fn get_token_account_balance(&self, pubkey: &Pubkey) -> ClientResult<u64> {
|
||||
pub fn get_token_account(&self, pubkey: &Pubkey) -> ClientResult<Option<UiTokenAccount>> {
|
||||
Ok(self
|
||||
.get_token_account_with_commitment(pubkey, CommitmentConfig::default())?
|
||||
.value)
|
||||
}
|
||||
|
||||
pub fn get_token_account_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<Option<UiTokenAccount>> {
|
||||
let Response {
|
||||
context,
|
||||
value: account,
|
||||
} = self.get_account_with_commitment(pubkey, commitment_config)?;
|
||||
|
||||
Ok(Response {
|
||||
context,
|
||||
value: account
|
||||
.map(|account| match parse_token(&account.data) {
|
||||
Ok(TokenAccountType::Account(ui_token_account)) => Some(ui_token_account),
|
||||
_ => None,
|
||||
})
|
||||
.flatten(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_token_mint(&self, pubkey: &Pubkey) -> ClientResult<Option<UiMint>> {
|
||||
Ok(self
|
||||
.get_token_mint_with_commitment(pubkey, CommitmentConfig::default())?
|
||||
.value)
|
||||
}
|
||||
|
||||
pub fn get_token_mint_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<Option<UiMint>> {
|
||||
let Response {
|
||||
context,
|
||||
value: account,
|
||||
} = self.get_account_with_commitment(pubkey, commitment_config)?;
|
||||
|
||||
Ok(Response {
|
||||
context,
|
||||
value: account
|
||||
.map(|account| match parse_token(&account.data) {
|
||||
Ok(TokenAccountType::Mint(ui_token_mint)) => Some(ui_token_mint),
|
||||
_ => None,
|
||||
})
|
||||
.flatten(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_token_multisig(&self, pubkey: &Pubkey) -> ClientResult<Option<UiMultisig>> {
|
||||
Ok(self
|
||||
.get_token_multisig_with_commitment(pubkey, CommitmentConfig::default())?
|
||||
.value)
|
||||
}
|
||||
|
||||
pub fn get_token_multisig_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<Option<UiMultisig>> {
|
||||
let Response {
|
||||
context,
|
||||
value: account,
|
||||
} = self.get_account_with_commitment(pubkey, commitment_config)?;
|
||||
|
||||
Ok(Response {
|
||||
context,
|
||||
value: account
|
||||
.map(|account| match parse_token(&account.data) {
|
||||
Ok(TokenAccountType::Multisig(ui_token_multisig)) => Some(ui_token_multisig),
|
||||
_ => None,
|
||||
})
|
||||
.flatten(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_token_account_balance(&self, pubkey: &Pubkey) -> ClientResult<RpcTokenAmount> {
|
||||
Ok(self
|
||||
.get_token_account_balance_with_commitment(pubkey, CommitmentConfig::default())?
|
||||
.value)
|
||||
@@ -668,7 +781,7 @@ impl RpcClient {
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<u64> {
|
||||
) -> RpcResult<RpcTokenAmount> {
|
||||
self.send(
|
||||
RpcRequest::GetTokenAccountBalance,
|
||||
json!([pubkey.to_string(), commitment_config]),
|
||||
@@ -679,7 +792,7 @@ impl RpcClient {
|
||||
&self,
|
||||
delegate: &Pubkey,
|
||||
token_account_filter: TokenAccountsFilter,
|
||||
) -> ClientResult<Vec<(Pubkey, Account)>> {
|
||||
) -> ClientResult<Vec<(Pubkey, UiTokenAccount)>> {
|
||||
Ok(self
|
||||
.get_token_accounts_by_delegate_with_commitment(
|
||||
delegate,
|
||||
@@ -694,7 +807,7 @@ impl RpcClient {
|
||||
delegate: &Pubkey,
|
||||
token_account_filter: TokenAccountsFilter,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<Vec<(Pubkey, Account)>> {
|
||||
) -> RpcResult<Vec<(Pubkey, UiTokenAccount)>> {
|
||||
let token_account_filter = match token_account_filter {
|
||||
TokenAccountsFilter::Mint(mint) => RpcTokenAccountsFilter::Mint(mint.to_string()),
|
||||
TokenAccountsFilter::ProgramId(program_id) => {
|
||||
@@ -712,8 +825,10 @@ impl RpcClient {
|
||||
commitment_config
|
||||
]),
|
||||
)?;
|
||||
let pubkey_accounts =
|
||||
parse_keyed_accounts(accounts, RpcRequest::GetTokenAccountsByDelegate)?;
|
||||
let pubkey_accounts = accounts_to_token_accounts(parse_keyed_accounts(
|
||||
accounts,
|
||||
RpcRequest::GetTokenAccountsByDelegate,
|
||||
)?);
|
||||
Ok(Response {
|
||||
context,
|
||||
value: pubkey_accounts,
|
||||
@@ -724,7 +839,7 @@ impl RpcClient {
|
||||
&self,
|
||||
owner: &Pubkey,
|
||||
token_account_filter: TokenAccountsFilter,
|
||||
) -> ClientResult<Vec<(Pubkey, Account)>> {
|
||||
) -> ClientResult<Vec<(Pubkey, UiTokenAccount)>> {
|
||||
Ok(self
|
||||
.get_token_accounts_by_owner_with_commitment(
|
||||
owner,
|
||||
@@ -739,7 +854,7 @@ impl RpcClient {
|
||||
owner: &Pubkey,
|
||||
token_account_filter: TokenAccountsFilter,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<Vec<(Pubkey, Account)>> {
|
||||
) -> RpcResult<Vec<(Pubkey, UiTokenAccount)>> {
|
||||
let token_account_filter = match token_account_filter {
|
||||
TokenAccountsFilter::Mint(mint) => RpcTokenAccountsFilter::Mint(mint.to_string()),
|
||||
TokenAccountsFilter::ProgramId(program_id) => {
|
||||
@@ -753,14 +868,17 @@ impl RpcClient {
|
||||
RpcRequest::GetTokenAccountsByOwner,
|
||||
json!([owner.to_string(), token_account_filter, commitment_config]),
|
||||
)?;
|
||||
let pubkey_accounts = parse_keyed_accounts(accounts, RpcRequest::GetTokenAccountsByOwner)?;
|
||||
let pubkey_accounts = accounts_to_token_accounts(parse_keyed_accounts(
|
||||
accounts,
|
||||
RpcRequest::GetTokenAccountsByDelegate,
|
||||
)?);
|
||||
Ok(Response {
|
||||
context,
|
||||
value: pubkey_accounts,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_token_supply(&self, mint: &Pubkey) -> ClientResult<u64> {
|
||||
pub fn get_token_supply(&self, mint: &Pubkey) -> ClientResult<RpcTokenAmount> {
|
||||
Ok(self
|
||||
.get_token_supply_with_commitment(mint, CommitmentConfig::default())?
|
||||
.value)
|
||||
@@ -770,7 +888,7 @@ impl RpcClient {
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<u64> {
|
||||
) -> RpcResult<RpcTokenAmount> {
|
||||
self.send(
|
||||
RpcRequest::GetTokenSupply,
|
||||
json!([mint.to_string(), commitment_config]),
|
||||
@@ -1130,11 +1248,31 @@ fn parse_keyed_accounts(
|
||||
request,
|
||||
)
|
||||
})?;
|
||||
pubkey_accounts.push((pubkey, account.decode().unwrap()));
|
||||
pubkey_accounts.push((
|
||||
pubkey,
|
||||
account.decode().ok_or_else(|| {
|
||||
ClientError::new_with_request(
|
||||
RpcError::ParseError("Account from rpc".to_string()).into(),
|
||||
request,
|
||||
)
|
||||
})?,
|
||||
));
|
||||
}
|
||||
Ok(pubkey_accounts)
|
||||
}
|
||||
|
||||
fn accounts_to_token_accounts(
|
||||
pubkey_accounts: Vec<(Pubkey, Account)>,
|
||||
) -> Vec<(Pubkey, UiTokenAccount)> {
|
||||
pubkey_accounts
|
||||
.into_iter()
|
||||
.filter_map(|(pubkey, account)| match parse_token(&account.data) {
|
||||
Ok(TokenAccountType::Account(ui_token_account)) => Some((pubkey, ui_token_account)),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@@ -65,3 +65,10 @@ pub enum RpcTokenAccountsFilter {
|
||||
Mint(String),
|
||||
ProgramId(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcGetConfirmedSignaturesForAddress2Config {
|
||||
pub before: Option<String>, // Signature as base-58 string
|
||||
pub limit: Option<usize>,
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ pub enum RpcRequest {
|
||||
GetConfirmedBlock,
|
||||
GetConfirmedBlocks,
|
||||
GetConfirmedSignaturesForAddress,
|
||||
GetConfirmedSignaturesForAddress2,
|
||||
GetConfirmedTransaction,
|
||||
GetEpochInfo,
|
||||
GetEpochSchedule,
|
||||
@@ -65,6 +66,7 @@ impl fmt::Display for RpcRequest {
|
||||
RpcRequest::GetConfirmedBlock => "getConfirmedBlock",
|
||||
RpcRequest::GetConfirmedBlocks => "getConfirmedBlocks",
|
||||
RpcRequest::GetConfirmedSignaturesForAddress => "getConfirmedSignaturesForAddress",
|
||||
RpcRequest::GetConfirmedSignaturesForAddress2 => "getConfirmedSignaturesForAddress2",
|
||||
RpcRequest::GetConfirmedTransaction => "getConfirmedTransaction",
|
||||
RpcRequest::GetEpochInfo => "getEpochInfo",
|
||||
RpcRequest::GetEpochSchedule => "getEpochSchedule",
|
||||
@@ -112,6 +114,7 @@ pub const NUM_LARGEST_ACCOUNTS: usize = 20;
|
||||
pub const MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS: usize = 256;
|
||||
pub const MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE: u64 = 10_000;
|
||||
pub const MAX_GET_CONFIRMED_BLOCKS_RANGE: u64 = 500_000;
|
||||
pub const MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT: usize = 1_000;
|
||||
|
||||
// Validators that are this number of slots behind are considered delinquent
|
||||
pub const DELINQUENT_VALIDATOR_SLOT_DISTANCE: u64 = 128;
|
||||
|
@@ -6,9 +6,11 @@ use solana_sdk::{
|
||||
inflation::Inflation,
|
||||
transaction::{Result, TransactionError},
|
||||
};
|
||||
use solana_transaction_status::ConfirmedTransactionStatusWithSignature;
|
||||
use std::{collections::HashMap, net::SocketAddr};
|
||||
|
||||
pub type RpcResult<T> = client_error::Result<Response<T>>;
|
||||
pub type RpcAmount = String;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RpcResponseContext {
|
||||
@@ -219,3 +221,45 @@ pub struct RpcStakeActivation {
|
||||
pub active: u64,
|
||||
pub inactive: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcTokenAmount {
|
||||
pub ui_amount: f64,
|
||||
pub decimals: u8,
|
||||
pub amount: RpcAmount,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcTokenAccountBalance {
|
||||
pub address: String,
|
||||
#[serde(flatten)]
|
||||
pub amount: RpcTokenAmount,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcConfirmedTransactionStatusWithSignature {
|
||||
pub signature: String,
|
||||
pub slot: Slot,
|
||||
pub err: Option<TransactionError>,
|
||||
pub memo: Option<String>,
|
||||
}
|
||||
|
||||
impl From<ConfirmedTransactionStatusWithSignature> for RpcConfirmedTransactionStatusWithSignature {
|
||||
fn from(value: ConfirmedTransactionStatusWithSignature) -> Self {
|
||||
let ConfirmedTransactionStatusWithSignature {
|
||||
signature,
|
||||
slot,
|
||||
err,
|
||||
memo,
|
||||
} = value;
|
||||
Self {
|
||||
signature: signature.to_string(),
|
||||
slot,
|
||||
err,
|
||||
memo,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-core"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "../README.md"
|
||||
@@ -42,37 +42,37 @@ regex = "1.3.7"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.53"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.17" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.17" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.17" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-perf = { path = "../perf", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.17" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.17" }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.3", features = ["skip-no-mangle"] }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-streamer = { path = "../streamer", version = "1.2.19" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.19" }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
tokio = "0.1"
|
||||
tokio-codec = "0.1"
|
||||
tokio-fs = "0.1"
|
||||
tokio-io = "0.1"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.17" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
trees = "0.2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
433
core/src/rpc.rs
433
core/src/rpc.rs
@@ -13,12 +13,16 @@ use crate::{
|
||||
use bincode::serialize;
|
||||
use jsonrpc_core::{Error, Metadata, Result};
|
||||
use jsonrpc_derive::rpc;
|
||||
use solana_account_decoder::{parse_token::spl_token_id_v1_0, UiAccount, UiAccountEncoding};
|
||||
use solana_account_decoder::{
|
||||
parse_token::{spl_token_id_v1_0, spl_token_v1_0_native_mint},
|
||||
UiAccount, UiAccountEncoding,
|
||||
};
|
||||
use solana_client::{
|
||||
rpc_config::*,
|
||||
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
|
||||
rpc_request::{
|
||||
TokenAccountsFilter, DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_BLOCKS_RANGE,
|
||||
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT,
|
||||
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE,
|
||||
MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS, NUM_LARGEST_ACCOUNTS,
|
||||
},
|
||||
@@ -51,7 +55,7 @@ use solana_transaction_status::{
|
||||
ConfirmedBlock, ConfirmedTransaction, TransactionStatus, UiTransactionEncoding,
|
||||
};
|
||||
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
||||
use spl_token_v1_0::state::{Account as TokenAccount, State as TokenState};
|
||||
use spl_token_v1_0::state::{Account as TokenAccount, Mint};
|
||||
use std::{
|
||||
cmp::{max, min},
|
||||
collections::{HashMap, HashSet},
|
||||
@@ -118,7 +122,10 @@ impl JsonRpcRequestProcessor {
|
||||
.unwrap()
|
||||
.highest_confirmed_slot();
|
||||
debug!("RPC using confirmed slot: {:?}", slot);
|
||||
Ok(r_bank_forks.get(slot).cloned().unwrap())
|
||||
Ok(r_bank_forks
|
||||
.get(slot)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| r_bank_forks.root_bank().clone()))
|
||||
}
|
||||
CommitmentLevel::Max => {
|
||||
let cluster_root = self
|
||||
@@ -723,6 +730,35 @@ impl JsonRpcRequestProcessor {
|
||||
.unwrap_or_default())
|
||||
}
|
||||
|
||||
pub fn get_confirmed_signatures_for_address2(
|
||||
&self,
|
||||
address: Pubkey,
|
||||
before: Option<Signature>,
|
||||
limit: usize,
|
||||
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>> {
|
||||
if self.config.enable_rpc_transaction_history {
|
||||
let highest_confirmed_root = self
|
||||
.block_commitment_cache
|
||||
.read()
|
||||
.unwrap()
|
||||
.highest_confirmed_slot();
|
||||
|
||||
let results = self
|
||||
.blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address,
|
||||
highest_confirmed_root,
|
||||
before,
|
||||
limit,
|
||||
)
|
||||
.map_err(|err| Error::invalid_params(format!("{}", err)))?;
|
||||
|
||||
Ok(results.into_iter().map(|x| x.into()).collect())
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_stake_activation(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
@@ -788,7 +824,7 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<u64>> {
|
||||
) -> Result<RpcResponse<RpcTokenAmount>> {
|
||||
let bank = self.bank(commitment)?;
|
||||
let account = bank.get_account(pubkey).ok_or_else(|| {
|
||||
Error::invalid_params("Invalid param: could not find account".to_string())
|
||||
@@ -800,11 +836,14 @@ impl JsonRpcRequestProcessor {
|
||||
));
|
||||
}
|
||||
let mut data = account.data.to_vec();
|
||||
let balance = TokenState::unpack(&mut data)
|
||||
.map_err(|_| {
|
||||
let token_account =
|
||||
spl_token_v1_0::state::unpack::<TokenAccount>(&mut data).map_err(|_| {
|
||||
Error::invalid_params("Invalid param: not a v1.0 Token account".to_string())
|
||||
})
|
||||
.map(|account: &mut TokenAccount| account.amount)?;
|
||||
})?;
|
||||
let mint = &Pubkey::from_str(&token_account.mint.to_string())
|
||||
.expect("Token account mint should be convertible to Pubkey");
|
||||
let (_, decimals) = get_mint_owner_and_decimals(&bank, &mint)?;
|
||||
let balance = token_amount_to_ui_amount(token_account.amount, decimals);
|
||||
new_response(&bank, balance)
|
||||
}
|
||||
|
||||
@@ -812,12 +851,45 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<u64>> {
|
||||
) -> Result<RpcResponse<RpcTokenAmount>> {
|
||||
let bank = self.bank(commitment)?;
|
||||
let mint_account = bank.get_account(mint).ok_or_else(|| {
|
||||
Error::invalid_params("Invalid param: could not find mint".to_string())
|
||||
})?;
|
||||
if mint_account.owner != spl_token_id_v1_0() {
|
||||
let (mint_owner, decimals) = get_mint_owner_and_decimals(&bank, mint)?;
|
||||
if mint_owner != spl_token_id_v1_0() {
|
||||
return Err(Error::invalid_params(
|
||||
"Invalid param: not a v1.0 Token mint".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let filters = vec![
|
||||
// Filter on Mint address
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary(mint.to_string()),
|
||||
encoding: None,
|
||||
}),
|
||||
// Filter on Token Account state
|
||||
RpcFilterType::DataSize(size_of::<TokenAccount>() as u64),
|
||||
];
|
||||
let supply = get_filtered_program_accounts(&bank, &mint_owner, filters)
|
||||
.map(|(_pubkey, account)| {
|
||||
let mut data = account.data.to_vec();
|
||||
spl_token_v1_0::state::unpack(&mut data)
|
||||
.map(|account: &mut TokenAccount| account.amount)
|
||||
.unwrap_or(0)
|
||||
})
|
||||
.sum();
|
||||
let supply = token_amount_to_ui_amount(supply, decimals);
|
||||
new_response(&bank, supply)
|
||||
}
|
||||
|
||||
pub fn get_token_largest_accounts(
|
||||
&self,
|
||||
mint: &Pubkey,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcTokenAccountBalance>>> {
|
||||
let bank = self.bank(commitment)?;
|
||||
let (mint_owner, decimals) = get_mint_owner_and_decimals(&bank, mint)?;
|
||||
if mint_owner != spl_token_id_v1_0() {
|
||||
return Err(Error::invalid_params(
|
||||
"Invalid param: not a v1.0 Token mint".to_string(),
|
||||
));
|
||||
@@ -832,24 +904,41 @@ impl JsonRpcRequestProcessor {
|
||||
// Filter on Token Account state
|
||||
RpcFilterType::DataSize(size_of::<TokenAccount>() as u64),
|
||||
];
|
||||
let supply = get_filtered_program_accounts(&bank, &mint_account.owner, filters)
|
||||
.map(|(_pubkey, account)| {
|
||||
let mut data = account.data.to_vec();
|
||||
TokenState::unpack(&mut data)
|
||||
.map(|account: &mut TokenAccount| account.amount)
|
||||
.unwrap_or(0)
|
||||
})
|
||||
.sum();
|
||||
new_response(&bank, supply)
|
||||
let mut token_balances: Vec<RpcTokenAccountBalance> =
|
||||
get_filtered_program_accounts(&bank, &mint_owner, filters)
|
||||
.map(|(address, account)| {
|
||||
let mut data = account.data.to_vec();
|
||||
let amount = spl_token_v1_0::state::unpack(&mut data)
|
||||
.map(|account: &mut TokenAccount| account.amount)
|
||||
.unwrap_or(0);
|
||||
let amount = token_amount_to_ui_amount(amount, decimals);
|
||||
RpcTokenAccountBalance {
|
||||
address: address.to_string(),
|
||||
amount,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
token_balances.sort_by(|a, b| {
|
||||
a.amount
|
||||
.amount
|
||||
.parse::<u64>()
|
||||
.unwrap()
|
||||
.cmp(&b.amount.amount.parse::<u64>().unwrap())
|
||||
.reverse()
|
||||
});
|
||||
token_balances.truncate(NUM_LARGEST_ACCOUNTS);
|
||||
new_response(&bank, token_balances)
|
||||
}
|
||||
|
||||
pub fn get_token_accounts_by_owner(
|
||||
&self,
|
||||
owner: &Pubkey,
|
||||
token_account_filter: TokenAccountsFilter,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcKeyedAccount>>> {
|
||||
let bank = self.bank(commitment)?;
|
||||
let config = config.unwrap_or_default();
|
||||
let bank = self.bank(config.commitment)?;
|
||||
let encoding = config.encoding.unwrap_or(UiAccountEncoding::Binary);
|
||||
let (token_program_id, mint) = get_token_program_id_and_mint(&bank, token_account_filter)?;
|
||||
|
||||
let mut filters = vec![
|
||||
@@ -873,7 +962,7 @@ impl JsonRpcRequestProcessor {
|
||||
let accounts = get_filtered_program_accounts(&bank, &token_program_id, filters)
|
||||
.map(|(pubkey, account)| RpcKeyedAccount {
|
||||
pubkey: pubkey.to_string(),
|
||||
account: UiAccount::encode(account, UiAccountEncoding::JsonParsed),
|
||||
account: UiAccount::encode(account, encoding.clone()),
|
||||
})
|
||||
.collect();
|
||||
new_response(&bank, accounts)
|
||||
@@ -883,9 +972,11 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
delegate: &Pubkey,
|
||||
token_account_filter: TokenAccountsFilter,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcKeyedAccount>>> {
|
||||
let bank = self.bank(commitment)?;
|
||||
let config = config.unwrap_or_default();
|
||||
let bank = self.bank(config.commitment)?;
|
||||
let encoding = config.encoding.unwrap_or(UiAccountEncoding::Binary);
|
||||
let (token_program_id, mint) = get_token_program_id_and_mint(&bank, token_account_filter)?;
|
||||
|
||||
let mut filters = vec![
|
||||
@@ -917,7 +1008,7 @@ impl JsonRpcRequestProcessor {
|
||||
let accounts = get_filtered_program_accounts(&bank, &token_program_id, filters)
|
||||
.map(|(pubkey, account)| RpcKeyedAccount {
|
||||
pubkey: pubkey.to_string(),
|
||||
account: UiAccount::encode(account, UiAccountEncoding::JsonParsed),
|
||||
account: UiAccount::encode(account, encoding.clone()),
|
||||
})
|
||||
.collect();
|
||||
new_response(&bank, accounts)
|
||||
@@ -1000,15 +1091,13 @@ fn get_token_program_id_and_mint(
|
||||
) -> Result<(Pubkey, Option<Pubkey>)> {
|
||||
match token_account_filter {
|
||||
TokenAccountsFilter::Mint(mint) => {
|
||||
let mint_account = bank.get_account(&mint).ok_or_else(|| {
|
||||
Error::invalid_params("Invalid param: could not find mint".to_string())
|
||||
})?;
|
||||
if mint_account.owner != spl_token_id_v1_0() {
|
||||
let (mint_owner, _) = get_mint_owner_and_decimals(&bank, &mint)?;
|
||||
if mint_owner != spl_token_id_v1_0() {
|
||||
return Err(Error::invalid_params(
|
||||
"Invalid param: not a v1.0 Token mint".to_string(),
|
||||
));
|
||||
}
|
||||
Ok((mint_account.owner, Some(mint)))
|
||||
Ok((mint_owner, Some(mint)))
|
||||
}
|
||||
TokenAccountsFilter::ProgramId(program_id) => {
|
||||
if program_id == spl_token_id_v1_0() {
|
||||
@@ -1022,6 +1111,41 @@ fn get_token_program_id_and_mint(
|
||||
}
|
||||
}
|
||||
|
||||
/// Analyze a mint Pubkey that may be the native_mint and get the mint-account owner (token
|
||||
/// program_id) and decimals
|
||||
fn get_mint_owner_and_decimals(bank: &Arc<Bank>, mint: &Pubkey) -> Result<(Pubkey, u8)> {
|
||||
if mint == &spl_token_v1_0_native_mint() {
|
||||
// Uncomment the following once spl_token is bumped to a version that includes native_mint::DECIMALS
|
||||
// Ok((spl_token_id_v1_0(), spl_token_v1_0::native_mint::DECIMALS))
|
||||
Ok((spl_token_id_v1_0(), 9))
|
||||
} else {
|
||||
let mint_account = bank.get_account(mint).ok_or_else(|| {
|
||||
Error::invalid_params("Invalid param: could not find mint".to_string())
|
||||
})?;
|
||||
let decimals = get_mint_decimals(&mint_account.data)?;
|
||||
Ok((mint_account.owner, decimals))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mint_decimals(data: &[u8]) -> Result<u8> {
|
||||
let mut data = data.to_vec();
|
||||
spl_token_v1_0::state::unpack(&mut data)
|
||||
.map_err(|_| {
|
||||
Error::invalid_params("Invalid param: Token mint could not be unpacked".to_string())
|
||||
})
|
||||
.map(|mint: &mut Mint| mint.decimals)
|
||||
}
|
||||
|
||||
fn token_amount_to_ui_amount(amount: u64, decimals: u8) -> RpcTokenAmount {
|
||||
// Use `amount_to_ui_amount()` once spl_token is bumped to a version that supports it: https://github.com/solana-labs/solana-program-library/pull/211
|
||||
let amount_decimals = amount as f64 / 10_usize.pow(decimals as u32) as f64;
|
||||
RpcTokenAmount {
|
||||
ui_amount: amount_decimals,
|
||||
decimals,
|
||||
amount: amount.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[rpc]
|
||||
pub trait RpcSol {
|
||||
type Metadata;
|
||||
@@ -1284,6 +1408,14 @@ pub trait RpcSol {
|
||||
end_slot: Slot,
|
||||
) -> Result<Vec<String>>;
|
||||
|
||||
#[rpc(meta, name = "getConfirmedSignaturesForAddress2")]
|
||||
fn get_confirmed_signatures_for_address2(
|
||||
&self,
|
||||
meta: Self::Metadata,
|
||||
address: String,
|
||||
config: Option<RpcGetConfirmedSignaturesForAddress2Config>,
|
||||
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>>;
|
||||
|
||||
#[rpc(meta, name = "getFirstAvailableBlock")]
|
||||
fn get_first_available_block(&self, meta: Self::Metadata) -> Result<Slot>;
|
||||
|
||||
@@ -1305,7 +1437,7 @@ pub trait RpcSol {
|
||||
meta: Self::Metadata,
|
||||
pubkey_str: String,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<u64>>;
|
||||
) -> Result<RpcResponse<RpcTokenAmount>>;
|
||||
|
||||
#[rpc(meta, name = "getTokenSupply")]
|
||||
fn get_token_supply(
|
||||
@@ -1313,7 +1445,15 @@ pub trait RpcSol {
|
||||
meta: Self::Metadata,
|
||||
mint_str: String,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<u64>>;
|
||||
) -> Result<RpcResponse<RpcTokenAmount>>;
|
||||
|
||||
#[rpc(meta, name = "getTokenLargestAccounts")]
|
||||
fn get_token_largest_accounts(
|
||||
&self,
|
||||
meta: Self::Metadata,
|
||||
mint_str: String,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcTokenAccountBalance>>>;
|
||||
|
||||
#[rpc(meta, name = "getTokenAccountsByOwner")]
|
||||
fn get_token_accounts_by_owner(
|
||||
@@ -1321,7 +1461,7 @@ pub trait RpcSol {
|
||||
meta: Self::Metadata,
|
||||
owner_str: String,
|
||||
token_account_filter: RpcTokenAccountsFilter,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcKeyedAccount>>>;
|
||||
|
||||
#[rpc(meta, name = "getTokenAccountsByDelegate")]
|
||||
@@ -1330,7 +1470,7 @@ pub trait RpcSol {
|
||||
meta: Self::Metadata,
|
||||
delegate_str: String,
|
||||
token_account_filter: RpcTokenAccountsFilter,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcKeyedAccount>>>;
|
||||
}
|
||||
|
||||
@@ -1904,6 +2044,34 @@ impl RpcSol for RpcSolImpl {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_confirmed_signatures_for_address2(
|
||||
&self,
|
||||
meta: Self::Metadata,
|
||||
address: String,
|
||||
config: Option<RpcGetConfirmedSignaturesForAddress2Config>,
|
||||
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>> {
|
||||
let address = verify_pubkey(address)?;
|
||||
|
||||
let config = config.unwrap_or_default();
|
||||
let before = if let Some(before) = config.before {
|
||||
Some(verify_signature(&before)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let limit = config
|
||||
.limit
|
||||
.unwrap_or(MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT);
|
||||
|
||||
if limit == 0 || limit > MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT {
|
||||
return Err(Error::invalid_params(format!(
|
||||
"Invalid limit; max {}",
|
||||
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT
|
||||
)));
|
||||
}
|
||||
|
||||
meta.get_confirmed_signatures_for_address2(address, before, limit)
|
||||
}
|
||||
|
||||
fn get_first_available_block(&self, meta: Self::Metadata) -> Result<Slot> {
|
||||
debug!("get_first_available_block rpc request received");
|
||||
meta.get_first_available_block()
|
||||
@@ -1928,7 +2096,7 @@ impl RpcSol for RpcSolImpl {
|
||||
meta: Self::Metadata,
|
||||
pubkey_str: String,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<u64>> {
|
||||
) -> Result<RpcResponse<RpcTokenAmount>> {
|
||||
debug!(
|
||||
"get_token_account_balance rpc request received: {:?}",
|
||||
pubkey_str
|
||||
@@ -1942,18 +2110,32 @@ impl RpcSol for RpcSolImpl {
|
||||
meta: Self::Metadata,
|
||||
mint_str: String,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<u64>> {
|
||||
) -> Result<RpcResponse<RpcTokenAmount>> {
|
||||
debug!("get_token_supply rpc request received: {:?}", mint_str);
|
||||
let mint = verify_pubkey(mint_str)?;
|
||||
meta.get_token_supply(&mint, commitment)
|
||||
}
|
||||
|
||||
fn get_token_largest_accounts(
|
||||
&self,
|
||||
meta: Self::Metadata,
|
||||
mint_str: String,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcTokenAccountBalance>>> {
|
||||
debug!(
|
||||
"get_token_largest_accounts rpc request received: {:?}",
|
||||
mint_str
|
||||
);
|
||||
let mint = verify_pubkey(mint_str)?;
|
||||
meta.get_token_largest_accounts(&mint, commitment)
|
||||
}
|
||||
|
||||
fn get_token_accounts_by_owner(
|
||||
&self,
|
||||
meta: Self::Metadata,
|
||||
owner_str: String,
|
||||
token_account_filter: RpcTokenAccountsFilter,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcKeyedAccount>>> {
|
||||
debug!(
|
||||
"get_token_accounts_by_owner rpc request received: {:?}",
|
||||
@@ -1961,7 +2143,7 @@ impl RpcSol for RpcSolImpl {
|
||||
);
|
||||
let owner = verify_pubkey(owner_str)?;
|
||||
let token_account_filter = verify_token_account_filter(token_account_filter)?;
|
||||
meta.get_token_accounts_by_owner(&owner, token_account_filter, commitment)
|
||||
meta.get_token_accounts_by_owner(&owner, token_account_filter, config)
|
||||
}
|
||||
|
||||
fn get_token_accounts_by_delegate(
|
||||
@@ -1969,7 +2151,7 @@ impl RpcSol for RpcSolImpl {
|
||||
meta: Self::Metadata,
|
||||
delegate_str: String,
|
||||
token_account_filter: RpcTokenAccountsFilter,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<RpcKeyedAccount>>> {
|
||||
debug!(
|
||||
"get_token_accounts_by_delegate rpc request received: {:?}",
|
||||
@@ -1977,7 +2159,7 @@ impl RpcSol for RpcSolImpl {
|
||||
);
|
||||
let delegate = verify_pubkey(delegate_str)?;
|
||||
let token_account_filter = verify_token_account_filter(token_account_filter)?;
|
||||
meta.get_token_accounts_by_delegate(&delegate, token_account_filter, commitment)
|
||||
meta.get_token_accounts_by_delegate(&delegate, token_account_filter, config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3362,7 +3544,7 @@ pub mod tests {
|
||||
let block_commitment_cache = Arc::new(RwLock::new(
|
||||
BlockCommitmentCache::default_with_blockstore(blockstore.clone()),
|
||||
));
|
||||
let bank_forks = new_bank_forks().0;
|
||||
let (bank_forks, mint_keypair, ..) = new_bank_forks();
|
||||
let health = RpcHealth::stub();
|
||||
|
||||
// Freeze bank 0 to prevent a panic in `run_transaction_simulation()`
|
||||
@@ -3390,8 +3572,8 @@ pub mod tests {
|
||||
)),
|
||||
);
|
||||
|
||||
let bad_transaction =
|
||||
system_transaction::transfer(&Keypair::new(), &Pubkey::default(), 42, Hash::default());
|
||||
let mut bad_transaction =
|
||||
system_transaction::transfer(&mint_keypair, &Pubkey::new_rand(), 42, Hash::default());
|
||||
|
||||
// sendTransaction will fail because the blockhash is invalid
|
||||
let req = format!(
|
||||
@@ -3406,9 +3588,23 @@ pub mod tests {
|
||||
)
|
||||
);
|
||||
|
||||
// sendTransaction will fail due to insanity
|
||||
bad_transaction.message.instructions[0].program_id_index = 255u8;
|
||||
let recent_blockhash = bank_forks.read().unwrap().root_bank().last_blockhash();
|
||||
bad_transaction.sign(&[&mint_keypair], recent_blockhash);
|
||||
let req = format!(
|
||||
r#"{{"jsonrpc":"2.0","id":1,"method":"sendTransaction","params":["{}"]}}"#,
|
||||
bs58::encode(serialize(&bad_transaction).unwrap()).into_string()
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
assert_eq!(
|
||||
res,
|
||||
Some(
|
||||
r#"{"jsonrpc":"2.0","error":{"code":-32002,"message":"Transaction simulation failed: TransactionError::SanitizeFailure"},"id":1}"#.to_string(),
|
||||
)
|
||||
);
|
||||
let mut bad_transaction =
|
||||
system_transaction::transfer(&Keypair::new(), &Pubkey::default(), 42, recent_blockhash);
|
||||
system_transaction::transfer(&mint_keypair, &Pubkey::new_rand(), 42, recent_blockhash);
|
||||
|
||||
// sendTransaction will fail due to poor node health
|
||||
health.stub_set_health_status(Some(RpcHealthStatus::Behind));
|
||||
@@ -4181,7 +4377,8 @@ pub mod tests {
|
||||
let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&Pubkey::new_rand());
|
||||
|
||||
let mut account_data = [0; size_of::<TokenAccount>()];
|
||||
let account: &mut TokenAccount = TokenState::unpack_unchecked(&mut account_data).unwrap();
|
||||
let account: &mut TokenAccount =
|
||||
spl_token_v1_0::state::unpack_unchecked(&mut account_data).unwrap();
|
||||
let mint = SplTokenPubkey::new(&[2; 32]);
|
||||
let owner = SplTokenPubkey::new(&[3; 32]);
|
||||
let delegate = SplTokenPubkey::new(&[4; 32]);
|
||||
@@ -4189,7 +4386,7 @@ pub mod tests {
|
||||
mint,
|
||||
owner,
|
||||
delegate: COption::Some(delegate),
|
||||
amount: 42,
|
||||
amount: 420,
|
||||
is_initialized: true,
|
||||
is_native: false,
|
||||
delegated_amount: 30,
|
||||
@@ -4203,29 +4400,10 @@ pub mod tests {
|
||||
let token_account_pubkey = Pubkey::new_rand();
|
||||
bank.store_account(&token_account_pubkey, &token_account);
|
||||
|
||||
let req = format!(
|
||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getTokenAccountBalance","params":["{}"]}}"#,
|
||||
token_account_pubkey,
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
let balance: u64 = serde_json::from_value(result["result"]["value"].clone()).unwrap();
|
||||
assert_eq!(balance, 42);
|
||||
|
||||
// Test non-existent token account
|
||||
let req = format!(
|
||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getTokenAccountBalance","params":["{}"]}}"#,
|
||||
Pubkey::new_rand(),
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
assert!(result.get("error").is_some());
|
||||
|
||||
// Add the mint, plus another token account to ensure getTokenSupply sums all mint accounts
|
||||
// Add the mint
|
||||
let mut mint_data = [0; size_of::<Mint>()];
|
||||
let mint_state: &mut Mint = TokenState::unpack_unchecked(&mut mint_data).unwrap();
|
||||
let mint_state: &mut Mint =
|
||||
spl_token_v1_0::state::unpack_unchecked(&mut mint_data).unwrap();
|
||||
*mint_state = Mint {
|
||||
owner: COption::Some(owner),
|
||||
decimals: 2,
|
||||
@@ -4238,6 +4416,32 @@ pub mod tests {
|
||||
..Account::default()
|
||||
};
|
||||
bank.store_account(&Pubkey::from_str(&mint.to_string()).unwrap(), &mint_account);
|
||||
|
||||
let req = format!(
|
||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getTokenAccountBalance","params":["{}"]}}"#,
|
||||
token_account_pubkey,
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
let balance: RpcTokenAmount =
|
||||
serde_json::from_value(result["result"]["value"].clone()).unwrap();
|
||||
let error = f64::EPSILON;
|
||||
assert!((balance.ui_amount - 4.2).abs() < error);
|
||||
assert_eq!(balance.amount, 420.to_string());
|
||||
assert_eq!(balance.decimals, 2);
|
||||
|
||||
// Test non-existent token account
|
||||
let req = format!(
|
||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getTokenAccountBalance","params":["{}"]}}"#,
|
||||
Pubkey::new_rand(),
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
assert!(result.get("error").is_some());
|
||||
|
||||
// Add another token account to ensure getTokenSupply sums all mint accounts
|
||||
let other_token_account_pubkey = Pubkey::new_rand();
|
||||
bank.store_account(&other_token_account_pubkey, &token_account);
|
||||
|
||||
@@ -4248,8 +4452,12 @@ pub mod tests {
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
let supply: u64 = serde_json::from_value(result["result"]["value"].clone()).unwrap();
|
||||
assert_eq!(supply, 2 * 42);
|
||||
let supply: RpcTokenAmount =
|
||||
serde_json::from_value(result["result"]["value"].clone()).unwrap();
|
||||
let error = f64::EPSILON;
|
||||
assert!((supply.ui_amount - 2.0 * 4.2).abs() < error);
|
||||
assert_eq!(supply.amount, (2 * 420).to_string());
|
||||
assert_eq!(supply.decimals, 2);
|
||||
|
||||
// Test non-existent mint address
|
||||
let req = format!(
|
||||
@@ -4263,7 +4471,8 @@ pub mod tests {
|
||||
|
||||
// Add another token account with the same owner and delegate but different mint
|
||||
let mut account_data = [0; size_of::<TokenAccount>()];
|
||||
let account: &mut TokenAccount = TokenState::unpack_unchecked(&mut account_data).unwrap();
|
||||
let account: &mut TokenAccount =
|
||||
spl_token_v1_0::state::unpack_unchecked(&mut account_data).unwrap();
|
||||
let new_mint = SplTokenPubkey::new(&[5; 32]);
|
||||
*account = TokenAccount {
|
||||
mint: new_mint,
|
||||
@@ -4430,7 +4639,7 @@ pub mod tests {
|
||||
.expect("actual response deserialization");
|
||||
assert!(result.get("error").is_some());
|
||||
|
||||
// Test non-existent Owner
|
||||
// Test non-existent Delegate
|
||||
let req = format!(
|
||||
r#"{{
|
||||
"jsonrpc":"2.0",
|
||||
@@ -4441,11 +4650,83 @@ pub mod tests {
|
||||
Pubkey::new_rand(),
|
||||
spl_token_id_v1_0(),
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta);
|
||||
let res = io.handle_request_sync(&req, meta.clone());
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
let accounts: Vec<RpcKeyedAccount> =
|
||||
serde_json::from_value(result["result"]["value"].clone()).unwrap();
|
||||
assert!(accounts.is_empty());
|
||||
|
||||
// Add new_mint, and another token account on new_mint with different balance
|
||||
let mut mint_data = [0; size_of::<Mint>()];
|
||||
let mint_state: &mut Mint =
|
||||
spl_token_v1_0::state::unpack_unchecked(&mut mint_data).unwrap();
|
||||
*mint_state = Mint {
|
||||
owner: COption::Some(owner),
|
||||
decimals: 2,
|
||||
is_initialized: true,
|
||||
};
|
||||
let mint_account = Account {
|
||||
lamports: 111,
|
||||
data: mint_data.to_vec(),
|
||||
owner: spl_token_id_v1_0(),
|
||||
..Account::default()
|
||||
};
|
||||
bank.store_account(
|
||||
&Pubkey::from_str(&new_mint.to_string()).unwrap(),
|
||||
&mint_account,
|
||||
);
|
||||
let mut account_data = [0; size_of::<TokenAccount>()];
|
||||
let account: &mut TokenAccount =
|
||||
spl_token_v1_0::state::unpack_unchecked(&mut account_data).unwrap();
|
||||
*account = TokenAccount {
|
||||
mint: new_mint,
|
||||
owner,
|
||||
delegate: COption::Some(delegate),
|
||||
amount: 10,
|
||||
is_initialized: true,
|
||||
is_native: false,
|
||||
delegated_amount: 30,
|
||||
};
|
||||
let token_account = Account {
|
||||
lamports: 111,
|
||||
data: account_data.to_vec(),
|
||||
owner: spl_token_id_v1_0(),
|
||||
..Account::default()
|
||||
};
|
||||
let token_with_smaller_balance = Pubkey::new_rand();
|
||||
bank.store_account(&token_with_smaller_balance, &token_account);
|
||||
|
||||
// Test largest token accounts
|
||||
let req = format!(
|
||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getTokenLargestAccounts","params":["{}"]}}"#,
|
||||
new_mint,
|
||||
);
|
||||
let res = io.handle_request_sync(&req, meta);
|
||||
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
let largest_accounts: Vec<RpcTokenAccountBalance> =
|
||||
serde_json::from_value(result["result"]["value"].clone()).unwrap();
|
||||
assert_eq!(
|
||||
largest_accounts,
|
||||
vec![
|
||||
RpcTokenAccountBalance {
|
||||
address: token_with_different_mint_pubkey.to_string(),
|
||||
amount: RpcTokenAmount {
|
||||
ui_amount: 0.42,
|
||||
decimals: 2,
|
||||
amount: "42".to_string(),
|
||||
}
|
||||
},
|
||||
RpcTokenAccountBalance {
|
||||
address: token_with_smaller_balance.to_string(),
|
||||
amount: RpcTokenAmount {
|
||||
ui_amount: 0.1,
|
||||
decimals: 2,
|
||||
amount: "10".to_string(),
|
||||
}
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-crate-features"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Crate Features"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -24,6 +24,7 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
||||
- [getConfirmedBlock](jsonrpc-api.md#getconfirmedblock)
|
||||
- [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks)
|
||||
- [getConfirmedSignaturesForAddress](jsonrpc-api.md#getconfirmedsignaturesforaddress)
|
||||
- [getConfirmedSignaturesForAddress2](jsonrpc-api.md#getconfirmedsignaturesforaddress2)
|
||||
- [getConfirmedTransaction](jsonrpc-api.md#getconfirmedtransaction)
|
||||
- [getEpochInfo](jsonrpc-api.md#getepochinfo)
|
||||
- [getEpochSchedule](jsonrpc-api.md#getepochschedule)
|
||||
@@ -389,6 +390,8 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m
|
||||
|
||||
### getConfirmedSignaturesForAddress
|
||||
|
||||
**DEPRECATED: Please use getConfirmedSignaturesForAddress2 instead**
|
||||
|
||||
Returns a list of all the confirmed signatures for transactions involving an
|
||||
address, within a specified Slot range. Max range allowed is 10,000 Slots
|
||||
|
||||
@@ -416,6 +419,37 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m
|
||||
{"jsonrpc":"2.0","result":{["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4bJdGN8Tt2kLWZ3Fa1dpwPSEkXWWTSszPSf1rRVsCwNjxbbUdwTeiWtmi8soA26YmwnKD4aAxNp8ci1Gjpdv4gsr","4LQ14a7BYY27578Uj8LPCaVhSdJGLn9DJqnUJHpy95FMqdKf9acAhUhecPQNjNUy6VoNFUbvwYkPociFSf87cWbG"]},"id":1}
|
||||
```
|
||||
|
||||
|
||||
### getConfirmedSignaturesForAddress2
|
||||
|
||||
Returns confirmed signatures for transactions involving an
|
||||
address backwards in time from the provided signature or most recent confirmed block
|
||||
|
||||
#### Parameters:
|
||||
* `<string>` - account address as base-58 encoded string
|
||||
* `<object>` - (optional) Configuration object containing the following fields:
|
||||
* `before: <string>` - (optional) start searching backwards from this transaction signature.
|
||||
If not provided the search starts from the top of the highest max confirmed block.
|
||||
* `limit: <number>` - (optional) maximum transaction signatures to return (between 1 and 1,000, default: 1,000).
|
||||
|
||||
#### Results:
|
||||
The result field will be an array of transaction signature information, ordered
|
||||
from newest to oldest transaction:
|
||||
* `<object>`
|
||||
* `signature: <string>` - transaction signature as base-58 encoded string
|
||||
* `slot: <u64>` - The slot that contains the block with the transaction
|
||||
* `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
|
||||
* `memo: <string |null>` - Memo associated with the transaction, null if no memo is present
|
||||
|
||||
#### Example:
|
||||
```bash
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedSignaturesForAddress2","params":["Vote111111111111111111111111111111111111111", {"limit": 1}]}' localhost:8899
|
||||
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":[{"err":null,"memo":null,"signature":"5h6xBEauJ3PK6SWCZ1PGjBvj8vDdWG3KpwATGy1ARAXFSDwt8GFXM7W5Ncn16wmqokgpiKRLuS83KUxyZyv2sUYv","slot":114}],"id":1}
|
||||
```
|
||||
|
||||
### getConfirmedTransaction
|
||||
|
||||
Returns transaction details for a confirmed transaction
|
||||
@@ -1031,7 +1065,11 @@ Returns the token balance of an SPL Token account.
|
||||
|
||||
#### Results:
|
||||
|
||||
- `RpcResponse<u64>` - RpcResponse JSON object with `value` field set to the balance
|
||||
The result will be an RpcResponse JSON object with `value` equal to a JSON object containing:
|
||||
|
||||
- `uiAmount: <f64>` - the balance, using mint-prescribed decimals
|
||||
- `amount: <string>` - the raw balance without decimals, a string representation of u64
|
||||
- `decimals: <u8>` - number of base 10 digits to the right of the decimal place
|
||||
|
||||
#### Example:
|
||||
|
||||
@@ -1039,7 +1077,7 @@ Returns the token balance of an SPL Token account.
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getTokenAccountBalance", "params": ["7fUAJdStEuGbc3sM84cKRL6yYaaSstyLSU4ve5oovLS7"]}' http://localhost:8899
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":9864,"id":1}
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":{"uiAmount":98.64,"amount":"9864","decimals":2},"id":1}
|
||||
```
|
||||
|
||||
### getTokenAccountsByDelegate
|
||||
@@ -1052,7 +1090,10 @@ Returns all SPL Token accounts by approved Delegate.
|
||||
- `<object>` - Either:
|
||||
* `mint: <string>` - Pubkey of the specific token Mint to limit accounts to, as base-58 encoded string; or
|
||||
* `programId: <string>` - Pubkey of the Token program ID that owns the accounts, as base-58 encoded string
|
||||
- `<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) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -1062,7 +1103,7 @@ The result will be an RpcResponse JSON object with `value` equal to an array of
|
||||
- `account: <object>` - a JSON object, with the following sub fields:
|
||||
- `lamports: <u64>`, number of lamports assigned to this account, as a u64
|
||||
- `owner: <string>`, base-58 encoded Pubkey of the program this account has been assigned to
|
||||
`data: <object>`, Token state data associated with the account, in JSON format `{<program>: <state>}`
|
||||
- `data: <object>`, Token state data associated with the account, either as base-58 encoded binary data or in JSON format `{<program>: <state>}`
|
||||
- `executable: <bool>`, boolean indicating if the account contains a program \(and is strictly read-only\)
|
||||
- `rentEpoch: <u64>`, the epoch at which this account will next owe rent, as u64
|
||||
|
||||
@@ -1070,9 +1111,9 @@ The result will be an RpcResponse JSON object with `value` equal to an array of
|
||||
|
||||
```bash
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getTokenAccountsByDelegate", "params": ["4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T", {"programId": "TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o"}]}' http://localhost:8899
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getTokenAccountsByDelegate", "params": ["4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T", {"programId": "TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o"}, {"encoding": "jsonParsed"}]}' http://localhost:8899
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":[{"data":{"token":{"account":{"amount":1,"delegate":"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T","delegatedAmount":1,"isInitialized":true,"isNative":false,"mint":"3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E","owner":"CnPoSPKXu7wJqxe59Fs72tkBeALovhsCxYeFwPCQH9TD"}}},"executable":false,"lamports":1726080,"owner":"TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o","rentEpoch":4},"pubkey":"CnPoSPKXu7wJqxe59Fs72tkBeALovhsCxYeFwPCQH9TD"}],"id":1}
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":[{"data":{"program":"spl-token","parsed":{"accountType":"account","info":{"amount":1,"delegate":"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T","delegatedAmount":1,"isInitialized":true,"isNative":false,"mint":"3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E","owner":"CnPoSPKXu7wJqxe59Fs72tkBeALovhsCxYeFwPCQH9TD"}}},"executable":false,"lamports":1726080,"owner":"TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o","rentEpoch":4},"pubkey":"CnPoSPKXu7wJqxe59Fs72tkBeALovhsCxYeFwPCQH9TD"}],"id":1}
|
||||
```
|
||||
|
||||
### getTokenAccountsByOwner
|
||||
@@ -1085,7 +1126,10 @@ Returns all SPL Token accounts by token owner.
|
||||
- `<object>` - Either:
|
||||
* `mint: <string>` - Pubkey of the specific token Mint to limit accounts to, as base-58 encoded string; or
|
||||
* `programId: <string>` - Pubkey of the Token program ID that owns the accounts, as base-58 encoded string
|
||||
- `<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) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
|
||||
Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type `<string>`.
|
||||
|
||||
#### Results:
|
||||
|
||||
@@ -1095,7 +1139,7 @@ The result will be an RpcResponse JSON object with `value` equal to an array of
|
||||
- `account: <object>` - a JSON object, with the following sub fields:
|
||||
- `lamports: <u64>`, number of lamports assigned to this account, as a u64
|
||||
- `owner: <string>`, base-58 encoded Pubkey of the program this account has been assigned to
|
||||
`data: <object>`, Token state data associated with the account, in JSON format `{<program>: <state>}`
|
||||
- `data: <object>`, Token state data associated with the account, either as base-58 encoded binary data or in JSON format `{<program>: <state>}`
|
||||
- `executable: <bool>`, boolean indicating if the account contains a program \(and is strictly read-only\)
|
||||
- `rentEpoch: <u64>`, the epoch at which this account will next owe rent, as u64
|
||||
|
||||
@@ -1103,9 +1147,9 @@ The result will be an RpcResponse JSON object with `value` equal to an array of
|
||||
|
||||
```bash
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getTokenAccountsByOwner", "params": ["4Qkev8aNZcqFNSRhQzwyLMFSsi94jHqE8WNVTJzTP99F", {"mint":"3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E"}]}' http://localhost:8899
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getTokenAccountsByOwner", "params": ["4Qkev8aNZcqFNSRhQzwyLMFSsi94jHqE8WNVTJzTP99F", {"mint":"3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E"}, {"encoding": "jsonParsed"}]}' http://localhost:8899
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":[{"data":{"token":{"account":{"amount":1,"delegate":null,"delegatedAmount":1,"isInitialized":true,"isNative":false,"mint":"3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E","owner":"4Qkev8aNZcqFNSRhQzwyLMFSsi94jHqE8WNVTJzTP99F"}}},"executable":false,"lamports":1726080,"owner":"TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o","rentEpoch":4},"pubkey":"CnPoSPKXu7wJqxe59Fs72tkBeALovhsCxYeFwPCQH9TD"}],"id":1}
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":[{"data":{"program":"spl-token","parsed":{"accountType":"account","info":{"amount":1,"delegate":null,"delegatedAmount":1,"isInitialized":true,"isNative":false,"mint":"3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E","owner":"4Qkev8aNZcqFNSRhQzwyLMFSsi94jHqE8WNVTJzTP99F"}}},"executable":false,"lamports":1726080,"owner":"TokenSVp5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o","rentEpoch":4},"pubkey":"CnPoSPKXu7wJqxe59Fs72tkBeALovhsCxYeFwPCQH9TD"}],"id":1}
|
||||
```
|
||||
|
||||
### getTokenSupply
|
||||
@@ -1119,7 +1163,11 @@ Returns the total supply of an SPL Token type.
|
||||
|
||||
#### Results:
|
||||
|
||||
- `RpcResponse<u64>` - RpcResponse JSON object with `value` field set to the total token supply
|
||||
The result will be an RpcResponse JSON object with `value` equal to a JSON object containing:
|
||||
|
||||
- `uiAmount: <f64>` - the total token supply, using mint-prescribed decimals
|
||||
- `amount: <string>` - the raw total token supply without decimals, a string representation of u64
|
||||
- `decimals: <u8>` - number of base 10 digits to the right of the decimal place
|
||||
|
||||
#### Example:
|
||||
|
||||
@@ -1127,7 +1175,7 @@ Returns the total supply of an SPL Token type.
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getTokenSupply", "params": ["3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E"]}' http://localhost:8899
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":100000,"id":1}
|
||||
{"jsonrpc":"2.0","result":{"context":{"slot":1114},"value":{"uiAmount":1000.0,"amount":"100000","decimals":2},"id":1}
|
||||
```
|
||||
|
||||
### getTransactionCount
|
||||
@@ -1172,7 +1220,7 @@ The result field will be a JSON object with the following fields:
|
||||
// Request
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.2.17"},"id":1}
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.2.19"},"id":1}
|
||||
```
|
||||
|
||||
### getVoteAccounts
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-dos"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,14 +13,14 @@ clap = "2.33.1"
|
||||
log = "0.4.8"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-download-utils"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Download Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,8 +14,8 @@ console = "0.10.1"
|
||||
indicatif = "0.14.0"
|
||||
log = "0.4.8"
|
||||
reqwest = { version = "0.10.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
tar = "0.4.28"
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-faucet"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Faucet"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,11 +16,11 @@ clap = "2.33"
|
||||
log = "0.4.8"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
tokio = "0.1"
|
||||
tokio-codec = "0.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-genesis-programs"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana genesis programs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,12 +10,12 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = { version = "0.4.8" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.17" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.17" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.17" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-genesis"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,14 +15,14 @@ chrono = "0.4"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,20 +3,20 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-gossip"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-install"
|
||||
description = "The solana cluster software installer"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -24,12 +24,12 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
semver = "0.9.0"
|
||||
tar = "0.4.28"
|
||||
tempdir = "0.3.7"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-keygen"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana key generation utility"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,11 +13,11 @@ bs58 = "0.3.1"
|
||||
clap = "2.33"
|
||||
dirs = "2.0.2"
|
||||
num_cpus = "1.13.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.17" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
tiny-bip39 = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-ledger-tool"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -16,16 +16,16 @@ histogram = "*"
|
||||
log = { version = "0.4.8" }
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-cli = { path = "../cli", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli = { path = "../cli", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
regex = "1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ledger"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana ledger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -32,19 +32,19 @@ reed-solomon-erasure = { version = "4.0.2", features = ["simd-accel"] }
|
||||
regex = "1.3.7"
|
||||
serde = "1.0.110"
|
||||
serde_bytes = "0.11.4"
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-perf = { path = "../perf", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
ed25519-dalek = "1.0.0-pre.3"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
symlink = "0.1.0"
|
||||
tar = "0.4.28"
|
||||
thiserror = "1.0"
|
||||
@@ -62,7 +62,7 @@ features = ["lz4"]
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
matches = "0.1.6"
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.17" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -37,14 +37,15 @@ use solana_sdk::{
|
||||
transaction::Transaction,
|
||||
};
|
||||
use solana_transaction_status::{
|
||||
ConfirmedBlock, ConfirmedTransaction, EncodedTransaction, Rewards, TransactionStatusMeta,
|
||||
TransactionWithStatusMeta, UiTransactionEncoding, UiTransactionStatusMeta,
|
||||
ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature,
|
||||
EncodedTransaction, Rewards, TransactionStatusMeta, TransactionWithStatusMeta,
|
||||
UiTransactionEncoding, UiTransactionStatusMeta,
|
||||
};
|
||||
use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::TIMESTAMP_SLOT_INTERVAL};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
cmp,
|
||||
collections::HashMap,
|
||||
collections::{HashMap, HashSet},
|
||||
fs,
|
||||
io::{Error as IOError, ErrorKind},
|
||||
path::{Path, PathBuf},
|
||||
@@ -1864,7 +1865,8 @@ impl Blockstore {
|
||||
}
|
||||
|
||||
// Returns all cached signatures for an address, ordered by slot that the transaction was
|
||||
// processed in
|
||||
// processed in. Within each slot the transactions will be ordered by signature, and NOT by
|
||||
// the order in which the transactions exist in the block
|
||||
fn find_address_signatures(
|
||||
&self,
|
||||
pubkey: Pubkey,
|
||||
@@ -1914,6 +1916,121 @@ impl Blockstore {
|
||||
.map(|signatures| signatures.iter().map(|(_, signature)| *signature).collect())
|
||||
}
|
||||
|
||||
pub fn get_confirmed_signatures_for_address2(
|
||||
&self,
|
||||
address: Pubkey,
|
||||
highest_confirmed_root: Slot,
|
||||
before: Option<Signature>,
|
||||
limit: usize,
|
||||
) -> Result<Vec<ConfirmedTransactionStatusWithSignature>> {
|
||||
datapoint_info!(
|
||||
"blockstore-rpc-api",
|
||||
(
|
||||
"method",
|
||||
"get_confirmed_signatures_for_address2".to_string(),
|
||||
String
|
||||
)
|
||||
);
|
||||
|
||||
// Figure the `slot` to start listing signatures at, based on the ledger location of the
|
||||
// `before` signature if present. Also generate a HashSet of signatures that should
|
||||
// be excluded from the results.
|
||||
let (mut slot, mut excluded_signatures) = match before {
|
||||
None => (highest_confirmed_root, None),
|
||||
Some(before) => {
|
||||
let transaction_status = self.get_transaction_status(before)?;
|
||||
match transaction_status {
|
||||
None => return Ok(vec![]),
|
||||
Some((slot, _)) => {
|
||||
let confirmed_block = self
|
||||
.get_confirmed_block(slot, Some(UiTransactionEncoding::Binary))
|
||||
.map_err(|err| {
|
||||
BlockstoreError::IO(IOError::new(
|
||||
ErrorKind::Other,
|
||||
format!("Unable to get confirmed block: {}", err),
|
||||
))
|
||||
})?;
|
||||
|
||||
// Load all signatures for the block
|
||||
let mut slot_signatures: Vec<_> = confirmed_block
|
||||
.transactions
|
||||
.iter()
|
||||
.filter_map(|transaction_with_meta| {
|
||||
if let Some(transaction) =
|
||||
transaction_with_meta.transaction.decode()
|
||||
{
|
||||
transaction.signatures.into_iter().next()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Sort signatures as a way to entire a stable ordering within a slot, as
|
||||
// `self.find_address_signatures()` is ordered by signatures ordered and
|
||||
// not by block ordering
|
||||
slot_signatures.sort();
|
||||
|
||||
if let Some(pos) = slot_signatures.iter().position(|&x| x == before) {
|
||||
slot_signatures.truncate(pos + 1);
|
||||
}
|
||||
|
||||
(
|
||||
slot,
|
||||
Some(slot_signatures.into_iter().collect::<HashSet<_>>()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch the list of signatures that affect the given address
|
||||
let first_available_block = self.get_first_available_block()?;
|
||||
let mut address_signatures = vec![];
|
||||
loop {
|
||||
if address_signatures.len() >= limit {
|
||||
address_signatures.truncate(limit);
|
||||
break;
|
||||
}
|
||||
|
||||
let mut signatures = self.find_address_signatures(address, slot, slot)?;
|
||||
if let Some(excluded_signatures) = excluded_signatures.take() {
|
||||
address_signatures.extend(
|
||||
signatures
|
||||
.into_iter()
|
||||
.filter(|(_, signature)| !excluded_signatures.contains(&signature)),
|
||||
)
|
||||
} else {
|
||||
address_signatures.append(&mut signatures);
|
||||
}
|
||||
excluded_signatures = None;
|
||||
|
||||
if slot == first_available_block {
|
||||
break;
|
||||
}
|
||||
slot -= 1;
|
||||
}
|
||||
address_signatures.truncate(limit);
|
||||
|
||||
// Fill in the status information for each found transaction
|
||||
let mut infos = vec![];
|
||||
for (slot, signature) in address_signatures.into_iter() {
|
||||
let transaction_status = self.get_transaction_status(signature)?;
|
||||
let err = match transaction_status {
|
||||
None => None,
|
||||
Some((_slot, status)) => status.status.err(),
|
||||
};
|
||||
infos.push(ConfirmedTransactionStatusWithSignature {
|
||||
signature,
|
||||
slot,
|
||||
err,
|
||||
memo: None,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(infos)
|
||||
}
|
||||
|
||||
pub fn read_rewards(&self, index: Slot) -> Result<Option<Rewards>> {
|
||||
self.rewards_cf.get(index)
|
||||
}
|
||||
@@ -6082,6 +6199,168 @@ pub mod tests {
|
||||
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_confirmed_signatures_for_address2() {
|
||||
let blockstore_path = get_tmp_ledger_path!();
|
||||
{
|
||||
let blockstore = Blockstore::open(&blockstore_path).unwrap();
|
||||
|
||||
fn make_slot_entries_with_transaction_addresses(addresses: &[Pubkey]) -> Vec<Entry> {
|
||||
let mut entries: Vec<Entry> = Vec::new();
|
||||
for address in addresses {
|
||||
let transaction = Transaction::new_with_compiled_instructions(
|
||||
&[&Keypair::new()],
|
||||
&[*address],
|
||||
Hash::default(),
|
||||
vec![Pubkey::new_rand()],
|
||||
vec![CompiledInstruction::new(1, &(), vec![0])],
|
||||
);
|
||||
entries.push(next_entry_mut(&mut Hash::default(), 0, vec![transaction]));
|
||||
let mut tick = create_ticks(1, 0, hash(&serialize(address).unwrap()));
|
||||
entries.append(&mut tick);
|
||||
}
|
||||
entries
|
||||
}
|
||||
|
||||
let address0 = Pubkey::new_rand();
|
||||
let address1 = Pubkey::new_rand();
|
||||
|
||||
for slot in 2..=4 {
|
||||
let entries = make_slot_entries_with_transaction_addresses(&[
|
||||
address0, address1, address0, address1,
|
||||
]);
|
||||
let shreds = entries_to_test_shreds(entries.clone(), slot, slot - 1, true, 0);
|
||||
blockstore.insert_shreds(shreds, None, false).unwrap();
|
||||
|
||||
for entry in &entries {
|
||||
for transaction in &entry.transactions {
|
||||
assert_eq!(transaction.signatures.len(), 1);
|
||||
blockstore
|
||||
.write_transaction_status(
|
||||
slot,
|
||||
transaction.signatures[0],
|
||||
transaction.message.account_keys.iter().collect(),
|
||||
vec![],
|
||||
&TransactionStatusMeta::default(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
blockstore.set_roots(&[1, 2, 3, 4]).unwrap();
|
||||
let highest_confirmed_root = 4;
|
||||
|
||||
// Fetch all signatures for address 0 at once...
|
||||
let all0 = blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address0,
|
||||
highest_confirmed_root,
|
||||
None,
|
||||
usize::MAX,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(all0.len(), 6);
|
||||
|
||||
// Fetch all signatures for address 1 at once...
|
||||
let all1 = blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address1,
|
||||
highest_confirmed_root,
|
||||
None,
|
||||
usize::MAX,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(all1.len(), 6);
|
||||
|
||||
assert!(all0 != all1);
|
||||
|
||||
// Fetch all signatures for address 0 individually
|
||||
for i in 0..all0.len() {
|
||||
let results = blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address0,
|
||||
highest_confirmed_root,
|
||||
if i == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(all0[i - 1].signature)
|
||||
},
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(results[0], all0[i], "Unexpected result for {}", i);
|
||||
}
|
||||
|
||||
assert!(blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address0,
|
||||
highest_confirmed_root,
|
||||
Some(all0[all0.len() - 1].signature),
|
||||
1,
|
||||
)
|
||||
.unwrap()
|
||||
.is_empty());
|
||||
|
||||
// Fetch all signatures for address 0, three at a time
|
||||
assert!(all0.len() % 3 == 0);
|
||||
for i in (0..all0.len()).step_by(3) {
|
||||
let results = blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address0,
|
||||
highest_confirmed_root,
|
||||
if i == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(all0[i - 1].signature)
|
||||
},
|
||||
3,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(results.len(), 3);
|
||||
assert_eq!(results[0], all0[i]);
|
||||
assert_eq!(results[1], all0[i + 1]);
|
||||
assert_eq!(results[2], all0[i + 2]);
|
||||
}
|
||||
|
||||
// Ensure that the signatures within a slot are ordered by signature
|
||||
// (current limitation of the .get_confirmed_signatures_for_address2())
|
||||
for i in (0..all1.len()).step_by(2) {
|
||||
let results = blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address1,
|
||||
highest_confirmed_root,
|
||||
if i == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(all1[i - 1].signature)
|
||||
},
|
||||
2,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(results.len(), 2);
|
||||
assert_eq!(results[0].slot, results[1].slot);
|
||||
assert!(results[0].signature <= results[1].signature);
|
||||
assert_eq!(results[0], all1[i]);
|
||||
assert_eq!(results[1], all1[i + 1]);
|
||||
}
|
||||
|
||||
// A search for address 0 with a `before` signature from address1 should also work
|
||||
let results = blockstore
|
||||
.get_confirmed_signatures_for_address2(
|
||||
address0,
|
||||
highest_confirmed_root,
|
||||
Some(all1[0].signature),
|
||||
usize::MAX,
|
||||
)
|
||||
.unwrap();
|
||||
// The exact number of results returned is variable, based on the sort order of the
|
||||
// random signatures that are generated
|
||||
assert!(!results.is_empty());
|
||||
}
|
||||
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_last_hash() {
|
||||
let mut entries: Vec<Entry> = vec![];
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-local-cluster"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -12,22 +12,22 @@ homepage = "https://solana.com/"
|
||||
itertools = "0.9.0"
|
||||
log = "0.4.8"
|
||||
rand = "0.7.0"
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-download-utils = { path = "../download-utils", version = "1.2.17" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.17" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.17" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.17" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-download-utils = { path = "../download-utils", version = "1.2.19" }
|
||||
solana-faucet = { path = "../faucet", version = "1.2.19" }
|
||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.19" }
|
||||
solana-genesis-programs = { path = "../genesis-programs", version = "1.2.19" }
|
||||
solana-ledger = { path = "../ledger", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vest-program = { path = "../programs/vest", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.17" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-log-analyzer"
|
||||
description = "The solana cluster network analysis tool"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,9 +14,9 @@ byte-unit = "3.1.1"
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[[bin]]
|
||||
name = "solana-log-analyzer"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-logger"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Logger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-measure"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "../README.md"
|
||||
@@ -12,8 +12,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.8"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
jemallocator = "0.3.2"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-merkle-tree"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Merkle Tree"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
fast-math = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-metrics"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Metrics"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,7 +14,7 @@ gethostname = "0.2.1"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.8"
|
||||
reqwest = { version = "0.10.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.0"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-net-shaper"
|
||||
description = "The solana cluster network shaping tool"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,8 +13,8 @@ publish = false
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
rand = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-net-utils"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Network Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,9 +18,9 @@ rand = "0.7.0"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
socket2 = "0.3.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
tokio = "0.1"
|
||||
tokio-codec = "0.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-notifier"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Notifier"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-perf"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Performance APIs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -17,11 +17,11 @@ serde = "1.0.110"
|
||||
dlopen_derive = "0.1.4"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.8"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.17" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-budget-program = { path = "../programs/budget", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
curve25519-dalek = { version = "2" }
|
||||
|
||||
[lib]
|
||||
|
170
programs/bpf/Cargo.lock
generated
170
programs/bpf/Cargo.lock
generated
@@ -280,7 +280,7 @@ name = "ed25519"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.112 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signature 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1399,7 +1399,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-loader-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1407,170 +1407,170 @@ dependencies = [
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-logger 1.2.17",
|
||||
"solana-runtime 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-logger 1.2.19",
|
||||
"solana-runtime 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
"solana_rbpf 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-programs"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-bpf-loader-program 1.2.17",
|
||||
"solana-logger 1.2.17",
|
||||
"solana-runtime 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-bpf-loader-program 1.2.19",
|
||||
"solana-logger 1.2.19",
|
||||
"solana-runtime 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
"solana_rbpf 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-128bit-dep 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-bpf-rust-128bit-dep 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-128bit-dep"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-alloc"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-dep-crate"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-dup-accounts"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-error-handling"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-external-spend"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-invoked 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-bpf-rust-invoked 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoked"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-iter"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-many-args"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-many-args-dep 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-bpf-rust-many-args-dep 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-many-args-dep"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-noop"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-panic"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-param-passing"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-param-passing-dep 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-bpf-rust-param-passing-dep 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-param-passing-dep"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sysval"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-config-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-crate-features"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"backtrace 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1593,7 +1593,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-logger"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1602,30 +1602,30 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-measure"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-metrics 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-metrics 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-metrics"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-sdk 1.2.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1633,7 +1633,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-runtime"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bv 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1653,21 +1653,21 @@ dependencies = [
|
||||
"rayon 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-config-program 1.2.17",
|
||||
"solana-logger 1.2.17",
|
||||
"solana-measure 1.2.17",
|
||||
"solana-metrics 1.2.17",
|
||||
"solana-rayon-threadlimit 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-stake-program 1.2.17",
|
||||
"solana-vote-program 1.2.17",
|
||||
"solana-config-program 1.2.19",
|
||||
"solana-logger 1.2.19",
|
||||
"solana-measure 1.2.19",
|
||||
"solana-metrics 1.2.19",
|
||||
"solana-rayon-threadlimit 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
"solana-stake-program 1.2.19",
|
||||
"solana-vote-program 1.2.19",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-sdk"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1694,15 +1694,15 @@ dependencies = [
|
||||
"serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-crate-features 1.2.17",
|
||||
"solana-logger 1.2.17",
|
||||
"solana-sdk-macro 1.2.17",
|
||||
"solana-crate-features 1.2.19",
|
||||
"solana-logger 1.2.19",
|
||||
"solana-sdk-macro 1.2.19",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-sdk-macro"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bs58 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1713,7 +1713,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-stake-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1721,16 +1721,16 @@ dependencies = [
|
||||
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-config-program 1.2.17",
|
||||
"solana-metrics 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-vote-program 1.2.17",
|
||||
"solana-config-program 1.2.19",
|
||||
"solana-metrics 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
"solana-vote-program 1.2.19",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-vote-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
dependencies = [
|
||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1738,8 +1738,8 @@ dependencies = [
|
||||
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-metrics 1.2.17",
|
||||
"solana-sdk 1.2.17",
|
||||
"solana-metrics 1.2.19",
|
||||
"solana-sdk 1.2.19",
|
||||
"thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2325,10 +2325,10 @@ name = "zeroize_derive"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
@@ -2367,6 +2367,7 @@ dependencies = [
|
||||
"checksum curve25519-dalek 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5"
|
||||
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
"checksum dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
||||
"checksum ed25519 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf038a7b6fd7ef78ad3348b63f3a17550877b0e28f8d68bcc94894d1412158bc"
|
||||
"checksum ed25519-dalek 1.0.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)" = "21a8a37f4e8b35af971e6db5e3897e7a6344caa3f92f6544f88125a1f5f0035a"
|
||||
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
"checksum elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4841de15dbe0e49b9b62a417589299e3be0d557e0900d36acb87e6dae47197f5"
|
||||
@@ -2559,3 +2560,4 @@ dependencies = [
|
||||
"checksum winreg 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
|
||||
"checksum zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-bpf-programs"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "README.md"
|
||||
@@ -22,10 +22,10 @@ walkdir = "2"
|
||||
bincode = "1.1.4"
|
||||
byteorder = "1.3.2"
|
||||
elf = "0.0.10"
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.2.17" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.2.19" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana_rbpf = "=0.1.28"
|
||||
|
||||
[[bench]]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.2.19" }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit-dep"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-alloc"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-dep-crate"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,7 +13,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = { version = "1", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-dup-accounts"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-error-handling"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,7 +14,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
num-derive = "0.2"
|
||||
num-traits = "0.2"
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
thiserror = "1.0"
|
||||
|
||||
[features]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-external-spend"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-invoke"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,7 +13,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-bpf-rust-invoked = { path = "../invoked"}
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-invoked"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-iter"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-many-args"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.2.19" }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-many-args-dep"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-noop"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-panic"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-param-passing"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,8 +12,8 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.2.19" }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-param-passing-dep"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-bpf-rust-sysval"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,7 +12,7 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.17", default-features = false }
|
||||
solana-sdk = { path = "../../../../sdk/", version = "1.2.19", default-features = false }
|
||||
|
||||
[features]
|
||||
program = ["solana-sdk/program"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-loader-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana BPF loader"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,9 +15,9 @@ jemalloc-sys = { version = "0.3.2", features = ["disable_initial_exec_tls"] }
|
||||
log = "0.4.8"
|
||||
num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana_rbpf = "=0.1.28"
|
||||
thiserror = "1.0"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-btc-spv-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Bitcoin spv parsing program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,7 +15,7 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17"}
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19"}
|
||||
hex = "0.4.2"
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "btc_spv_bin"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Bitcoin spv parsing program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-budget-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Budget program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,11 +16,11 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-config-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Config program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,10 +14,10 @@ chrono = { version = "0.4.11", features = ["serde"] }
|
||||
log = "0.4.8"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../../logger", version = "1.2.17" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-exchange-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Exchange program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,13 +15,13 @@ num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-logger = { path = "../../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-failure-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana failure program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -9,10 +9,10 @@ homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-noop-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Noop program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,8 +10,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.8"
|
||||
solana-logger = { path = "../../logger", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ownable"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "ownable program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,13 +10,13 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.2.1"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-stake-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Stake program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,14 +15,14 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../vote", version = "1.2.17" }
|
||||
solana-config-program = { path = "../config", version = "1.2.17" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../vote", version = "1.2.19" }
|
||||
solana-config-program = { path = "../config", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../../logger", version = "1.2.17" }
|
||||
solana-logger = { path = "../../logger", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-vest-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Vest program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,12 +15,12 @@ num-derive = "0.2"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-config-program = { path = "../config", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
solana-config-program = { path = "../config", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.17" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.2.19" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-vote-program"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Vote program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,8 +15,8 @@ num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.17" }
|
||||
solana-metrics = { path = "../../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[lib]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-ramp-tps"
|
||||
description = "Solana Tour de SOL - TPS ramp up"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/tour-de-sol"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -16,12 +16,12 @@ reqwest = { version = "0.10.4", default-features = false }
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.17" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-net-utils = { path = "../net-utils", version = "1.2.19" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
tar = "0.4.28"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "solana-rayon-threadlimit"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "../README.md"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-remote-wallet"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -18,7 +18,7 @@ num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
parking_lot = "0.10"
|
||||
semver = "0.9"
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
url = "2.1.1"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-runtime"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana runtime"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -27,14 +27,14 @@ rand = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
serde = { version = "1.0.110", features = ["rc"] }
|
||||
serde_derive = "1.0.103"
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.17" }
|
||||
solana-config-program = { path = "../programs/config", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -44,7 +44,7 @@ name = "solana_runtime"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
solana-noop-program = { path = "../programs/noop", version = "1.2.17" }
|
||||
solana-noop-program = { path = "../programs/noop", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -629,8 +629,7 @@ impl Accounts {
|
||||
use solana_sdk::sanitize::Sanitize;
|
||||
let keys: Vec<Result<_>> = OrderedIterator::new(txs, txs_iteration_order)
|
||||
.map(|tx| {
|
||||
tx.sanitize()
|
||||
.map_err(|_| TransactionError::SanitizeFailure)?;
|
||||
tx.sanitize().map_err(TransactionError::from)?;
|
||||
|
||||
if Self::has_duplicates(&tx.message.account_keys) {
|
||||
return Err(TransactionError::AccountLoadedTwice);
|
||||
|
@@ -48,6 +48,7 @@ use solana_sdk::{
|
||||
native_loader, nonce,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
sanitize::Sanitize,
|
||||
signature::{Keypair, Signature},
|
||||
slot_hashes::SlotHashes,
|
||||
slot_history::SlotHistory,
|
||||
@@ -1135,7 +1136,11 @@ impl Bank {
|
||||
&'a self,
|
||||
txs: &'b [Transaction],
|
||||
) -> TransactionBatch<'a, 'b> {
|
||||
let mut batch = TransactionBatch::new(vec![Ok(()); txs.len()], &self, txs, None);
|
||||
let lock_results: Vec<_> = txs
|
||||
.iter()
|
||||
.map(|tx| tx.sanitize().map_err(|e| e.into()))
|
||||
.collect();
|
||||
let mut batch = TransactionBatch::new(lock_results, &self, txs, None);
|
||||
batch.needs_unlock = false;
|
||||
batch
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-scripts"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-sdk"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana SDK"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -53,9 +53,9 @@ serde_json = { version = "1.0.53", optional = true }
|
||||
sha2 = "0.8.2"
|
||||
thiserror = "1.0"
|
||||
ed25519-dalek = { version = "=1.0.0-pre.4", optional = true }
|
||||
solana-crate-features = { path = "../crate-features", version = "1.2.17", optional = true }
|
||||
solana-logger = { path = "../logger", version = "1.2.17", optional = true }
|
||||
solana-sdk-macro = { path = "macro", version = "1.2.17" }
|
||||
solana-crate-features = { path = "../crate-features", version = "1.2.19", optional = true }
|
||||
solana-logger = { path = "../logger", version = "1.2.19", optional = true }
|
||||
solana-sdk-macro = { path = "macro", version = "1.2.19" }
|
||||
rustversion = "1.0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-sdk-macro"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana SDK Macro"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -81,6 +81,12 @@ impl std::fmt::Display for TransactionError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SanitizeError> for TransactionError {
|
||||
fn from(_: SanitizeError) -> Self {
|
||||
Self::SanitizeFailure
|
||||
}
|
||||
}
|
||||
|
||||
/// An atomic transaction
|
||||
#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct Transaction {
|
||||
|
@@ -3,22 +3,22 @@ name = "solana-stake-accounts"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-stake-monitor"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,21 +14,21 @@ console = "0.10.1"
|
||||
log = "0.4.8"
|
||||
serde = "1.0.110"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.4.0"
|
||||
serial_test_derive = "0.4.0"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.19" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -6,21 +6,21 @@ homepage = "https://solana.com/"
|
||||
license = "Apache-2.0"
|
||||
name = "solana-stake-o-matic"
|
||||
repository = "https://github.com/solana-labs/stake-o-matic"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
log = "0.4.8"
|
||||
serde_yaml = "0.8.12"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-notifier = { path = "../notifier", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-streamer"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana Streamer"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,14 +10,14 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.8"
|
||||
solana-metrics = { path = "../metrics", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-metrics = { path = "../metrics", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
thiserror = "1.0"
|
||||
solana-measure = { path = "../measure", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-measure = { path = "../measure", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
libc = "0.2.70"
|
||||
nix = "0.17.0"
|
||||
solana-perf = { path = "../perf", version = "1.2.17" }
|
||||
solana-perf = { path = "../perf", version = "1.2.19" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
name = "solana-sys-tuner"
|
||||
description = "The solana cluster system tuner daemon"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,9 +13,9 @@ publish = true
|
||||
clap = "2.33.1"
|
||||
log = "0.4.8"
|
||||
libc = "0.2.70"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-logger = { path = "../logger", version = "1.2.17" }
|
||||
solana-version = { path = "../version", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-logger = { path = "../logger", version = "1.2.19" }
|
||||
solana-version = { path = "../version", version = "1.2.19" }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
unix_socket2 = "0.5.4"
|
||||
|
@@ -3,7 +3,7 @@ name = "solana-tokens"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2018"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -18,16 +18,16 @@ indexmap = "1.3.2"
|
||||
indicatif = "0.14.0"
|
||||
pickledb = "0.4.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.17" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.17" }
|
||||
solana-client = { path = "../client", version = "1.2.17" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.17" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.17" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.17" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.19" }
|
||||
solana-cli-config = { path = "../cli-config", version = "1.2.19" }
|
||||
solana-client = { path = "../client", version = "1.2.19" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.2.19" }
|
||||
solana-runtime = { path = "../runtime", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "1.2.19" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "1.2.19" }
|
||||
tempfile = "3.1.0"
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-core = { path = "../core", version = "1.2.17" }
|
||||
solana-core = { path = "../core", version = "1.2.19" }
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-transaction-status"
|
||||
version = "1.2.17"
|
||||
version = "1.2.19"
|
||||
description = "Solana transaction status types"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,10 +13,10 @@ bincode = "1.2.1"
|
||||
bs58 = "0.3.1"
|
||||
Inflector = "0.11.4"
|
||||
lazy_static = "1.4.0"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.17" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.17" }
|
||||
spl-memo-v1-0 = { package = "spl-memo", version = "1.0.4", features = ["skip-no-mangle"] }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.3", features = ["skip-no-mangle"] }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "1.2.19" }
|
||||
solana-sdk = { path = "../sdk", version = "1.2.19" }
|
||||
spl-memo-v1-0 = { package = "spl-memo", version = "1.0.7", features = ["skip-no-mangle"] }
|
||||
spl-token-v1-0 = { package = "spl-token", version = "1.0.6", features = ["skip-no-mangle"] }
|
||||
serde = "1.0.110"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.54"
|
||||
|
@@ -7,13 +7,17 @@ pub mod parse_accounts;
|
||||
pub mod parse_instruction;
|
||||
pub mod parse_token;
|
||||
|
||||
use crate::{parse_accounts::parse_accounts, parse_instruction::parse};
|
||||
use serde_json::Value;
|
||||
use crate::{
|
||||
parse_accounts::{parse_accounts, ParsedAccount},
|
||||
parse_instruction::{parse, ParsedInstruction},
|
||||
};
|
||||
use solana_sdk::{
|
||||
clock::{Slot, UnixTimestamp},
|
||||
commitment_config::CommitmentConfig,
|
||||
instruction::CompiledInstruction,
|
||||
message::MessageHeader,
|
||||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
transaction::{Result, Transaction, TransactionError},
|
||||
};
|
||||
|
||||
@@ -22,7 +26,14 @@ use solana_sdk::{
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
pub enum UiInstruction {
|
||||
Compiled(UiCompiledInstruction),
|
||||
Parsed(Value),
|
||||
Parsed(UiParsedInstruction),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
pub enum UiParsedInstruction {
|
||||
Parsed(ParsedInstruction),
|
||||
PartiallyDecoded(UiPartiallyDecodedInstruction),
|
||||
}
|
||||
|
||||
/// A duplicate representation of a CompiledInstruction for pretty JSON serialization
|
||||
@@ -44,6 +55,29 @@ impl From<&CompiledInstruction> for UiCompiledInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
/// A partially decoded CompiledInstruction that includes explicit account addresses
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiPartiallyDecodedInstruction {
|
||||
pub program_id: String,
|
||||
pub accounts: Vec<String>,
|
||||
pub data: String,
|
||||
}
|
||||
|
||||
impl UiPartiallyDecodedInstruction {
|
||||
fn from(instruction: &CompiledInstruction, account_keys: &[Pubkey]) -> Self {
|
||||
Self {
|
||||
program_id: account_keys[instruction.program_id_index as usize].to_string(),
|
||||
accounts: instruction
|
||||
.accounts
|
||||
.iter()
|
||||
.map(|&i| account_keys[i as usize].to_string())
|
||||
.collect(),
|
||||
data: bs58::encode(instruction.data.clone()).into_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TransactionStatusMeta {
|
||||
@@ -92,7 +126,7 @@ impl From<TransactionStatusMeta> for UiTransactionStatusMeta {
|
||||
pub struct TransactionStatus {
|
||||
pub slot: Slot,
|
||||
pub confirmations: Option<usize>, // None = rooted
|
||||
pub status: Result<()>,
|
||||
pub status: Result<()>, // legacy field
|
||||
pub err: Option<TransactionError>,
|
||||
}
|
||||
|
||||
@@ -103,6 +137,15 @@ impl TransactionStatus {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ConfirmedTransactionStatusWithSignature {
|
||||
pub signature: Signature,
|
||||
pub slot: Slot,
|
||||
pub err: Option<TransactionError>,
|
||||
pub memo: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Reward {
|
||||
pub pubkey: String,
|
||||
@@ -159,7 +202,7 @@ pub struct UiRawMessage {
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UiParsedMessage {
|
||||
pub account_keys: Value,
|
||||
pub account_keys: Vec<ParsedAccount>,
|
||||
pub recent_blockhash: String,
|
||||
pub instructions: Vec<UiInstruction>,
|
||||
}
|
||||
@@ -226,9 +269,16 @@ impl EncodedTransaction {
|
||||
instruction,
|
||||
&transaction.message.account_keys,
|
||||
) {
|
||||
UiInstruction::Parsed(parsed_instruction)
|
||||
UiInstruction::Parsed(UiParsedInstruction::Parsed(
|
||||
parsed_instruction,
|
||||
))
|
||||
} else {
|
||||
UiInstruction::Compiled(instruction.into())
|
||||
UiInstruction::Parsed(UiParsedInstruction::PartiallyDecoded(
|
||||
UiPartiallyDecodedInstruction::from(
|
||||
instruction,
|
||||
&transaction.message.account_keys,
|
||||
),
|
||||
))
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
|
@@ -1,28 +1,23 @@
|
||||
use serde_json::{json, Value};
|
||||
use solana_sdk::message::Message;
|
||||
|
||||
type AccountAttributes = Vec<AccountAttribute>;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum AccountAttribute {
|
||||
Signer,
|
||||
Writable,
|
||||
pub struct ParsedAccount {
|
||||
pub pubkey: String,
|
||||
pub writable: bool,
|
||||
pub signer: bool,
|
||||
}
|
||||
|
||||
pub fn parse_accounts(message: &Message) -> Value {
|
||||
let mut accounts: Vec<Value> = vec![];
|
||||
pub fn parse_accounts(message: &Message) -> Vec<ParsedAccount> {
|
||||
let mut accounts: Vec<ParsedAccount> = vec![];
|
||||
for (i, account_key) in message.account_keys.iter().enumerate() {
|
||||
let mut attributes: AccountAttributes = vec![];
|
||||
if message.is_writable(i) {
|
||||
attributes.push(AccountAttribute::Writable);
|
||||
}
|
||||
if message.is_signer(i) {
|
||||
attributes.push(AccountAttribute::Signer);
|
||||
}
|
||||
accounts.push(json!({ account_key.to_string(): attributes }));
|
||||
accounts.push(ParsedAccount {
|
||||
pubkey: account_key.to_string(),
|
||||
writable: message.is_writable(i),
|
||||
signer: message.is_signer(i),
|
||||
});
|
||||
}
|
||||
json!(accounts)
|
||||
accounts
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -44,13 +39,30 @@ mod test {
|
||||
};
|
||||
message.account_keys = vec![pubkey0, pubkey1, pubkey2, pubkey3];
|
||||
|
||||
let expected_json = json!([
|
||||
{pubkey0.to_string(): ["writable", "signer"]},
|
||||
{pubkey1.to_string(): ["signer"]},
|
||||
{pubkey2.to_string(): ["writable"]},
|
||||
{pubkey3.to_string(): []},
|
||||
]);
|
||||
|
||||
assert_eq!(parse_accounts(&message), expected_json);
|
||||
assert_eq!(
|
||||
parse_accounts(&message),
|
||||
vec![
|
||||
ParsedAccount {
|
||||
pubkey: pubkey0.to_string(),
|
||||
writable: true,
|
||||
signer: true,
|
||||
},
|
||||
ParsedAccount {
|
||||
pubkey: pubkey1.to_string(),
|
||||
writable: false,
|
||||
signer: true,
|
||||
},
|
||||
ParsedAccount {
|
||||
pubkey: pubkey2.to_string(),
|
||||
writable: true,
|
||||
signer: false,
|
||||
},
|
||||
ParsedAccount {
|
||||
pubkey: pubkey3.to_string(),
|
||||
writable: false,
|
||||
signer: false,
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use crate::parse_token::parse_token;
|
||||
use inflector::Inflector;
|
||||
use serde_json::{json, Value};
|
||||
use serde_json::Value;
|
||||
use solana_account_decoder::parse_token::spl_token_id_v1_0;
|
||||
use solana_sdk::{instruction::CompiledInstruction, pubkey::Pubkey};
|
||||
use std::{
|
||||
@@ -21,7 +21,7 @@ lazy_static! {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ParseInstructionError {
|
||||
#[error("{0:?} instruction not parsable")]
|
||||
InstructionNotParsable(ParsableProgram),
|
||||
@@ -31,6 +31,25 @@ pub enum ParseInstructionError {
|
||||
|
||||
#[error("Program not parsable")]
|
||||
ProgramNotParsable,
|
||||
|
||||
#[error("Internal error, please report")]
|
||||
SerdeJsonError(#[from] serde_json::error::Error),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ParsedInstruction {
|
||||
pub program: String,
|
||||
pub program_id: String,
|
||||
pub parsed: Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ParsedInstructionEnum {
|
||||
#[serde(rename = "type")]
|
||||
pub instruction_type: String,
|
||||
pub info: Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
@@ -44,17 +63,19 @@ pub fn parse(
|
||||
program_id: &Pubkey,
|
||||
instruction: &CompiledInstruction,
|
||||
account_keys: &[Pubkey],
|
||||
) -> Result<Value, ParseInstructionError> {
|
||||
) -> Result<ParsedInstruction, ParseInstructionError> {
|
||||
let program_name = PARSABLE_PROGRAM_IDS
|
||||
.get(program_id)
|
||||
.ok_or_else(|| ParseInstructionError::ProgramNotParsable)?;
|
||||
let parsed_json = match program_name {
|
||||
ParsableProgram::SplMemo => parse_memo(instruction),
|
||||
ParsableProgram::SplToken => parse_token(instruction, account_keys)?,
|
||||
ParsableProgram::SplToken => serde_json::to_value(parse_token(instruction, account_keys)?)?,
|
||||
};
|
||||
Ok(json!({
|
||||
format!("{:?}", program_name).to_kebab_case(): parsed_json
|
||||
}))
|
||||
Ok(ParsedInstruction {
|
||||
program: format!("{:?}", program_name).to_kebab_case(),
|
||||
program_id: program_id.to_string(),
|
||||
parsed: parsed_json,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_memo(instruction: &CompiledInstruction) -> Value {
|
||||
@@ -64,6 +85,7 @@ fn parse_memo(instruction: &CompiledInstruction) -> Value {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
@@ -72,18 +94,16 @@ mod test {
|
||||
accounts: vec![],
|
||||
data: vec![240, 159, 166, 150],
|
||||
};
|
||||
let expected_json = json!({
|
||||
"spl-memo": "🦖"
|
||||
});
|
||||
assert_eq!(
|
||||
parse(&MEMO_PROGRAM_ID, &memo_instruction, &[]).unwrap(),
|
||||
expected_json
|
||||
ParsedInstruction {
|
||||
program: "spl-memo".to_string(),
|
||||
program_id: MEMO_PROGRAM_ID.to_string(),
|
||||
parsed: json!("🦖"),
|
||||
}
|
||||
);
|
||||
|
||||
let non_parsable_program_id = Pubkey::new(&[1; 32]);
|
||||
assert_eq!(
|
||||
parse(&non_parsable_program_id, &memo_instruction, &[]).unwrap_err(),
|
||||
ParseInstructionError::ProgramNotParsable
|
||||
);
|
||||
assert!(parse(&non_parsable_program_id, &memo_instruction, &[]).is_err());
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use crate::parse_instruction::{ParsableProgram, ParseInstructionError};
|
||||
use crate::parse_instruction::{ParsableProgram, ParseInstructionError, ParsedInstructionEnum};
|
||||
use serde_json::{json, Map, Value};
|
||||
use solana_sdk::{instruction::CompiledInstruction, pubkey::Pubkey};
|
||||
use spl_token_v1_0::instruction::TokenInstruction;
|
||||
@@ -6,7 +6,7 @@ use spl_token_v1_0::instruction::TokenInstruction;
|
||||
pub fn parse_token(
|
||||
instruction: &CompiledInstruction,
|
||||
account_keys: &[Pubkey],
|
||||
) -> Result<Value, ParseInstructionError> {
|
||||
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
|
||||
let token_instruction = TokenInstruction::unpack(&instruction.data)
|
||||
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken))?;
|
||||
if instruction.accounts.len() > account_keys.len() {
|
||||
@@ -23,7 +23,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "initializeMint",
|
||||
"mint": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"amount": amount,
|
||||
"decimals":decimals,
|
||||
@@ -46,7 +45,10 @@ pub fn parse_token(
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "initializeMint".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::InitializeAccount => {
|
||||
if instruction.accounts.len() < 3 {
|
||||
@@ -54,12 +56,14 @@ pub fn parse_token(
|
||||
ParsableProgram::SplToken,
|
||||
));
|
||||
}
|
||||
Ok(json!({
|
||||
"type": "initializeAccount",
|
||||
"account": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"mint": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
"owner": account_keys[instruction.accounts[2] as usize].to_string(),
|
||||
}))
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "initializeAccount".to_string(),
|
||||
info: json!({
|
||||
"account": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"mint": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
"owner": account_keys[instruction.accounts[2] as usize].to_string(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
TokenInstruction::InitializeMultisig { m } => {
|
||||
if instruction.accounts.len() < 2 {
|
||||
@@ -71,12 +75,14 @@ pub fn parse_token(
|
||||
for i in instruction.accounts[1..].iter() {
|
||||
signers.push(account_keys[*i as usize].to_string());
|
||||
}
|
||||
Ok(json!({
|
||||
"type": "initializeMultisig",
|
||||
"multisig": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"signers": signers,
|
||||
"m": m,
|
||||
}))
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "initializeMultisig".to_string(),
|
||||
info: json!({
|
||||
"multisig": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"signers": signers,
|
||||
"m": m,
|
||||
}),
|
||||
})
|
||||
}
|
||||
TokenInstruction::Transfer { amount } => {
|
||||
if instruction.accounts.len() < 3 {
|
||||
@@ -85,7 +91,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "transfer",
|
||||
"source": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"destination": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
"amount": amount,
|
||||
@@ -99,7 +104,10 @@ pub fn parse_token(
|
||||
"authority",
|
||||
"multisigAuthority",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "transfer".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::Approve { amount } => {
|
||||
if instruction.accounts.len() < 3 {
|
||||
@@ -108,7 +116,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "approve",
|
||||
"source": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"delegate": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
"amount": amount,
|
||||
@@ -122,7 +129,10 @@ pub fn parse_token(
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "approve".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::Revoke => {
|
||||
if instruction.accounts.len() < 2 {
|
||||
@@ -131,7 +141,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "revoke",
|
||||
"source": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
});
|
||||
let mut map = value.as_object_mut().unwrap();
|
||||
@@ -143,7 +152,10 @@ pub fn parse_token(
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "revoke".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::SetOwner => {
|
||||
if instruction.accounts.len() < 3 {
|
||||
@@ -152,7 +164,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "setOwner",
|
||||
"owned": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"newOwner": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
});
|
||||
@@ -165,7 +176,10 @@ pub fn parse_token(
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "setOwner".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::MintTo { amount } => {
|
||||
if instruction.accounts.len() < 3 {
|
||||
@@ -174,7 +188,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "mintTo",
|
||||
"mint": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"account": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
"amount": amount,
|
||||
@@ -188,7 +201,10 @@ pub fn parse_token(
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "mintTo".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::Burn { amount } => {
|
||||
if instruction.accounts.len() < 2 {
|
||||
@@ -197,7 +213,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "burn",
|
||||
"account": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"amount": amount,
|
||||
});
|
||||
@@ -210,7 +225,10 @@ pub fn parse_token(
|
||||
"authority",
|
||||
"multisigAuthority",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "burn".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
TokenInstruction::CloseAccount => {
|
||||
if instruction.accounts.len() < 3 {
|
||||
@@ -219,7 +237,6 @@ pub fn parse_token(
|
||||
));
|
||||
}
|
||||
let mut value = json!({
|
||||
"type": "closeAccount",
|
||||
"account": account_keys[instruction.accounts[0] as usize].to_string(),
|
||||
"destination": account_keys[instruction.accounts[1] as usize].to_string(),
|
||||
});
|
||||
@@ -232,7 +249,10 @@ pub fn parse_token(
|
||||
"owner",
|
||||
"multisigOwner",
|
||||
);
|
||||
Ok(value)
|
||||
Ok(ParsedInstructionEnum {
|
||||
instruction_type: "closeAccount".to_string(),
|
||||
info: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,14 +331,16 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "initializeMint",
|
||||
"mint": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
"decimals": 2,
|
||||
"account": keys[1].to_string(),
|
||||
"owner": keys[2].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeMint".to_string(),
|
||||
info: json!({
|
||||
"mint": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
"decimals": 2,
|
||||
"account": keys[1].to_string(),
|
||||
"owner": keys[2].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let initialize_mint_ix = initialize_mint(
|
||||
@@ -334,13 +356,15 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "initializeMint",
|
||||
"mint": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
"decimals": 2,
|
||||
"account": keys[1].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeMint".to_string(),
|
||||
info: json!({
|
||||
"mint": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
"decimals": 2,
|
||||
"account": keys[1].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let initialize_mint_ix = initialize_mint(
|
||||
@@ -356,13 +380,15 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "initializeMint",
|
||||
"mint": keys[0].to_string(),
|
||||
"amount": 0,
|
||||
"decimals": 2,
|
||||
"owner": keys[1].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeMint".to_string(),
|
||||
info: json!({
|
||||
"mint": keys[0].to_string(),
|
||||
"amount": 0,
|
||||
"decimals": 2,
|
||||
"owner": keys[1].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test InitializeAccount
|
||||
@@ -377,12 +403,14 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "initializeAccount",
|
||||
"account": keys[0].to_string(),
|
||||
"mint": keys[1].to_string(),
|
||||
"owner": keys[2].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeAccount".to_string(),
|
||||
info: json!({
|
||||
"account": keys[0].to_string(),
|
||||
"mint": keys[1].to_string(),
|
||||
"owner": keys[2].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test InitializeMultisig
|
||||
@@ -401,12 +429,14 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "initializeMultisig",
|
||||
"multisig": keys[0].to_string(),
|
||||
"m": 2,
|
||||
"signers": keys[1..4].iter().map(|key| key.to_string()).collect::<Vec<String>>(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "initializeMultisig".to_string(),
|
||||
info: json!({
|
||||
"multisig": keys[0].to_string(),
|
||||
"m": 2,
|
||||
"signers": keys[1..4].iter().map(|key| key.to_string()).collect::<Vec<String>>(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test Transfer, incl multisig
|
||||
@@ -423,13 +453,15 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "transfer",
|
||||
"source": keys[1].to_string(),
|
||||
"destination": keys[2].to_string(),
|
||||
"authority": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "transfer".to_string(),
|
||||
info: json!({
|
||||
"source": keys[1].to_string(),
|
||||
"destination": keys[2].to_string(),
|
||||
"authority": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let transfer_ix = transfer(
|
||||
@@ -445,14 +477,16 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "transfer",
|
||||
"source": keys[2].to_string(),
|
||||
"destination": keys[3].to_string(),
|
||||
"multisigAuthority": keys[4].to_string(),
|
||||
"signers": keys[0..2].iter().map(|key| key.to_string()).collect::<Vec<String>>(),
|
||||
"amount": 42,
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "transfer".to_string(),
|
||||
info: json!({
|
||||
"source": keys[2].to_string(),
|
||||
"destination": keys[3].to_string(),
|
||||
"multisigAuthority": keys[4].to_string(),
|
||||
"signers": keys[0..2].iter().map(|key| key.to_string()).collect::<Vec<String>>(),
|
||||
"amount": 42,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test Approve, incl multisig
|
||||
@@ -469,13 +503,15 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "approve",
|
||||
"source": keys[1].to_string(),
|
||||
"delegate": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "approve".to_string(),
|
||||
info: json!({
|
||||
"source": keys[1].to_string(),
|
||||
"delegate": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let approve_ix = approve(
|
||||
@@ -491,14 +527,16 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "approve",
|
||||
"source": keys[2].to_string(),
|
||||
"delegate": keys[3].to_string(),
|
||||
"multisigOwner": keys[4].to_string(),
|
||||
"signers": keys[0..2].iter().map(|key| key.to_string()).collect::<Vec<String>>(),
|
||||
"amount": 42,
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "approve".to_string(),
|
||||
info: json!({
|
||||
"source": keys[2].to_string(),
|
||||
"delegate": keys[3].to_string(),
|
||||
"multisigOwner": keys[4].to_string(),
|
||||
"signers": keys[0..2].iter().map(|key| key.to_string()).collect::<Vec<String>>(),
|
||||
"amount": 42,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test Revoke
|
||||
@@ -513,11 +551,13 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "revoke",
|
||||
"source": keys[1].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "revoke".to_string(),
|
||||
info: json!({
|
||||
"source": keys[1].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test SetOwner
|
||||
@@ -533,12 +573,14 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "setOwner",
|
||||
"owned": keys[1].to_string(),
|
||||
"newOwner": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "setOwner".to_string(),
|
||||
info: json!({
|
||||
"owned": keys[1].to_string(),
|
||||
"newOwner": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test MintTo
|
||||
@@ -555,13 +597,15 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "mintTo",
|
||||
"mint": keys[1].to_string(),
|
||||
"account": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "mintTo".to_string(),
|
||||
info: json!({
|
||||
"mint": keys[1].to_string(),
|
||||
"account": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test Burn
|
||||
@@ -577,12 +621,14 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "burn",
|
||||
"account": keys[1].to_string(),
|
||||
"authority": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "burn".to_string(),
|
||||
info: json!({
|
||||
"account": keys[1].to_string(),
|
||||
"authority": keys[0].to_string(),
|
||||
"amount": 42,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
// Test CloseAccount
|
||||
@@ -598,12 +644,14 @@ mod test {
|
||||
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
|
||||
assert_eq!(
|
||||
parse_token(&compiled_instruction, &keys).unwrap(),
|
||||
json!({
|
||||
"type": "closeAccount",
|
||||
"account": keys[1].to_string(),
|
||||
"destination": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
})
|
||||
ParsedInstructionEnum {
|
||||
instruction_type: "closeAccount".to_string(),
|
||||
info: json!({
|
||||
"account": keys[1].to_string(),
|
||||
"destination": keys[2].to_string(),
|
||||
"owner": keys[0].to_string(),
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user