Cli error cleanup 1.0 (#8834)
* Don't use move semantics if not needed (#8793) * SDK: Deboilerplate `TransportError` with thiserror * Enable interchange between `TransportError` and `ClientError` * SDK: Retval consistency between `Client` and `AsyncClient` traits * Client: Introduce/use `Result` type * Client: Remove unused `RpcResponseIn` type * Client: Rename `RpcResponse` to more appropriate `RpcResult` * Client: Death to `io::Result` return types * Client: Struct-ify `ClientError` * Client: Add optional `command` parameter to `ClientError` * RpcClient: Stop abusing `io::Error` (low-fruit) * ClientError: Use `thiserror`'s `Display` impl * Extend `RpcError`'s utility * RpcClient: Stop abusing `io::Error` (the rest) * CLI: Shim `main()` so we can `Display` format errors * claputils: format input validator errors with `Display` They are intended to be displayed to users * SDK: `thiserror` for hash and sig parse erros * Keygen: Shim main to format errors with `Display` * SDK: `thiserror` for `InstructionError` * CLI: `thiserror` for `CliError` * CLI: Format user messages with `Display` * Client: Tweak `Display` for `ClientError` * RpcClient: Improve messaging when TX cannot be confirmed * fu death io res retval * CLI/Keygen - fix shell return value on error * Tweak `InstructionError` `Display` messages as per review * Cleanup hackjob return code fix * Embrace that which you hate most * Too much... Co-authored-by: Jack May <jack@solana.com>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3812,6 +3812,7 @@ dependencies = [
|
|||||||
"rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"solana-remote-wallet 1.0.6",
|
"solana-remote-wallet 1.0.6",
|
||||||
"solana-sdk 1.0.6",
|
"solana-sdk 1.0.6",
|
||||||
|
"thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@@ -379,8 +379,7 @@ impl Archiver {
|
|||||||
&archiver_keypair.pubkey(),
|
&archiver_keypair.pubkey(),
|
||||||
&storage_keypair.pubkey(),
|
&storage_keypair.pubkey(),
|
||||||
);
|
);
|
||||||
let message =
|
let message = Message::new_with_payer(&[ix], Some(&archiver_keypair.pubkey()));
|
||||||
Message::new_with_payer(vec![ix], Some(&archiver_keypair.pubkey()));
|
|
||||||
if let Err(e) = client.send_message(&[archiver_keypair.as_ref()], message) {
|
if let Err(e) = client.send_message(&[archiver_keypair.as_ref()], message) {
|
||||||
error!("unable to redeem reward, tx failed: {:?}", e);
|
error!("unable to redeem reward, tx failed: {:?}", e);
|
||||||
} else {
|
} else {
|
||||||
@@ -613,6 +612,7 @@ impl Archiver {
|
|||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
"setup_mining_account: signature not found",
|
"setup_mining_account: signature not found",
|
||||||
),
|
),
|
||||||
|
TransportError::Custom(e) => io::Error::new(ErrorKind::Other, e),
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -655,7 +655,7 @@ impl Archiver {
|
|||||||
Signature::new(&meta.signature.as_ref()),
|
Signature::new(&meta.signature.as_ref()),
|
||||||
meta.blockhash,
|
meta.blockhash,
|
||||||
);
|
);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&archiver_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&archiver_keypair.pubkey()));
|
||||||
let mut transaction = Transaction::new(
|
let mut transaction = Transaction::new(
|
||||||
&[archiver_keypair.as_ref(), storage_keypair.as_ref()],
|
&[archiver_keypair.as_ref(), storage_keypair.as_ref()],
|
||||||
message,
|
message,
|
||||||
|
@@ -13,6 +13,7 @@ clap = "2.33.0"
|
|||||||
rpassword = "4.0"
|
rpassword = "4.0"
|
||||||
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.6" }
|
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.6" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.0.6" }
|
solana-sdk = { path = "../sdk", version = "1.0.6" }
|
||||||
|
thiserror = "1.0.11"
|
||||||
tiny-bip39 = "0.7.0"
|
tiny-bip39 = "0.7.0"
|
||||||
url = "2.1.0"
|
url = "2.1.0"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
@@ -12,7 +12,7 @@ use std::str::FromStr;
|
|||||||
pub fn is_pubkey(string: String) -> Result<(), String> {
|
pub fn is_pubkey(string: String) -> Result<(), String> {
|
||||||
match string.parse::<Pubkey>() {
|
match string.parse::<Pubkey>() {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(format!("{:?}", err)),
|
Err(err) => Err(format!("{}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ pub fn is_pubkey(string: String) -> Result<(), String> {
|
|||||||
pub fn is_hash(string: String) -> Result<(), String> {
|
pub fn is_hash(string: String) -> Result<(), String> {
|
||||||
match string.parse::<Hash>() {
|
match string.parse::<Hash>() {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(format!("{:?}", err)),
|
Err(err) => Err(format!("{}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ pub fn is_hash(string: String) -> Result<(), String> {
|
|||||||
pub fn is_keypair(string: String) -> Result<(), String> {
|
pub fn is_keypair(string: String) -> Result<(), String> {
|
||||||
read_keypair_file(&string)
|
read_keypair_file(&string)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.map_err(|err| format!("{:?}", err))
|
.map_err(|err| format!("{}", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an error if a keypair file cannot be parsed
|
// Return an error if a keypair file cannot be parsed
|
||||||
@@ -38,7 +38,7 @@ pub fn is_keypair_or_ask_keyword(string: String) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
read_keypair_file(&string)
|
read_keypair_file(&string)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.map_err(|err| format!("{:?}", err))
|
.map_err(|err| format!("{}", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an error if string cannot be parsed as pubkey string or keypair file location
|
// Return an error if string cannot be parsed as pubkey string or keypair file location
|
||||||
@@ -73,10 +73,10 @@ pub fn is_pubkey_sig(string: String) -> Result<(), String> {
|
|||||||
.ok_or_else(|| "Malformed signer string".to_string())?,
|
.ok_or_else(|| "Malformed signer string".to_string())?,
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => Err(format!("{:?}", err)),
|
Err(err) => Err(format!("{}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Err(format!("{:?}", err)),
|
Err(err) => Err(format!("{}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,20 +90,20 @@ pub fn is_url(string: String) -> Result<(), String> {
|
|||||||
Err("no host provided".to_string())
|
Err("no host provided".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Err(format!("{:?}", err)),
|
Err(err) => Err(format!("{}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_slot(slot: String) -> Result<(), String> {
|
pub fn is_slot(slot: String) -> Result<(), String> {
|
||||||
slot.parse::<Slot>()
|
slot.parse::<Slot>()
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.map_err(|e| format!("{:?}", e))
|
.map_err(|e| format!("{}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_port(port: String) -> Result<(), String> {
|
pub fn is_port(port: String) -> Result<(), String> {
|
||||||
port.parse::<u16>()
|
port.parse::<u16>()
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.map_err(|e| format!("{:?}", e))
|
.map_err(|e| format!("{}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_valid_percentage(percentage: String) -> Result<(), String> {
|
pub fn is_valid_percentage(percentage: String) -> Result<(), String> {
|
||||||
@@ -111,7 +111,7 @@ pub fn is_valid_percentage(percentage: String) -> Result<(), String> {
|
|||||||
.parse::<u8>()
|
.parse::<u8>()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
format!(
|
format!(
|
||||||
"Unable to parse input percentage, provided: {}, err: {:?}",
|
"Unable to parse input percentage, provided: {}, err: {}",
|
||||||
percentage, e
|
percentage, e
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -141,7 +141,7 @@ pub fn is_amount(amount: String) -> Result<(), String> {
|
|||||||
pub fn is_rfc3339_datetime(value: String) -> Result<(), String> {
|
pub fn is_rfc3339_datetime(value: String) -> Result<(), String> {
|
||||||
DateTime::parse_from_rfc3339(&value)
|
DateTime::parse_from_rfc3339(&value)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.map_err(|e| format!("{:?}", e))
|
.map_err(|e| format!("{}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_derivation(value: String) -> Result<(), String> {
|
pub fn is_derivation(value: String) -> Result<(), String> {
|
||||||
@@ -152,7 +152,7 @@ pub fn is_derivation(value: String) -> Result<(), String> {
|
|||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
format!(
|
format!(
|
||||||
"Unable to parse derivation, provided: {}, err: {:?}",
|
"Unable to parse derivation, provided: {}, err: {}",
|
||||||
account, e
|
account, e
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -160,7 +160,7 @@ pub fn is_derivation(value: String) -> Result<(), String> {
|
|||||||
if let Some(change) = parts.next() {
|
if let Some(change) = parts.next() {
|
||||||
change.parse::<u32>().map_err(|e| {
|
change.parse::<u32>().map_err(|e| {
|
||||||
format!(
|
format!(
|
||||||
"Unable to parse derivation, provided: {}, err: {:?}",
|
"Unable to parse derivation, provided: {}, err: {}",
|
||||||
change, e
|
change, e
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
use crate::{input_parsers::pubkeys_sigs_of, offline::SIGNER_ARG, ArgConstant};
|
use crate::{input_parsers::pubkeys_sigs_of, offline::SIGNER_ARG, ArgConstant};
|
||||||
use bip39::{Language, Mnemonic, Seed};
|
use bip39::{Language, Mnemonic, Seed};
|
||||||
use clap::{ArgMatches, Error, ErrorKind};
|
use clap::ArgMatches;
|
||||||
use rpassword::prompt_password_stderr;
|
use rpassword::prompt_password_stderr;
|
||||||
use solana_remote_wallet::{
|
use solana_remote_wallet::{
|
||||||
remote_keypair::generate_remote_keypair,
|
remote_keypair::generate_remote_keypair,
|
||||||
@@ -71,7 +71,14 @@ pub fn signer_from_path(
|
|||||||
false,
|
false,
|
||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
KeypairUrl::Filepath(path) => Ok(Box::new(read_keypair_file(&path)?)),
|
KeypairUrl::Filepath(path) => match read_keypair_file(&path) {
|
||||||
|
Err(e) => Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
format!("could not find keypair file: {} error: {}", path, e),
|
||||||
|
)
|
||||||
|
.into()),
|
||||||
|
Ok(file) => Ok(Box::new(file)),
|
||||||
|
},
|
||||||
KeypairUrl::Stdin => {
|
KeypairUrl::Stdin => {
|
||||||
let mut stdin = std::io::stdin();
|
let mut stdin = std::io::stdin();
|
||||||
Ok(Box::new(read_keypair(&mut stdin)?))
|
Ok(Box::new(read_keypair(&mut stdin)?))
|
||||||
@@ -95,9 +102,9 @@ pub fn signer_from_path(
|
|||||||
if let Some(presigner) = presigner {
|
if let Some(presigner) = presigner {
|
||||||
Ok(Box::new(presigner))
|
Ok(Box::new(presigner))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::with_description(
|
Err(std::io::Error::new(
|
||||||
"Missing signature for supplied pubkey",
|
std::io::ErrorKind::Other,
|
||||||
ErrorKind::MissingRequiredArgument,
|
"missing signature for supplied pubkey".to_string(),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! version {
|
macro_rules! version {
|
||||||
() => {
|
() => {
|
||||||
@@ -23,6 +25,23 @@ pub struct ArgConstant<'a> {
|
|||||||
pub help: &'a str,
|
pub help: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error type for forwarding Errors out of `main()` of a `clap` app
|
||||||
|
/// and still using the `Display` formatter
|
||||||
|
#[derive(Error)]
|
||||||
|
#[error("{0}")]
|
||||||
|
pub struct DisplayError(Box<dyn std::error::Error>);
|
||||||
|
impl DisplayError {
|
||||||
|
pub fn new_as_boxed(inner: Box<dyn std::error::Error>) -> Box<Self> {
|
||||||
|
DisplayError(inner).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for DisplayError {
|
||||||
|
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(fmt, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod input_parsers;
|
pub mod input_parsers;
|
||||||
pub mod input_validators;
|
pub mod input_validators;
|
||||||
pub mod keypair;
|
pub mod keypair;
|
||||||
|
@@ -18,7 +18,10 @@ use solana_clap_utils::{
|
|||||||
input_parsers::*, input_validators::*, keypair::signer_from_path, offline::SIGN_ONLY_ARG,
|
input_parsers::*, input_validators::*, keypair::signer_from_path, offline::SIGN_ONLY_ARG,
|
||||||
ArgConstant,
|
ArgConstant,
|
||||||
};
|
};
|
||||||
use solana_client::{client_error::ClientError, rpc_client::RpcClient};
|
use solana_client::{
|
||||||
|
client_error::{ClientErrorKind, Result as ClientResult},
|
||||||
|
rpc_client::RpcClient,
|
||||||
|
};
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use solana_faucet::faucet::request_airdrop_transaction;
|
use solana_faucet::faucet::request_airdrop_transaction;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -47,14 +50,15 @@ use solana_stake_program::{
|
|||||||
use solana_storage_program::storage_instruction::StorageAccountType;
|
use solana_storage_program::storage_instruction::StorageAccountType;
|
||||||
use solana_vote_program::vote_state::VoteAuthorize;
|
use solana_vote_program::vote_state::VoteAuthorize;
|
||||||
use std::{
|
use std::{
|
||||||
|
error,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
net::{IpAddr, SocketAddr},
|
net::{IpAddr, SocketAddr},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
{error, fmt},
|
|
||||||
};
|
};
|
||||||
|
use thiserror::Error;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub type CliSigners = Vec<Box<dyn Signer>>;
|
pub type CliSigners = Vec<Box<dyn Signer>>;
|
||||||
@@ -406,46 +410,34 @@ pub struct CliCommandInfo {
|
|||||||
pub signers: CliSigners,
|
pub signers: CliSigners,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, Error, PartialEq)]
|
||||||
pub enum CliError {
|
pub enum CliError {
|
||||||
|
#[error("bad parameter: {0}")]
|
||||||
BadParameter(String),
|
BadParameter(String),
|
||||||
|
#[error("command not recognized: {0}")]
|
||||||
CommandNotRecognized(String),
|
CommandNotRecognized(String),
|
||||||
|
#[error("insuficient funds for fee")]
|
||||||
InsufficientFundsForFee,
|
InsufficientFundsForFee,
|
||||||
|
#[error(transparent)]
|
||||||
InvalidNonce(CliNonceError),
|
InvalidNonce(CliNonceError),
|
||||||
|
#[error("dynamic program error: {0}")]
|
||||||
DynamicProgramError(String),
|
DynamicProgramError(String),
|
||||||
|
#[error("rpc request error: {0}")]
|
||||||
RpcRequestError(String),
|
RpcRequestError(String),
|
||||||
|
#[error("keypair file not found: {0}")]
|
||||||
KeypairFileNotFound(String),
|
KeypairFileNotFound(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CliError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "invalid")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for CliError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
"invalid"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
// Generic error, underlying cause isn't tracked.
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Box<dyn error::Error>> for CliError {
|
impl From<Box<dyn error::Error>> for CliError {
|
||||||
fn from(error: Box<dyn error::Error>) -> Self {
|
fn from(error: Box<dyn error::Error>) -> Self {
|
||||||
CliError::DynamicProgramError(format!("{:?}", error))
|
CliError::DynamicProgramError(error.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<CliNonceError> for CliError {
|
impl From<CliNonceError> for CliError {
|
||||||
fn from(error: CliNonceError) -> Self {
|
fn from(error: CliNonceError) -> Self {
|
||||||
match error {
|
match error {
|
||||||
CliNonceError::Client(client_error) => {
|
CliNonceError::Client(client_error) => Self::RpcRequestError(client_error),
|
||||||
Self::RpcRequestError(format!("{:?}", client_error))
|
|
||||||
}
|
|
||||||
_ => Self::InvalidNonce(error),
|
_ => Self::InvalidNonce(error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,7 +709,7 @@ pub fn parse_command(
|
|||||||
.parse()
|
.parse()
|
||||||
.or_else(|err| {
|
.or_else(|err| {
|
||||||
Err(CliError::BadParameter(format!(
|
Err(CliError::BadParameter(format!(
|
||||||
"Invalid faucet port: {:?}",
|
"Invalid faucet port: {}",
|
||||||
err
|
err
|
||||||
)))
|
)))
|
||||||
})?;
|
})?;
|
||||||
@@ -725,7 +717,7 @@ pub fn parse_command(
|
|||||||
let faucet_host = if let Some(faucet_host) = matches.value_of("faucet_host") {
|
let faucet_host = if let Some(faucet_host) = matches.value_of("faucet_host") {
|
||||||
Some(solana_net_utils::parse_host(faucet_host).or_else(|err| {
|
Some(solana_net_utils::parse_host(faucet_host).or_else(|err| {
|
||||||
Err(CliError::BadParameter(format!(
|
Err(CliError::BadParameter(format!(
|
||||||
"Invalid faucet host: {:?}",
|
"Invalid faucet host: {}",
|
||||||
err
|
err
|
||||||
)))
|
)))
|
||||||
})?)
|
})?)
|
||||||
@@ -1137,13 +1129,13 @@ fn process_confirm(rpc_client: &RpcClient, signature: &Signature) -> ProcessResu
|
|||||||
if let Some(result) = status {
|
if let Some(result) = status {
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => Ok("Confirmed".to_string()),
|
Ok(_) => Ok("Confirmed".to_string()),
|
||||||
Err(err) => Ok(format!("Transaction failed with error {:?}", err)),
|
Err(err) => Ok(format!("Transaction failed with error: {}", err)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok("Not found".to_string())
|
Ok("Not found".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Err(CliError::RpcRequestError(format!("Unable to confirm: {:?}", err)).into()),
|
Err(err) => Err(CliError::RpcRequestError(format!("Unable to confirm: {}", err)).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1203,7 +1195,7 @@ fn process_deploy(
|
|||||||
program_data.len() as u64,
|
program_data.len() as u64,
|
||||||
&bpf_loader::id(),
|
&bpf_loader::id(),
|
||||||
);
|
);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let mut create_account_tx = Transaction::new_unsigned(message);
|
let mut create_account_tx = Transaction::new_unsigned(message);
|
||||||
create_account_tx.try_sign(&[config.signers[0], &program_id], blockhash)?;
|
create_account_tx.try_sign(&[config.signers[0], &program_id], blockhash)?;
|
||||||
messages.push(&create_account_tx.message);
|
messages.push(&create_account_tx.message);
|
||||||
@@ -1216,7 +1208,7 @@ fn process_deploy(
|
|||||||
(i * DATA_CHUNK_SIZE) as u32,
|
(i * DATA_CHUNK_SIZE) as u32,
|
||||||
chunk.to_vec(),
|
chunk.to_vec(),
|
||||||
);
|
);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&signers[0].pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&signers, blockhash)?;
|
tx.try_sign(&signers, blockhash)?;
|
||||||
write_transactions.push(tx);
|
write_transactions.push(tx);
|
||||||
@@ -1226,7 +1218,7 @@ fn process_deploy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let instruction = loader_instruction::finalize(&program_id.pubkey(), &bpf_loader::id());
|
let instruction = loader_instruction::finalize(&program_id.pubkey(), &bpf_loader::id());
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&signers[0].pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&signers[0].pubkey()));
|
||||||
let mut finalize_tx = Transaction::new_unsigned(message);
|
let mut finalize_tx = Transaction::new_unsigned(message);
|
||||||
finalize_tx.try_sign(&signers, blockhash)?;
|
finalize_tx.try_sign(&signers, blockhash)?;
|
||||||
messages.push(&finalize_tx.message);
|
messages.push(&finalize_tx.message);
|
||||||
@@ -1294,7 +1286,7 @@ fn process_pay(
|
|||||||
let message = if let Some(nonce_account) = &nonce_account {
|
let message = if let Some(nonce_account) = &nonce_account {
|
||||||
Message::new_with_nonce(vec![ix], None, nonce_account, &nonce_authority.pubkey())
|
Message::new_with_nonce(vec![ix], None, nonce_account, &nonce_authority.pubkey())
|
||||||
} else {
|
} else {
|
||||||
Message::new(vec![ix])
|
Message::new(&[ix])
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, blockhash)?;
|
tx.try_sign(&config.signers, blockhash)?;
|
||||||
@@ -1334,7 +1326,7 @@ fn process_pay(
|
|||||||
cancelable,
|
cancelable,
|
||||||
lamports,
|
lamports,
|
||||||
);
|
);
|
||||||
let message = Message::new(ixs);
|
let message = Message::new(&ixs);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&[config.signers[0], &contract_state], blockhash)?;
|
tx.try_sign(&[config.signers[0], &contract_state], blockhash)?;
|
||||||
if sign_only {
|
if sign_only {
|
||||||
@@ -1377,7 +1369,7 @@ fn process_pay(
|
|||||||
cancelable,
|
cancelable,
|
||||||
lamports,
|
lamports,
|
||||||
);
|
);
|
||||||
let message = Message::new(ixs);
|
let message = Message::new(&ixs);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&[config.signers[0], &contract_state], blockhash)?;
|
tx.try_sign(&[config.signers[0], &contract_state], blockhash)?;
|
||||||
if sign_only {
|
if sign_only {
|
||||||
@@ -1411,7 +1403,7 @@ fn process_cancel(rpc_client: &RpcClient, config: &CliConfig, pubkey: &Pubkey) -
|
|||||||
pubkey,
|
pubkey,
|
||||||
&config.signers[0].pubkey(),
|
&config.signers[0].pubkey(),
|
||||||
);
|
);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, blockhash)?;
|
tx.try_sign(&config.signers, blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -1434,7 +1426,7 @@ fn process_time_elapsed(
|
|||||||
let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
|
|
||||||
let ix = budget_instruction::apply_timestamp(&config.signers[0].pubkey(), pubkey, to, dt);
|
let ix = budget_instruction::apply_timestamp(&config.signers[0].pubkey(), pubkey, to, dt);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, blockhash)?;
|
tx.try_sign(&config.signers, blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -1482,7 +1474,7 @@ fn process_transfer(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -1514,7 +1506,7 @@ fn process_witness(
|
|||||||
let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
|
|
||||||
let ix = budget_instruction::apply_signature(&config.signers[0].pubkey(), pubkey, to);
|
let ix = budget_instruction::apply_signature(&config.signers[0].pubkey(), pubkey, to);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, blockhash)?;
|
tx.try_sign(&config.signers, blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -2111,18 +2103,18 @@ pub fn request_and_confirm_airdrop(
|
|||||||
log_instruction_custom_error::<SystemError>(result)
|
log_instruction_custom_error::<SystemError>(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_instruction_custom_error<E>(result: Result<String, ClientError>) -> ProcessResult
|
pub fn log_instruction_custom_error<E>(result: ClientResult<String>) -> ProcessResult
|
||||||
where
|
where
|
||||||
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
E: 'static + std::error::Error + DecodeError<E> + FromPrimitive,
|
||||||
{
|
{
|
||||||
match result {
|
match result {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if let ClientError::TransactionError(TransactionError::InstructionError(
|
if let ClientErrorKind::TransactionError(TransactionError::InstructionError(
|
||||||
_,
|
_,
|
||||||
InstructionError::CustomError(code),
|
InstructionError::CustomError(code),
|
||||||
)) = err
|
)) = err.kind()
|
||||||
{
|
{
|
||||||
if let Some(specific_error) = E::decode_custom_error_to_enum(code) {
|
if let Some(specific_error) = E::decode_custom_error_to_enum(*code) {
|
||||||
error!("{}::{:?}", E::type_of(), specific_error);
|
error!("{}::{:?}", E::type_of(), specific_error);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Program Error ({}::{:?}): {}",
|
"Program Error ({}::{:?}): {}",
|
||||||
@@ -3325,7 +3317,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
process_command(&config).unwrap(),
|
process_command(&config).unwrap(),
|
||||||
format!(
|
format!(
|
||||||
"Transaction failed with error {:?}",
|
"Transaction failed with error: {}",
|
||||||
TransactionError::AccountInUse
|
TransactionError::AccountInUse
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@@ -789,7 +789,7 @@ pub fn process_ping(
|
|||||||
last_blockhash = recent_blockhash;
|
last_blockhash = recent_blockhash;
|
||||||
|
|
||||||
let ix = system_instruction::transfer(&config.signers[0].pubkey(), &to, lamports);
|
let ix = system_instruction::transfer(&config.signers[0].pubkey(), &to, lamports);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let mut transaction = Transaction::new_unsigned(message);
|
let mut transaction = Transaction::new_unsigned(message);
|
||||||
transaction.try_sign(&config.signers, recent_blockhash)?;
|
transaction.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -972,7 +972,7 @@ pub fn process_live_slots(url: &str) -> ProcessResult {
|
|||||||
current = Some(new_info);
|
current = Some(new_info);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("disconnected: {:?}", err);
|
eprintln!("disconnected: {}", err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
use clap::{crate_description, crate_name, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand};
|
use clap::{crate_description, crate_name, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand};
|
||||||
use console::style;
|
use console::style;
|
||||||
|
|
||||||
use solana_clap_utils::{input_validators::is_url, keypair::SKIP_SEED_PHRASE_VALIDATION_ARG};
|
use solana_clap_utils::{
|
||||||
|
input_validators::is_url, keypair::SKIP_SEED_PHRASE_VALIDATION_ARG, DisplayError,
|
||||||
|
};
|
||||||
use solana_cli::{
|
use solana_cli::{
|
||||||
cli::{app, parse_command, process_command, CliCommandInfo, CliConfig, CliSigners},
|
cli::{app, parse_command, process_command, CliCommandInfo, CliConfig, CliSigners},
|
||||||
display::{println_name_value, println_name_value_or},
|
display::{println_name_value, println_name_value_or},
|
||||||
@@ -230,6 +232,10 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
|
do_main(&matches).map_err(|err| DisplayError::new_as_boxed(err).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_main(matches: &ArgMatches<'_>) -> Result<(), Box<dyn error::Error>> {
|
||||||
if parse_settings(&matches)? {
|
if parse_settings(&matches)? {
|
||||||
let wallet_manager = maybe_wallet_manager()?;
|
let wallet_manager = maybe_wallet_manager()?;
|
||||||
|
|
||||||
@@ -237,6 +243,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||||||
config.signers = signers.iter().map(|s| s.as_ref()).collect();
|
config.signers = signers.iter().map(|s| s.as_ref()).collect();
|
||||||
let result = process_command(&config)?;
|
let result = process_command(&config)?;
|
||||||
println!("{}", result);
|
println!("{}", result);
|
||||||
}
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@@ -238,7 +238,7 @@ pub fn get_account(
|
|||||||
) -> Result<Account, CliNonceError> {
|
) -> Result<Account, CliNonceError> {
|
||||||
rpc_client
|
rpc_client
|
||||||
.get_account(nonce_pubkey)
|
.get_account(nonce_pubkey)
|
||||||
.map_err(|e| CliNonceError::Client(format!("{:?}", e)))
|
.map_err(|e| CliNonceError::Client(format!("{}", e)))
|
||||||
.and_then(|a| match account_identity_ok(&a) {
|
.and_then(|a| match account_identity_ok(&a) {
|
||||||
Ok(()) => Ok(a),
|
Ok(()) => Ok(a),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
@@ -441,7 +441,7 @@ pub fn process_authorize_nonce_account(
|
|||||||
|
|
||||||
let nonce_authority = config.signers[nonce_authority];
|
let nonce_authority = config.signers[nonce_authority];
|
||||||
let ix = authorize_nonce_account(nonce_account, &nonce_authority.pubkey(), new_authority);
|
let ix = authorize_nonce_account(nonce_account, &nonce_authority.pubkey(), new_authority);
|
||||||
let message = Message::new_with_payer(vec![ix], Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&[ix], Some(&config.signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
|
|
||||||
@@ -518,7 +518,7 @@ pub fn process_create_nonce_account(
|
|||||||
|
|
||||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
|
|
||||||
let message = Message::new_with_payer(ixs, Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&ixs, Some(&config.signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
|
|
||||||
@@ -560,7 +560,7 @@ pub fn process_new_nonce(
|
|||||||
let nonce_authority = config.signers[nonce_authority];
|
let nonce_authority = config.signers[nonce_authority];
|
||||||
let ix = advance_nonce_account(&nonce_account, &nonce_authority.pubkey());
|
let ix = advance_nonce_account(&nonce_account, &nonce_authority.pubkey());
|
||||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
let message = Message::new_with_payer(vec![ix], Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&[ix], Some(&config.signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -633,7 +633,7 @@ pub fn process_withdraw_from_nonce_account(
|
|||||||
destination_account_pubkey,
|
destination_account_pubkey,
|
||||||
lamports,
|
lamports,
|
||||||
);
|
);
|
||||||
let message = Message::new_with_payer(vec![ix], Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&[ix], Some(&config.signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
|
@@ -827,7 +827,7 @@ pub fn process_create_stake_account(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -889,7 +889,7 @@ pub fn process_stake_authorize(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -942,7 +942,7 @@ pub fn process_deactivate_stake_account(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -1001,7 +1001,7 @@ pub fn process_withdraw_stake(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -1134,7 +1134,7 @@ pub fn process_split_stake(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -1190,7 +1190,7 @@ pub fn process_stake_set_lockup(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
@@ -1300,7 +1300,7 @@ pub fn process_show_stake_account(
|
|||||||
Ok("".to_string())
|
Ok("".to_string())
|
||||||
}
|
}
|
||||||
Err(err) => Err(CliError::RpcRequestError(format!(
|
Err(err) => Err(CliError::RpcRequestError(format!(
|
||||||
"Account data could not be deserialized to stake state: {:?}",
|
"Account data could not be deserialized to stake state: {}",
|
||||||
err
|
err
|
||||||
))
|
))
|
||||||
.into()),
|
.into()),
|
||||||
@@ -1396,11 +1396,11 @@ pub fn process_delegate_stake(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if sanity_check_result.is_err() {
|
if let Err(err) = &sanity_check_result {
|
||||||
if !force {
|
if !force {
|
||||||
sanity_check_result?;
|
sanity_check_result?;
|
||||||
} else {
|
} else {
|
||||||
println!("--force supplied, ignoring: {:?}", sanity_check_result);
|
println!("--force supplied, ignoring: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1424,7 +1424,7 @@ pub fn process_delegate_stake(
|
|||||||
&nonce_authority.pubkey(),
|
&nonce_authority.pubkey(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Message::new_with_payer(ixs, Some(&fee_payer.pubkey()))
|
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
|
||||||
};
|
};
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
|
@@ -212,7 +212,7 @@ pub fn process_create_storage_account(
|
|||||||
);
|
);
|
||||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
|
|
||||||
let message = Message::new(ixs);
|
let message = Message::new(&ixs);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -236,7 +236,7 @@ pub fn process_claim_storage_reward(
|
|||||||
let instruction =
|
let instruction =
|
||||||
storage_instruction::claim_reward(node_account_pubkey, storage_account_pubkey);
|
storage_instruction::claim_reward(node_account_pubkey, storage_account_pubkey);
|
||||||
let signers = [config.signers[0]];
|
let signers = [config.signers[0]];
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&signers[0].pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&signers, recent_blockhash)?;
|
tx.try_sign(&signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -266,7 +266,7 @@ pub fn process_show_storage_account(
|
|||||||
|
|
||||||
use solana_storage_program::storage_contract::StorageContract;
|
use solana_storage_program::storage_contract::StorageContract;
|
||||||
let storage_contract: StorageContract = account.state().map_err(|err| {
|
let storage_contract: StorageContract = account.state().map_err(|err| {
|
||||||
CliError::RpcRequestError(format!("Unable to deserialize storage account: {:?}", err))
|
CliError::RpcRequestError(format!("Unable to deserialize storage account: {}", err))
|
||||||
})?;
|
})?;
|
||||||
println!("{:#?}", storage_contract);
|
println!("{:#?}", storage_contract);
|
||||||
println!("Account Lamports: {}", account.lamports);
|
println!("Account Lamports: {}", account.lamports);
|
||||||
|
@@ -274,7 +274,7 @@ pub fn process_set_validator_info(
|
|||||||
println!("--force supplied, ignoring: {:?}", result);
|
println!("--force supplied, ignoring: {:?}", result);
|
||||||
} else {
|
} else {
|
||||||
result.map_err(|err| {
|
result.map_err(|err| {
|
||||||
CliError::BadParameter(format!("Invalid validator keybase username: {:?}", err))
|
CliError::BadParameter(format!("Invalid validator keybase username: {}", err))
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,7 +339,7 @@ pub fn process_set_validator_info(
|
|||||||
&validator_info,
|
&validator_info,
|
||||||
)]);
|
)]);
|
||||||
let signers = vec![config.signers[0], &info_keypair];
|
let signers = vec![config.signers[0], &info_keypair];
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
(message, signers)
|
(message, signers)
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
@@ -353,7 +353,7 @@ pub fn process_set_validator_info(
|
|||||||
keys,
|
keys,
|
||||||
&validator_info,
|
&validator_info,
|
||||||
)];
|
)];
|
||||||
let message = Message::new_with_payer(instructions, Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&instructions, Some(&config.signers[0].pubkey()));
|
||||||
let signers = vec![config.signers[0]];
|
let signers = vec![config.signers[0]];
|
||||||
(message, signers)
|
(message, signers)
|
||||||
};
|
};
|
||||||
|
@@ -359,7 +359,7 @@ pub fn process_create_vote_account(
|
|||||||
};
|
};
|
||||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
|
|
||||||
let message = Message::new(ixs);
|
let message = Message::new(&ixs);
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -391,7 +391,7 @@ pub fn process_vote_authorize(
|
|||||||
vote_authorize, // vote or withdraw
|
vote_authorize, // vote or withdraw
|
||||||
)];
|
)];
|
||||||
|
|
||||||
let message = Message::new_with_payer(ixs, Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&ixs, Some(&config.signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
@@ -422,7 +422,7 @@ pub fn process_vote_update_validator(
|
|||||||
new_identity_pubkey,
|
new_identity_pubkey,
|
||||||
)];
|
)];
|
||||||
|
|
||||||
let message = Message::new_with_payer(ixs, Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&ixs, Some(&config.signers[0].pubkey()));
|
||||||
let mut tx = Transaction::new_unsigned(message);
|
let mut tx = Transaction::new_unsigned(message);
|
||||||
tx.try_sign(&config.signers, recent_blockhash)?;
|
tx.try_sign(&config.signers, recent_blockhash)?;
|
||||||
check_account_for_fee(
|
check_account_for_fee(
|
||||||
|
@@ -1,20 +1,161 @@
|
|||||||
use crate::rpc_request;
|
use crate::rpc_request;
|
||||||
use solana_sdk::{signature::SignerError, transaction::TransactionError};
|
use solana_sdk::{
|
||||||
use std::{fmt, io};
|
signature::SignerError, transaction::TransactionError, transport::TransportError,
|
||||||
|
};
|
||||||
|
use std::io;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ClientError {
|
pub enum ClientErrorKind {
|
||||||
|
#[error(transparent)]
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
|
#[error(transparent)]
|
||||||
Reqwest(#[from] reqwest::Error),
|
Reqwest(#[from] reqwest::Error),
|
||||||
|
#[error(transparent)]
|
||||||
RpcError(#[from] rpc_request::RpcError),
|
RpcError(#[from] rpc_request::RpcError),
|
||||||
|
#[error(transparent)]
|
||||||
SerdeJson(#[from] serde_json::error::Error),
|
SerdeJson(#[from] serde_json::error::Error),
|
||||||
|
#[error(transparent)]
|
||||||
SigningError(#[from] SignerError),
|
SigningError(#[from] SignerError),
|
||||||
|
#[error(transparent)]
|
||||||
TransactionError(#[from] TransactionError),
|
TransactionError(#[from] TransactionError),
|
||||||
|
#[error("Custom: {0}")]
|
||||||
|
Custom(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ClientError {
|
impl From<TransportError> for ClientErrorKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn from(err: TransportError) -> Self {
|
||||||
write!(f, "solana client error")
|
match err {
|
||||||
|
TransportError::IoError(err) => Self::Io(err),
|
||||||
|
TransportError::TransactionError(err) => Self::TransactionError(err),
|
||||||
|
TransportError::Custom(err) => Self::Custom(err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<TransportError> for ClientErrorKind {
|
||||||
|
fn into(self) -> TransportError {
|
||||||
|
match self {
|
||||||
|
Self::Io(err) => TransportError::IoError(err),
|
||||||
|
Self::TransactionError(err) => TransportError::TransactionError(err),
|
||||||
|
Self::Reqwest(err) => TransportError::Custom(format!("{:?}", err)),
|
||||||
|
Self::RpcError(err) => TransportError::Custom(format!("{:?}", err)),
|
||||||
|
Self::SerdeJson(err) => TransportError::Custom(format!("{:?}", err)),
|
||||||
|
Self::SigningError(err) => TransportError::Custom(format!("{:?}", err)),
|
||||||
|
Self::Custom(err) => TransportError::Custom(format!("{:?}", err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
#[error("{kind}")]
|
||||||
|
pub struct ClientError {
|
||||||
|
command: Option<&'static str>,
|
||||||
|
#[source]
|
||||||
|
#[error(transparent)]
|
||||||
|
kind: ClientErrorKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientError {
|
||||||
|
pub fn new_with_command(kind: ClientErrorKind, command: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
command: Some(command),
|
||||||
|
kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_with_command(self, command: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
command: Some(command),
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn command(&self) -> Option<&'static str> {
|
||||||
|
self.command
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(&self) -> &ClientErrorKind {
|
||||||
|
&self.kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ClientErrorKind> for ClientError {
|
||||||
|
fn from(kind: ClientErrorKind) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TransportError> for ClientError {
|
||||||
|
fn from(err: TransportError) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<TransportError> for ClientError {
|
||||||
|
fn into(self) -> TransportError {
|
||||||
|
self.kind.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for ClientError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<reqwest::Error> for ClientError {
|
||||||
|
fn from(err: reqwest::Error) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<rpc_request::RpcError> for ClientError {
|
||||||
|
fn from(err: rpc_request::RpcError) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<serde_json::error::Error> for ClientError {
|
||||||
|
fn from(err: serde_json::error::Error) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SignerError> for ClientError {
|
||||||
|
fn from(err: SignerError) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TransactionError> for ClientError {
|
||||||
|
fn from(err: TransactionError) -> Self {
|
||||||
|
Self {
|
||||||
|
command: None,
|
||||||
|
kind: err.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, ClientError>;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use crate::{client_error::ClientError, rpc_request::RpcRequest};
|
use crate::{client_error::Result, rpc_request::RpcRequest};
|
||||||
|
|
||||||
pub(crate) trait GenericRpcClientRequest {
|
pub(crate) trait GenericRpcClientRequest {
|
||||||
fn send(
|
fn send(
|
||||||
@@ -6,5 +6,5 @@ pub(crate) trait GenericRpcClientRequest {
|
|||||||
request: &RpcRequest,
|
request: &RpcRequest,
|
||||||
params: serde_json::Value,
|
params: serde_json::Value,
|
||||||
retries: usize,
|
retries: usize,
|
||||||
) -> Result<serde_json::Value, ClientError>;
|
) -> Result<serde_json::Value>;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
client_error::ClientError,
|
client_error::Result,
|
||||||
generic_rpc_client_request::GenericRpcClientRequest,
|
generic_rpc_client_request::GenericRpcClientRequest,
|
||||||
rpc_request::RpcRequest,
|
rpc_request::RpcRequest,
|
||||||
rpc_response::{Response, RpcResponseContext},
|
rpc_response::{Response, RpcResponseContext},
|
||||||
@@ -41,7 +41,7 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
|
|||||||
request: &RpcRequest,
|
request: &RpcRequest,
|
||||||
params: serde_json::Value,
|
params: serde_json::Value,
|
||||||
_retries: usize,
|
_retries: usize,
|
||||||
) -> Result<serde_json::Value, ClientError> {
|
) -> Result<serde_json::Value> {
|
||||||
if let Some(value) = self.mocks.write().unwrap().remove(request) {
|
if let Some(value) = self.mocks.write().unwrap().remove(request) {
|
||||||
return Ok(value);
|
return Ok(value);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
client_error::ClientError,
|
client_error::Result,
|
||||||
generic_rpc_client_request::GenericRpcClientRequest,
|
generic_rpc_client_request::GenericRpcClientRequest,
|
||||||
rpc_request::{RpcError, RpcRequest},
|
rpc_request::{RpcError, RpcRequest},
|
||||||
};
|
};
|
||||||
@@ -34,7 +34,7 @@ impl GenericRpcClientRequest for RpcClientRequest {
|
|||||||
request: &RpcRequest,
|
request: &RpcRequest,
|
||||||
params: serde_json::Value,
|
params: serde_json::Value,
|
||||||
mut retries: usize,
|
mut retries: usize,
|
||||||
) -> Result<serde_json::Value, ClientError> {
|
) -> Result<serde_json::Value> {
|
||||||
// Concurrent requests are not supported so reuse the same request id for all requests
|
// Concurrent requests are not supported so reuse the same request id for all requests
|
||||||
let request_id = 1;
|
let request_id = 1;
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::{error, fmt};
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum RpcRequest {
|
pub enum RpcRequest {
|
||||||
@@ -93,26 +93,16 @@ impl RpcRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Error)]
|
||||||
pub enum RpcError {
|
pub enum RpcError {
|
||||||
|
#[error("rpc reques error: {0}")]
|
||||||
RpcRequestError(String),
|
RpcRequestError(String),
|
||||||
}
|
#[error("parse error: expected {0}")]
|
||||||
|
ParseError(String), /* "expected" */
|
||||||
impl fmt::Display for RpcError {
|
// Anything in a `ForUser` needs to die. The caller should be
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
// deciding what to tell their user
|
||||||
write!(f, "invalid")
|
#[error("{0}")]
|
||||||
}
|
ForUser(String), /* "direct-to-user message" */
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for RpcError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
"invalid"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
// Generic error, underlying cause isn't tracked.
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
use crate::rpc_request::RpcError;
|
use crate::{client_error, rpc_request::RpcError};
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use jsonrpc_core::Result as JsonResult;
|
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
clock::{Epoch, Slot},
|
clock::{Epoch, Slot},
|
||||||
@@ -9,10 +8,9 @@ use solana_sdk::{
|
|||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
transaction::{Result, Transaction},
|
transaction::{Result, Transaction},
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, io, net::SocketAddr, str::FromStr};
|
use std::{collections::HashMap, net::SocketAddr, str::FromStr};
|
||||||
|
|
||||||
pub type RpcResponseIn<T> = JsonResult<Response<T>>;
|
pub type RpcResult<T> = client_error::Result<Response<T>>;
|
||||||
pub type RpcResponse<T> = io::Result<Response<T>>;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct RpcResponseContext {
|
pub struct RpcResponseContext {
|
||||||
|
@@ -188,7 +188,7 @@ impl ThinClient {
|
|||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
tries: usize,
|
tries: usize,
|
||||||
min_confirmed_blocks: usize,
|
min_confirmed_blocks: usize,
|
||||||
) -> io::Result<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
self.send_and_confirm_transaction(&[keypair], transaction, tries, min_confirmed_blocks)
|
self.send_and_confirm_transaction(&[keypair], transaction, tries, min_confirmed_blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ impl ThinClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
tries: usize,
|
tries: usize,
|
||||||
) -> io::Result<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
self.send_and_confirm_transaction(&[keypair], transaction, tries, 0)
|
self.send_and_confirm_transaction(&[keypair], transaction, tries, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ impl ThinClient {
|
|||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
tries: usize,
|
tries: usize,
|
||||||
pending_confirmations: usize,
|
pending_confirmations: usize,
|
||||||
) -> io::Result<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
for x in 0..tries {
|
for x in 0..tries {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
||||||
@@ -243,13 +243,14 @@ impl ThinClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("{} tries failed transfer to {}", x, self.tpu_addr());
|
info!("{} tries failed transfer to {}", x, self.tpu_addr());
|
||||||
let (blockhash, _fee_calculator) = self.rpc_client().get_recent_blockhash()?;
|
let (blockhash, _fee_calculator) = self.get_recent_blockhash()?;
|
||||||
transaction.sign(keypairs, blockhash);
|
transaction.sign(keypairs, blockhash);
|
||||||
}
|
}
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
format!("retry_transfer failed in {} retries", tries),
|
format!("retry_transfer failed in {} retries", tries),
|
||||||
))
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_balance_with_timeout_and_commitment(
|
pub fn poll_balance_with_timeout_and_commitment(
|
||||||
@@ -258,13 +259,15 @@ impl ThinClient {
|
|||||||
polling_frequency: &Duration,
|
polling_frequency: &Duration,
|
||||||
timeout: &Duration,
|
timeout: &Duration,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> io::Result<u64> {
|
) -> TransportResult<u64> {
|
||||||
self.rpc_client().poll_balance_with_timeout_and_commitment(
|
self.rpc_client()
|
||||||
pubkey,
|
.poll_balance_with_timeout_and_commitment(
|
||||||
polling_frequency,
|
pubkey,
|
||||||
timeout,
|
polling_frequency,
|
||||||
commitment_config,
|
timeout,
|
||||||
)
|
commitment_config,
|
||||||
|
)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_balance_with_timeout(
|
pub fn poll_balance_with_timeout(
|
||||||
@@ -272,8 +275,8 @@ impl ThinClient {
|
|||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
polling_frequency: &Duration,
|
polling_frequency: &Duration,
|
||||||
timeout: &Duration,
|
timeout: &Duration,
|
||||||
) -> io::Result<u64> {
|
) -> TransportResult<u64> {
|
||||||
self.rpc_client().poll_balance_with_timeout_and_commitment(
|
self.poll_balance_with_timeout_and_commitment(
|
||||||
pubkey,
|
pubkey,
|
||||||
polling_frequency,
|
polling_frequency,
|
||||||
timeout,
|
timeout,
|
||||||
@@ -281,18 +284,18 @@ impl ThinClient {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_get_balance(&self, pubkey: &Pubkey) -> io::Result<u64> {
|
pub fn poll_get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64> {
|
||||||
self.rpc_client()
|
self.poll_get_balance_with_commitment(pubkey, CommitmentConfig::default())
|
||||||
.poll_get_balance_with_commitment(pubkey, CommitmentConfig::default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_get_balance_with_commitment(
|
pub fn poll_get_balance_with_commitment(
|
||||||
&self,
|
&self,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> io::Result<u64> {
|
) -> TransportResult<u64> {
|
||||||
self.rpc_client()
|
self.rpc_client()
|
||||||
.poll_get_balance_with_commitment(pubkey, commitment_config)
|
.poll_get_balance_with_commitment(pubkey, commitment_config)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_for_balance(&self, pubkey: &Pubkey, expected_balance: Option<u64>) -> Option<u64> {
|
pub fn wait_for_balance(&self, pubkey: &Pubkey, expected_balance: Option<u64>) -> Option<u64> {
|
||||||
@@ -321,9 +324,9 @@ impl ThinClient {
|
|||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> TransportResult<()> {
|
) -> TransportResult<()> {
|
||||||
Ok(self
|
self.rpc_client()
|
||||||
.rpc_client()
|
.poll_for_signature_with_commitment(signature, commitment_config)
|
||||||
.poll_for_signature_with_commitment(signature, commitment_config)?)
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a signature in the bank. This method blocks
|
/// Check a signature in the bank. This method blocks
|
||||||
@@ -332,16 +335,17 @@ impl ThinClient {
|
|||||||
self.rpc_client().check_signature(signature)
|
self.rpc_client().check_signature(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validator_exit(&self) -> io::Result<bool> {
|
pub fn validator_exit(&self) -> TransportResult<bool> {
|
||||||
self.rpc_client().validator_exit()
|
self.rpc_client().validator_exit().map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_num_blocks_since_signature_confirmation(
|
pub fn get_num_blocks_since_signature_confirmation(
|
||||||
&mut self,
|
&mut self,
|
||||||
sig: &Signature,
|
sig: &Signature,
|
||||||
) -> io::Result<usize> {
|
) -> TransportResult<usize> {
|
||||||
self.rpc_client()
|
self.rpc_client()
|
||||||
.get_num_blocks_since_signature_confirmation(sig)
|
.get_num_blocks_since_signature_confirmation(sig)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +372,7 @@ impl SyncClient for ThinClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
) -> TransportResult<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
let message = Message::new(vec![instruction]);
|
let message = Message::new(&[instruction]);
|
||||||
self.send_message(&[keypair], message)
|
self.send_message(&[keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,14 +404,14 @@ impl SyncClient for ThinClient {
|
|||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> TransportResult<Option<Account>> {
|
) -> TransportResult<Option<Account>> {
|
||||||
Ok(self
|
self.rpc_client()
|
||||||
.rpc_client()
|
.get_account_with_commitment(pubkey, commitment_config)
|
||||||
.get_account_with_commitment(pubkey, commitment_config)?
|
.map_err(|e| e.into())
|
||||||
.value)
|
.map(|r| r.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64> {
|
fn get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64> {
|
||||||
Ok(self.rpc_client().get_balance(pubkey)?)
|
self.rpc_client().get_balance(pubkey).map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_balance_with_commitment(
|
fn get_balance_with_commitment(
|
||||||
@@ -415,10 +419,10 @@ impl SyncClient for ThinClient {
|
|||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
) -> TransportResult<u64> {
|
) -> TransportResult<u64> {
|
||||||
let balance = self
|
self.rpc_client()
|
||||||
.rpc_client()
|
.get_balance_with_commitment(pubkey, commitment_config)
|
||||||
.get_balance_with_commitment(pubkey, commitment_config)?;
|
.map_err(|e| e.into())
|
||||||
Ok(balance.value)
|
.map(|r| r.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_recent_blockhash(&self) -> TransportResult<(Hash, FeeCalculator)> {
|
fn get_recent_blockhash(&self) -> TransportResult<(Hash, FeeCalculator)> {
|
||||||
@@ -449,15 +453,16 @@ impl SyncClient for ThinClient {
|
|||||||
&self,
|
&self,
|
||||||
blockhash: &Hash,
|
blockhash: &Hash,
|
||||||
) -> TransportResult<Option<FeeCalculator>> {
|
) -> TransportResult<Option<FeeCalculator>> {
|
||||||
let fee_calculator = self
|
self.rpc_client()
|
||||||
.rpc_client()
|
.get_fee_calculator_for_blockhash(blockhash)
|
||||||
.get_fee_calculator_for_blockhash(blockhash)?;
|
.map_err(|e| e.into())
|
||||||
Ok(fee_calculator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fee_rate_governor(&self) -> TransportResult<FeeRateGovernor> {
|
fn get_fee_rate_governor(&self) -> TransportResult<FeeRateGovernor> {
|
||||||
let fee_rate_governor = self.rpc_client().get_fee_rate_governor()?;
|
self.rpc_client()
|
||||||
Ok(fee_rate_governor.value)
|
.get_fee_rate_governor()
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
.map(|r| r.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_signature_status(
|
fn get_signature_status(
|
||||||
@@ -555,23 +560,26 @@ impl SyncClient for ThinClient {
|
|||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
min_confirmed_blocks: usize,
|
min_confirmed_blocks: usize,
|
||||||
) -> TransportResult<usize> {
|
) -> TransportResult<usize> {
|
||||||
Ok(self
|
self.rpc_client()
|
||||||
.rpc_client()
|
.poll_for_signature_confirmation(signature, min_confirmed_blocks)
|
||||||
.poll_for_signature_confirmation(signature, min_confirmed_blocks)?)
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_for_signature(&self, signature: &Signature) -> TransportResult<()> {
|
fn poll_for_signature(&self, signature: &Signature) -> TransportResult<()> {
|
||||||
Ok(self.rpc_client().poll_for_signature(signature)?)
|
self.rpc_client()
|
||||||
|
.poll_for_signature(signature)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_new_blockhash(&self, blockhash: &Hash) -> TransportResult<(Hash, FeeCalculator)> {
|
fn get_new_blockhash(&self, blockhash: &Hash) -> TransportResult<(Hash, FeeCalculator)> {
|
||||||
let new_blockhash = self.rpc_client().get_new_blockhash(blockhash)?;
|
self.rpc_client()
|
||||||
Ok(new_blockhash)
|
.get_new_blockhash(blockhash)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncClient for ThinClient {
|
impl AsyncClient for ThinClient {
|
||||||
fn async_send_transaction(&self, transaction: Transaction) -> io::Result<Signature> {
|
fn async_send_transaction(&self, transaction: Transaction) -> TransportResult<Signature> {
|
||||||
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
||||||
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
||||||
serialize_into(&mut wr, &transaction)
|
serialize_into(&mut wr, &transaction)
|
||||||
@@ -586,7 +594,7 @@ impl AsyncClient for ThinClient {
|
|||||||
keypairs: &T,
|
keypairs: &T,
|
||||||
message: Message,
|
message: Message,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
let transaction = Transaction::new(keypairs, message, recent_blockhash);
|
let transaction = Transaction::new(keypairs, message, recent_blockhash);
|
||||||
self.async_send_transaction(transaction)
|
self.async_send_transaction(transaction)
|
||||||
}
|
}
|
||||||
@@ -595,8 +603,8 @@ impl AsyncClient for ThinClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
let message = Message::new(vec![instruction]);
|
let message = Message::new(&[instruction]);
|
||||||
self.async_send_message(&[keypair], message, recent_blockhash)
|
self.async_send_message(&[keypair], message, recent_blockhash)
|
||||||
}
|
}
|
||||||
fn async_transfer(
|
fn async_transfer(
|
||||||
@@ -605,7 +613,7 @@ impl AsyncClient for ThinClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature> {
|
) -> TransportResult<Signature> {
|
||||||
let transfer_instruction =
|
let transfer_instruction =
|
||||||
system_instruction::transfer(&keypair.pubkey(), pubkey, lamports);
|
system_instruction::transfer(&keypair.pubkey(), pubkey, lamports);
|
||||||
self.async_send_instruction(keypair, transfer_instruction, recent_blockhash)
|
self.async_send_instruction(keypair, transfer_instruction, recent_blockhash)
|
||||||
|
@@ -312,7 +312,7 @@ impl StorageStage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let signer_keys = vec![keypair.as_ref(), storage_keypair.as_ref()];
|
let signer_keys = vec![keypair.as_ref(), storage_keypair.as_ref()];
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&signer_keys[0].pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&signer_keys[0].pubkey()));
|
||||||
let transaction = Transaction::new(&signer_keys, message, blockhash);
|
let transaction = Transaction::new(&signer_keys, message, blockhash);
|
||||||
// try sending the transaction upto 5 times
|
// try sending the transaction upto 5 times
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
|
@@ -120,7 +120,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let message = Message::new_with_payer(vec![mining_proof_ix], Some(&mint_keypair.pubkey()));
|
let message = Message::new_with_payer(&[mining_proof_ix], Some(&mint_keypair.pubkey()));
|
||||||
let mining_proof_tx = Transaction::new(
|
let mining_proof_tx = Transaction::new(
|
||||||
&[&mint_keypair, archiver_keypair.as_ref()],
|
&[&mint_keypair, archiver_keypair.as_ref()],
|
||||||
message,
|
message,
|
||||||
|
@@ -127,7 +127,7 @@ impl Faucet {
|
|||||||
|
|
||||||
let create_instruction =
|
let create_instruction =
|
||||||
system_instruction::transfer(&self.mint_keypair.pubkey(), &to, lamports);
|
system_instruction::transfer(&self.mint_keypair.pubkey(), &to, lamports);
|
||||||
let message = Message::new(vec![create_instruction]);
|
let message = Message::new(&[create_instruction]);
|
||||||
Ok(Transaction::new(&[&self.mint_keypair], message, blockhash))
|
Ok(Transaction::new(&[&self.mint_keypair], message, blockhash))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(
|
Err(Error::new(
|
||||||
@@ -413,7 +413,7 @@ mod tests {
|
|||||||
|
|
||||||
let keypair = Keypair::new();
|
let keypair = Keypair::new();
|
||||||
let expected_instruction = system_instruction::transfer(&keypair.pubkey(), &to, lamports);
|
let expected_instruction = system_instruction::transfer(&keypair.pubkey(), &to, lamports);
|
||||||
let message = Message::new(vec![expected_instruction]);
|
let message = Message::new(&[expected_instruction]);
|
||||||
let expected_tx = Transaction::new(&[&keypair], message, blockhash);
|
let expected_tx = Transaction::new(&[&keypair], message, blockhash);
|
||||||
let expected_bytes = serialize(&expected_tx).unwrap();
|
let expected_bytes = serialize(&expected_tx).unwrap();
|
||||||
let mut expected_vec_with_length = vec![0; 2];
|
let mut expected_vec_with_length = vec![0; 2];
|
||||||
|
@@ -16,7 +16,7 @@ fn test_local_faucet() {
|
|||||||
let lamports = 50;
|
let lamports = 50;
|
||||||
let blockhash = Hash::new(&to.as_ref());
|
let blockhash = Hash::new(&to.as_ref());
|
||||||
let create_instruction = system_instruction::transfer(&keypair.pubkey(), &to, lamports);
|
let create_instruction = system_instruction::transfer(&keypair.pubkey(), &to, lamports);
|
||||||
let message = Message::new(vec![create_instruction]);
|
let message = Message::new(&[create_instruction]);
|
||||||
let expected_tx = Transaction::new(&[&keypair], message, blockhash);
|
let expected_tx = Transaction::new(&[&keypair], message, blockhash);
|
||||||
|
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
|
@@ -244,7 +244,7 @@ fn store_update_manifest(
|
|||||||
update_manifest,
|
update_manifest,
|
||||||
);
|
);
|
||||||
|
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&from_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&from_keypair.pubkey()));
|
||||||
let mut transaction = Transaction::new(&signers, message, recent_blockhash);
|
let mut transaction = Transaction::new(&signers, message, recent_blockhash);
|
||||||
rpc_client.send_and_confirm_transaction(&mut transaction, &[from_keypair])?;
|
rpc_client.send_and_confirm_transaction(&mut transaction, &[from_keypair])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@@ -11,6 +11,7 @@ use solana_clap_utils::{
|
|||||||
keypair_from_seed_phrase, prompt_passphrase, signer_from_path,
|
keypair_from_seed_phrase, prompt_passphrase, signer_from_path,
|
||||||
SKIP_SEED_PHRASE_VALIDATION_ARG,
|
SKIP_SEED_PHRASE_VALIDATION_ARG,
|
||||||
},
|
},
|
||||||
|
DisplayError,
|
||||||
};
|
};
|
||||||
use solana_cli_config::{Config, CONFIG_FILE};
|
use solana_cli_config::{Config, CONFIG_FILE};
|
||||||
use solana_remote_wallet::remote_wallet::{maybe_wallet_manager, RemoteWalletManager};
|
use solana_remote_wallet::remote_wallet::{maybe_wallet_manager, RemoteWalletManager};
|
||||||
@@ -378,6 +379,11 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||||||
|
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
|
do_main(&matches).map_err(|err| DisplayError::new_as_boxed(err).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_main(matches: &ArgMatches<'_>) -> Result<(), Box<dyn error::Error>> {
|
||||||
let config = if let Some(config_file) = matches.value_of("config_file") {
|
let config = if let Some(config_file) = matches.value_of("config_file") {
|
||||||
Config::load(config_file).unwrap_or_default()
|
Config::load(config_file).unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
@@ -566,7 +572,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||||||
}
|
}
|
||||||
("verify", Some(matches)) => {
|
("verify", Some(matches)) => {
|
||||||
let keypair = get_keypair_from_matches(matches, config, wallet_manager)?;
|
let keypair = get_keypair_from_matches(matches, config, wallet_manager)?;
|
||||||
let simple_message = Message::new(vec![Instruction::new(
|
let simple_message = Message::new(&[Instruction::new(
|
||||||
Pubkey::default(),
|
Pubkey::default(),
|
||||||
&0,
|
&0,
|
||||||
vec![AccountMeta::new(keypair.pubkey(), true)],
|
vec![AccountMeta::new(keypair.pubkey(), true)],
|
||||||
|
@@ -685,8 +685,7 @@ mod tests {
|
|||||||
fn test_verify_tick_hash_count() {
|
fn test_verify_tick_hash_count() {
|
||||||
let hashes_per_tick = 10;
|
let hashes_per_tick = 10;
|
||||||
let keypairs: Vec<&Keypair> = Vec::new();
|
let keypairs: Vec<&Keypair> = Vec::new();
|
||||||
let tx: Transaction =
|
let tx: Transaction = Transaction::new(&keypairs, Message::new(&[]), Hash::default());
|
||||||
Transaction::new(&keypairs, Message::new(Vec::new()), Hash::default());
|
|
||||||
let tx_entry = Entry::new(&Hash::default(), 1, vec![tx]);
|
let tx_entry = Entry::new(&Hash::default(), 1, vec![tx]);
|
||||||
let full_tick_entry = Entry::new_tick(hashes_per_tick, &Hash::default());
|
let full_tick_entry = Entry::new_tick(hashes_per_tick, &Hash::default());
|
||||||
let partial_tick_entry = Entry::new_tick(hashes_per_tick - 1, &Hash::default());
|
let partial_tick_entry = Entry::new_tick(hashes_per_tick - 1, &Hash::default());
|
||||||
|
@@ -262,7 +262,7 @@ pub fn kill_entry_and_spend_and_verify_rest(
|
|||||||
);
|
);
|
||||||
match sig {
|
match sig {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
result = Err(TransportError::IoError(e));
|
result = Err(e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@ use solana_sdk::{
|
|||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
system_transaction,
|
system_transaction,
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
|
transport::Result as TransportResult,
|
||||||
};
|
};
|
||||||
use solana_stake_program::{
|
use solana_stake_program::{
|
||||||
config as stake_config, stake_instruction,
|
config as stake_config, stake_instruction,
|
||||||
@@ -607,14 +608,14 @@ impl LocalCluster {
|
|||||||
storage_keypair: &Keypair,
|
storage_keypair: &Keypair,
|
||||||
from_keypair: &Arc<Keypair>,
|
from_keypair: &Arc<Keypair>,
|
||||||
archiver: bool,
|
archiver: bool,
|
||||||
) -> Result<()> {
|
) -> TransportResult<()> {
|
||||||
let storage_account_type = if archiver {
|
let storage_account_type = if archiver {
|
||||||
StorageAccountType::Archiver
|
StorageAccountType::Archiver
|
||||||
} else {
|
} else {
|
||||||
StorageAccountType::Validator
|
StorageAccountType::Validator
|
||||||
};
|
};
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
storage_instruction::create_storage_account(
|
&storage_instruction::create_storage_account(
|
||||||
&from_keypair.pubkey(),
|
&from_keypair.pubkey(),
|
||||||
&from_keypair.pubkey(),
|
&from_keypair.pubkey(),
|
||||||
&storage_keypair.pubkey(),
|
&storage_keypair.pubkey(),
|
||||||
|
@@ -256,7 +256,7 @@ mod tests {
|
|||||||
budget_instruction::payment(&alice_pubkey, &bob_pubkey, &budget_pubkey, 1);
|
budget_instruction::payment(&alice_pubkey, &bob_pubkey, &budget_pubkey, 1);
|
||||||
instructions[1].accounts = vec![]; // <!-- Attack! Prevent accounts from being passed into processor.
|
instructions[1].accounts = vec![]; // <!-- Attack! Prevent accounts from being passed into processor.
|
||||||
|
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
@@ -276,7 +276,7 @@ mod tests {
|
|||||||
let budget_pubkey = budget_keypair.pubkey();
|
let budget_pubkey = budget_keypair.pubkey();
|
||||||
let instructions =
|
let instructions =
|
||||||
budget_instruction::payment(&alice_pubkey, &bob_pubkey, &budget_pubkey, 100);
|
budget_instruction::payment(&alice_pubkey, &bob_pubkey, &budget_pubkey, 100);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -302,7 +302,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -315,7 +315,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let instruction =
|
let instruction =
|
||||||
budget_instruction::apply_signature(&mallory_pubkey, &budget_pubkey, &bob_pubkey);
|
budget_instruction::apply_signature(&mallory_pubkey, &budget_pubkey, &bob_pubkey);
|
||||||
let mut message = Message::new(vec![instruction]);
|
let mut message = Message::new(&[instruction]);
|
||||||
|
|
||||||
// Attack! Part 2: Point the instruction to the expected, but unsigned, key.
|
// Attack! Part 2: Point the instruction to the expected, but unsigned, key.
|
||||||
message.account_keys.insert(3, alice_pubkey);
|
message.account_keys.insert(3, alice_pubkey);
|
||||||
@@ -352,7 +352,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -365,7 +365,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let instruction =
|
let instruction =
|
||||||
budget_instruction::apply_timestamp(&mallory_pubkey, &budget_pubkey, &bob_pubkey, dt);
|
budget_instruction::apply_timestamp(&mallory_pubkey, &budget_pubkey, &bob_pubkey, dt);
|
||||||
let mut message = Message::new(vec![instruction]);
|
let mut message = Message::new(&[instruction]);
|
||||||
|
|
||||||
// Attack! Part 2: Point the instruction to the expected, but unsigned, key.
|
// Attack! Part 2: Point the instruction to the expected, but unsigned, key.
|
||||||
message.account_keys.insert(3, alice_pubkey);
|
message.account_keys.insert(3, alice_pubkey);
|
||||||
@@ -402,7 +402,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -472,7 +472,7 @@ mod tests {
|
|||||||
Some(alice_pubkey),
|
Some(alice_pubkey),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -550,7 +550,7 @@ mod tests {
|
|||||||
game_hash,
|
game_hash,
|
||||||
41,
|
41,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &budget_keypair], message)
|
.send_message(&[&alice_keypair, &budget_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -570,7 +570,7 @@ mod tests {
|
|||||||
|
|
||||||
// Anyone can sign the message, but presumably it's Bob, since he's the
|
// Anyone can sign the message, but presumably it's Bob, since he's the
|
||||||
// one claiming the payout.
|
// one claiming the payout.
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&bob_pubkey));
|
let message = Message::new_with_payer(&[instruction], Some(&bob_pubkey));
|
||||||
bank_client.send_message(&[&bob_keypair], message).unwrap();
|
bank_client.send_message(&[&bob_keypair], message).unwrap();
|
||||||
|
|
||||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 0);
|
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 0);
|
||||||
|
@@ -603,7 +603,7 @@ mod test {
|
|||||||
);
|
);
|
||||||
|
|
||||||
client
|
client
|
||||||
.send_message(&[owner, &new], Message::new(vec![instruction]))
|
.send_message(&[owner, &new], Message::new(&[instruction]))
|
||||||
.expect(&format!("{}:{}", line!(), file!()));
|
.expect(&format!("{}:{}", line!(), file!()));
|
||||||
new.pubkey()
|
new.pubkey()
|
||||||
}
|
}
|
||||||
|
@@ -32,11 +32,11 @@ pub fn create_genesis<T: Client>(from: &Keypair, client: &T, amount: u64) -> Key
|
|||||||
);
|
);
|
||||||
|
|
||||||
client
|
client
|
||||||
.send_message(&[&from, &genesis], Message::new(vec![instruction]))
|
.send_message(&[&from, &genesis], Message::new(&[instruction]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let instruction = librapay_instruction::genesis(&genesis.pubkey(), amount);
|
let instruction = librapay_instruction::genesis(&genesis.pubkey(), amount);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&from.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&from.pubkey()));
|
||||||
client.send_message(&[from, &genesis], message).unwrap();
|
client.send_message(&[from, &genesis], message).unwrap();
|
||||||
|
|
||||||
genesis
|
genesis
|
||||||
|
@@ -93,7 +93,7 @@ mod tests {
|
|||||||
owner_pubkey,
|
owner_pubkey,
|
||||||
lamports,
|
lamports,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client.send_message(&[payer_keypair, account_keypair], message)
|
bank_client.send_message(&[payer_keypair, account_keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ mod tests {
|
|||||||
&old_owner_keypair.pubkey(),
|
&old_owner_keypair.pubkey(),
|
||||||
new_owner_pubkey,
|
new_owner_pubkey,
|
||||||
);
|
);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&payer_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&payer_keypair.pubkey()));
|
||||||
bank_client.send_message(&[payer_keypair, old_owner_keypair], message)
|
bank_client.send_message(&[payer_keypair, old_owner_keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -187,7 +187,7 @@ mod tests {
|
|||||||
date_instruction::create_account(&payer_keypair.pubkey(), &date_pubkey, 1);
|
date_instruction::create_account(&payer_keypair.pubkey(), &date_pubkey, 1);
|
||||||
instructions.push(date_instruction::store(&date_pubkey, date));
|
instructions.push(date_instruction::store(&date_pubkey, date));
|
||||||
|
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client.send_message(&[payer_keypair, date_keypair], message)
|
bank_client.send_message(&[payer_keypair, date_keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ mod tests {
|
|||||||
) -> Result<Signature> {
|
) -> Result<Signature> {
|
||||||
let date_pubkey = date_keypair.pubkey();
|
let date_pubkey = date_keypair.pubkey();
|
||||||
let instruction = date_instruction::store(&date_pubkey, date);
|
let instruction = date_instruction::store(&date_pubkey, date);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&payer_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&payer_keypair.pubkey()));
|
||||||
bank_client.send_message(&[payer_keypair, date_keypair], message)
|
bank_client.send_message(&[payer_keypair, date_keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ mod tests {
|
|||||||
&date_pubkey,
|
&date_pubkey,
|
||||||
lamports,
|
lamports,
|
||||||
);
|
);
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
bank_client.send_message(&[payer_keypair, contract_keypair], message)
|
bank_client.send_message(&[payer_keypair, contract_keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ mod tests {
|
|||||||
) -> Result<Signature> {
|
) -> Result<Signature> {
|
||||||
let instruction =
|
let instruction =
|
||||||
vest_instruction::redeem_tokens(&contract_pubkey, &date_pubkey, &payee_pubkey);
|
vest_instruction::redeem_tokens(&contract_pubkey, &date_pubkey, &payee_pubkey);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&payer_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&payer_keypair.pubkey()));
|
||||||
bank_client.send_message(&[payer_keypair], message)
|
bank_client.send_message(&[payer_keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,7 +353,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
instructions[1].accounts = vec![]; // <!-- Attack! Prevent accounts from being passed into processor.
|
instructions[1].accounts = vec![]; // <!-- Attack! Prevent accounts from being passed into processor.
|
||||||
|
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&alice_keypair, &contract_keypair], message)
|
.send_message(&[&alice_keypair, &contract_keypair], message)
|
||||||
|
@@ -36,7 +36,7 @@ impl Client for BankClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncClient for BankClient {
|
impl AsyncClient for BankClient {
|
||||||
fn async_send_transaction(&self, transaction: Transaction) -> io::Result<Signature> {
|
fn async_send_transaction(&self, transaction: Transaction) -> Result<Signature> {
|
||||||
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
|
||||||
let transaction_sender = self.transaction_sender.lock().unwrap();
|
let transaction_sender = self.transaction_sender.lock().unwrap();
|
||||||
transaction_sender.send(transaction).unwrap();
|
transaction_sender.send(transaction).unwrap();
|
||||||
@@ -48,7 +48,7 @@ impl AsyncClient for BankClient {
|
|||||||
keypairs: &T,
|
keypairs: &T,
|
||||||
message: Message,
|
message: Message,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature> {
|
) -> Result<Signature> {
|
||||||
let transaction = Transaction::new(keypairs, message, recent_blockhash);
|
let transaction = Transaction::new(keypairs, message, recent_blockhash);
|
||||||
self.async_send_transaction(transaction)
|
self.async_send_transaction(transaction)
|
||||||
}
|
}
|
||||||
@@ -58,8 +58,8 @@ impl AsyncClient for BankClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature> {
|
) -> Result<Signature> {
|
||||||
let message = Message::new(vec![instruction]);
|
let message = Message::new(&[instruction]);
|
||||||
self.async_send_message(&[keypair], message, recent_blockhash)
|
self.async_send_message(&[keypair], message, recent_blockhash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ impl AsyncClient for BankClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature> {
|
) -> Result<Signature> {
|
||||||
let transfer_instruction =
|
let transfer_instruction =
|
||||||
system_instruction::transfer(&keypair.pubkey(), pubkey, lamports);
|
system_instruction::transfer(&keypair.pubkey(), pubkey, lamports);
|
||||||
self.async_send_instruction(keypair, transfer_instruction, recent_blockhash)
|
self.async_send_instruction(keypair, transfer_instruction, recent_blockhash)
|
||||||
@@ -87,7 +87,7 @@ impl SyncClient for BankClient {
|
|||||||
|
|
||||||
/// Create and process a transaction from a single instruction.
|
/// Create and process a transaction from a single instruction.
|
||||||
fn send_instruction(&self, keypair: &Keypair, instruction: Instruction) -> Result<Signature> {
|
fn send_instruction(&self, keypair: &Keypair, instruction: Instruction) -> Result<Signature> {
|
||||||
let message = Message::new(vec![instruction]);
|
let message = Message::new(&[instruction]);
|
||||||
self.send_message(&[keypair], message)
|
self.send_message(&[keypair], message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +302,7 @@ mod tests {
|
|||||||
.accounts
|
.accounts
|
||||||
.push(AccountMeta::new(jane_pubkey, true));
|
.push(AccountMeta::new(jane_pubkey, true));
|
||||||
|
|
||||||
let message = Message::new(vec![transfer_instruction]);
|
let message = Message::new(&[transfer_instruction]);
|
||||||
bank_client.send_message(&doe_keypairs, message).unwrap();
|
bank_client.send_message(&doe_keypairs, message).unwrap();
|
||||||
assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 42);
|
assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 42);
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ pub fn load_program<T: Client>(
|
|||||||
bank_client
|
bank_client
|
||||||
.send_message(
|
.send_message(
|
||||||
&[from_keypair, &program_keypair],
|
&[from_keypair, &program_keypair],
|
||||||
Message::new(vec![instruction]),
|
Message::new(&[instruction]),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ pub fn load_program<T: Client>(
|
|||||||
for chunk in program.chunks(chunk_size) {
|
for chunk in program.chunks(chunk_size) {
|
||||||
let instruction =
|
let instruction =
|
||||||
loader_instruction::write(&program_pubkey, loader_pubkey, offset, chunk.to_vec());
|
loader_instruction::write(&program_pubkey, loader_pubkey, offset, chunk.to_vec());
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&from_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&from_keypair.pubkey()));
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[from_keypair, &program_keypair], message)
|
.send_message(&[from_keypair, &program_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -45,7 +45,7 @@ pub fn load_program<T: Client>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let instruction = loader_instruction::finalize(&program_pubkey, loader_pubkey);
|
let instruction = loader_instruction::finalize(&program_pubkey, loader_pubkey);
|
||||||
let message = Message::new_with_payer(vec![instruction], Some(&from_keypair.pubkey()));
|
let message = Message::new_with_payer(&[instruction], Some(&from_keypair.pubkey()));
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[from_keypair, &program_keypair], message)
|
.send_message(&[from_keypair, &program_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@@ -800,7 +800,7 @@ mod tests {
|
|||||||
AccountMeta::new(from_pubkey, true),
|
AccountMeta::new(from_pubkey, true),
|
||||||
AccountMeta::new_readonly(to_pubkey, false),
|
AccountMeta::new_readonly(to_pubkey, false),
|
||||||
];
|
];
|
||||||
let message = Message::new(vec![Instruction::new(
|
let message = Message::new(&[Instruction::new(
|
||||||
mock_system_program_id,
|
mock_system_program_id,
|
||||||
&MockSystemInstruction::Correct,
|
&MockSystemInstruction::Correct,
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
@@ -811,7 +811,7 @@ mod tests {
|
|||||||
assert_eq!(accounts[0].borrow().lamports, 100);
|
assert_eq!(accounts[0].borrow().lamports, 100);
|
||||||
assert_eq!(accounts[1].borrow().lamports, 0);
|
assert_eq!(accounts[1].borrow().lamports, 0);
|
||||||
|
|
||||||
let message = Message::new(vec![Instruction::new(
|
let message = Message::new(&[Instruction::new(
|
||||||
mock_system_program_id,
|
mock_system_program_id,
|
||||||
&MockSystemInstruction::AttemptCredit { lamports: 50 },
|
&MockSystemInstruction::AttemptCredit { lamports: 50 },
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
@@ -826,7 +826,7 @@ mod tests {
|
|||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
let message = Message::new(vec![Instruction::new(
|
let message = Message::new(&[Instruction::new(
|
||||||
mock_system_program_id,
|
mock_system_program_id,
|
||||||
&MockSystemInstruction::AttemptDataChange { data: 50 },
|
&MockSystemInstruction::AttemptDataChange { data: 50 },
|
||||||
account_metas,
|
account_metas,
|
||||||
@@ -923,7 +923,7 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Try to borrow mut the same account
|
// Try to borrow mut the same account
|
||||||
let message = Message::new(vec![Instruction::new(
|
let message = Message::new(&[Instruction::new(
|
||||||
mock_program_id,
|
mock_program_id,
|
||||||
&MockSystemInstruction::BorrowFail,
|
&MockSystemInstruction::BorrowFail,
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
@@ -938,7 +938,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Try to borrow mut the same account in a safe way
|
// Try to borrow mut the same account in a safe way
|
||||||
let message = Message::new(vec![Instruction::new(
|
let message = Message::new(&[Instruction::new(
|
||||||
mock_program_id,
|
mock_program_id,
|
||||||
&MockSystemInstruction::MultiBorrowMut,
|
&MockSystemInstruction::MultiBorrowMut,
|
||||||
account_metas.clone(),
|
account_metas.clone(),
|
||||||
@@ -947,7 +947,7 @@ mod tests {
|
|||||||
assert_eq!(result, Ok(()));
|
assert_eq!(result, Ok(()));
|
||||||
|
|
||||||
// Do work on the same account but at different location in keyed_accounts[]
|
// Do work on the same account but at different location in keyed_accounts[]
|
||||||
let message = Message::new(vec![Instruction::new(
|
let message = Message::new(&[Instruction::new(
|
||||||
mock_program_id,
|
mock_program_id,
|
||||||
&MockSystemInstruction::DoWork {
|
&MockSystemInstruction::DoWork {
|
||||||
lamports: 10,
|
lamports: 10,
|
||||||
|
@@ -111,7 +111,7 @@ pub(crate) mod tests {
|
|||||||
let bank = Arc::new(bank);
|
let bank = Arc::new(bank);
|
||||||
let bank_client = BankClient::new_shared(&bank);
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
|
|
||||||
let message = Message::new(storage_instruction::create_storage_account(
|
let message = Message::new(&storage_instruction::create_storage_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&Pubkey::default(),
|
&Pubkey::default(),
|
||||||
&archiver_pubkey,
|
&archiver_pubkey,
|
||||||
@@ -122,7 +122,7 @@ pub(crate) mod tests {
|
|||||||
.send_message(&[&mint_keypair, &archiver_keypair], message)
|
.send_message(&[&mint_keypair, &archiver_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let message = Message::new(storage_instruction::create_storage_account(
|
let message = Message::new(&storage_instruction::create_storage_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&Pubkey::default(),
|
&Pubkey::default(),
|
||||||
&validator_pubkey,
|
&validator_pubkey,
|
||||||
|
@@ -926,7 +926,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let allocate_with_seed = Message::new_with_payer(
|
let allocate_with_seed = Message::new_with_payer(
|
||||||
vec![system_instruction::allocate_with_seed(
|
&[system_instruction::allocate_with_seed(
|
||||||
&alice_with_seed,
|
&alice_with_seed,
|
||||||
&alice_pubkey,
|
&alice_pubkey,
|
||||||
seed,
|
seed,
|
||||||
@@ -978,7 +978,7 @@ mod tests {
|
|||||||
let bank = Arc::new(Bank::new_from_parent(&bank, &collector, bank.slot() + 1));
|
let bank = Arc::new(Bank::new_from_parent(&bank, &collector, bank.slot() + 1));
|
||||||
let bank_client = BankClient::new_shared(&bank);
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
let ix = system_instruction::create_account(&alice_pubkey, &bob_pubkey, 0, len1, &program);
|
let ix = system_instruction::create_account(&alice_pubkey, &bob_pubkey, 0, len1, &program);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let r = bank_client.send_message(&[&alice_keypair, &bob_keypair], message);
|
let r = bank_client.send_message(&[&alice_keypair, &bob_keypair], message);
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
@@ -996,7 +996,7 @@ mod tests {
|
|||||||
let bank = Arc::new(Bank::new_from_parent(&bank, &collector, bank.slot() + 1));
|
let bank = Arc::new(Bank::new_from_parent(&bank, &collector, bank.slot() + 1));
|
||||||
let bank_client = BankClient::new_shared(&bank);
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
let ix = system_instruction::create_account(&alice_pubkey, &bob_pubkey, 1, len2, &program);
|
let ix = system_instruction::create_account(&alice_pubkey, &bob_pubkey, 1, len2, &program);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
let r = bank_client.send_message(&[&alice_keypair, &bob_keypair], message);
|
let r = bank_client.send_message(&[&alice_keypair, &bob_keypair], message);
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
}
|
}
|
||||||
@@ -1036,7 +1036,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let assign_with_seed = Message::new_with_payer(
|
let assign_with_seed = Message::new_with_payer(
|
||||||
vec![system_instruction::assign_with_seed(
|
&[system_instruction::assign_with_seed(
|
||||||
&alice_with_seed,
|
&alice_with_seed,
|
||||||
&alice_pubkey,
|
&alice_pubkey,
|
||||||
seed,
|
seed,
|
||||||
|
@@ -53,7 +53,7 @@ fn fill_epoch_with_votes(
|
|||||||
let parent = bank.parent().unwrap();
|
let parent = bank.parent().unwrap();
|
||||||
|
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![vote_instruction::vote(
|
&[vote_instruction::vote(
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
Vote::new(vec![parent.slot() as u64], parent.hash()),
|
Vote::new(vec![parent.slot() as u64], parent.hash()),
|
||||||
@@ -121,7 +121,7 @@ fn test_stake_create_and_split_single_signature() {
|
|||||||
let lamports = 1_000_000;
|
let lamports = 1_000_000;
|
||||||
|
|
||||||
// Create stake account with seed
|
// Create stake account with seed
|
||||||
let message = Message::new(stake_instruction::create_account_with_seed(
|
let message = Message::new(&stake_instruction::create_account_with_seed(
|
||||||
&staker_pubkey, // from
|
&staker_pubkey, // from
|
||||||
&stake_address, // to
|
&stake_address, // to
|
||||||
&staker_pubkey, // base
|
&staker_pubkey, // base
|
||||||
@@ -141,7 +141,7 @@ fn test_stake_create_and_split_single_signature() {
|
|||||||
create_address_with_seed(&staker_pubkey, "split_stake", &solana_stake_program::id())
|
create_address_with_seed(&staker_pubkey, "split_stake", &solana_stake_program::id())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// Test split
|
// Test split
|
||||||
let message = Message::new(stake_instruction::split_with_seed(
|
let message = Message::new(&stake_instruction::split_with_seed(
|
||||||
&stake_address, // original
|
&stake_address, // original
|
||||||
&staker_pubkey, // authorized
|
&staker_pubkey, // authorized
|
||||||
lamports / 2,
|
lamports / 2,
|
||||||
@@ -179,7 +179,7 @@ fn test_stake_account_lifetime() {
|
|||||||
let bank_client = BankClient::new_shared(&bank);
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
|
|
||||||
// Create Vote Account
|
// Create Vote Account
|
||||||
let message = Message::new(vote_instruction::create_account(
|
let message = Message::new(&vote_instruction::create_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
&VoteInit {
|
&VoteInit {
|
||||||
@@ -196,7 +196,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
let authorized = stake_state::Authorized::auto(&stake_pubkey);
|
let authorized = stake_state::Authorized::auto(&stake_pubkey);
|
||||||
// Create stake account and delegate to vote account
|
// Create stake account and delegate to vote account
|
||||||
let message = Message::new(stake_instruction::create_account_and_delegate_stake(
|
let message = Message::new(&stake_instruction::create_account_and_delegate_stake(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
@@ -219,7 +219,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
// Test that we cannot withdraw anything until deactivation
|
// Test that we cannot withdraw anything until deactivation
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![stake_instruction::withdraw(
|
&[stake_instruction::withdraw(
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&Pubkey::new_rand(),
|
&Pubkey::new_rand(),
|
||||||
@@ -282,7 +282,7 @@ fn test_stake_account_lifetime() {
|
|||||||
let bank_client = BankClient::new_shared(&bank);
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
// Test split
|
// Test split
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
stake_instruction::split(
|
&stake_instruction::split(
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
lamports / 2,
|
lamports / 2,
|
||||||
@@ -299,7 +299,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
// Deactivate the split
|
// Deactivate the split
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![stake_instruction::deactivate_stake(
|
&[stake_instruction::deactivate_stake(
|
||||||
&split_stake_pubkey,
|
&split_stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
)],
|
)],
|
||||||
@@ -313,7 +313,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
// Test that we cannot withdraw above what's staked
|
// Test that we cannot withdraw above what's staked
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![stake_instruction::withdraw(
|
&[stake_instruction::withdraw(
|
||||||
&split_stake_pubkey,
|
&split_stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&Pubkey::new_rand(),
|
&Pubkey::new_rand(),
|
||||||
@@ -334,7 +334,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
// withdrawal in cooldown
|
// withdrawal in cooldown
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![stake_instruction::withdraw(
|
&[stake_instruction::withdraw(
|
||||||
&split_stake_pubkey,
|
&split_stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&Pubkey::new_rand(),
|
&Pubkey::new_rand(),
|
||||||
@@ -349,7 +349,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
// but we can withdraw unstaked
|
// but we can withdraw unstaked
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![stake_instruction::withdraw(
|
&[stake_instruction::withdraw(
|
||||||
&split_stake_pubkey,
|
&split_stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&Pubkey::new_rand(),
|
&Pubkey::new_rand(),
|
||||||
@@ -373,7 +373,7 @@ fn test_stake_account_lifetime() {
|
|||||||
|
|
||||||
// Test that we can withdraw everything else out of the split
|
// Test that we can withdraw everything else out of the split
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![stake_instruction::withdraw(
|
&[stake_instruction::withdraw(
|
||||||
&split_stake_pubkey,
|
&split_stake_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&Pubkey::new_rand(),
|
&Pubkey::new_rand(),
|
||||||
@@ -414,7 +414,7 @@ fn test_create_stake_account_from_seed() {
|
|||||||
create_address_with_seed(&mint_pubkey, seed, &solana_stake_program::id()).unwrap();
|
create_address_with_seed(&mint_pubkey, seed, &solana_stake_program::id()).unwrap();
|
||||||
|
|
||||||
// Create Vote Account
|
// Create Vote Account
|
||||||
let message = Message::new(vote_instruction::create_account(
|
let message = Message::new(&vote_instruction::create_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
&VoteInit {
|
&VoteInit {
|
||||||
@@ -432,7 +432,7 @@ fn test_create_stake_account_from_seed() {
|
|||||||
let authorized = stake_state::Authorized::auto(&mint_pubkey);
|
let authorized = stake_state::Authorized::auto(&mint_pubkey);
|
||||||
// Create stake account and delegate to vote account
|
// Create stake account and delegate to vote account
|
||||||
let message = Message::new(
|
let message = Message::new(
|
||||||
stake_instruction::create_account_with_seed_and_delegate_stake(
|
&stake_instruction::create_account_with_seed_and_delegate_stake(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&stake_pubkey,
|
&stake_pubkey,
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
|
@@ -49,7 +49,7 @@ fn test_account_owner() {
|
|||||||
let bank = Arc::new(bank);
|
let bank = Arc::new(bank);
|
||||||
let bank_client = BankClient::new_shared(&bank);
|
let bank_client = BankClient::new_shared(&bank);
|
||||||
|
|
||||||
let message = Message::new(storage_instruction::create_storage_account(
|
let message = Message::new(&storage_instruction::create_storage_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&account_owner,
|
&account_owner,
|
||||||
&validator_storage_pubkey,
|
&validator_storage_pubkey,
|
||||||
@@ -69,7 +69,7 @@ fn test_account_owner() {
|
|||||||
assert!(false, "wrong account type found")
|
assert!(false, "wrong account type found")
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = Message::new(storage_instruction::create_storage_account(
|
let message = Message::new(&storage_instruction::create_storage_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&account_owner,
|
&account_owner,
|
||||||
&archiver_storage_pubkey,
|
&archiver_storage_pubkey,
|
||||||
@@ -137,7 +137,7 @@ fn test_validate_mining() {
|
|||||||
|
|
||||||
// advertise for storage segment 1
|
// advertise for storage segment 1
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::advertise_recent_blockhash(
|
&[storage_instruction::advertise_recent_blockhash(
|
||||||
&validator_storage_id,
|
&validator_storage_id,
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
1,
|
1,
|
||||||
@@ -172,7 +172,7 @@ fn test_validate_mining() {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::advertise_recent_blockhash(
|
&[storage_instruction::advertise_recent_blockhash(
|
||||||
&validator_storage_id,
|
&validator_storage_id,
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
2,
|
2,
|
||||||
@@ -195,7 +195,7 @@ fn test_validate_mining() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::proof_validation(
|
&[storage_instruction::proof_validation(
|
||||||
&validator_storage_id,
|
&validator_storage_id,
|
||||||
proof_segment as u64,
|
proof_segment as u64,
|
||||||
checked_proofs.into_iter().map(|entry| entry).collect(),
|
checked_proofs.into_iter().map(|entry| entry).collect(),
|
||||||
@@ -209,7 +209,7 @@ fn test_validate_mining() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::advertise_recent_blockhash(
|
&[storage_instruction::advertise_recent_blockhash(
|
||||||
&validator_storage_id,
|
&validator_storage_id,
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
3,
|
3,
|
||||||
@@ -244,7 +244,7 @@ fn test_validate_mining() {
|
|||||||
.map(|account| Rewards::from_account(&account).unwrap())
|
.map(|account| Rewards::from_account(&account).unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::claim_reward(
|
&[storage_instruction::claim_reward(
|
||||||
&owner_pubkey,
|
&owner_pubkey,
|
||||||
&validator_storage_id,
|
&validator_storage_id,
|
||||||
)],
|
)],
|
||||||
@@ -264,7 +264,7 @@ fn test_validate_mining() {
|
|||||||
assert_eq!(bank_client.get_balance(&archiver_1_storage_id).unwrap(), 10);
|
assert_eq!(bank_client.get_balance(&archiver_1_storage_id).unwrap(), 10);
|
||||||
|
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::claim_reward(
|
&[storage_instruction::claim_reward(
|
||||||
&owner_pubkey,
|
&owner_pubkey,
|
||||||
&archiver_1_storage_id,
|
&archiver_1_storage_id,
|
||||||
)],
|
)],
|
||||||
@@ -278,7 +278,7 @@ fn test_validate_mining() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::claim_reward(
|
&[storage_instruction::claim_reward(
|
||||||
&owner_pubkey,
|
&owner_pubkey,
|
||||||
&archiver_2_storage_id,
|
&archiver_2_storage_id,
|
||||||
)],
|
)],
|
||||||
@@ -328,7 +328,7 @@ fn init_storage_accounts(
|
|||||||
StorageAccountType::Archiver,
|
StorageAccountType::Archiver,
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
let message = Message::new(ixs);
|
let message = Message::new(&ixs);
|
||||||
client.send_message(&signers, message).unwrap();
|
client.send_message(&signers, message).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ fn submit_proof(
|
|||||||
) -> ProofStatus {
|
) -> ProofStatus {
|
||||||
let sha_state = Hash::new(Pubkey::new_rand().as_ref());
|
let sha_state = Hash::new(Pubkey::new_rand().as_ref());
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::mining_proof(
|
&[storage_instruction::mining_proof(
|
||||||
&storage_keypair.pubkey(),
|
&storage_keypair.pubkey(),
|
||||||
sha_state,
|
sha_state,
|
||||||
segment_index,
|
segment_index,
|
||||||
@@ -422,7 +422,7 @@ fn test_bank_storage() {
|
|||||||
let x2 = x * 2;
|
let x2 = x * 2;
|
||||||
let storage_blockhash = hash(&[x2]);
|
let storage_blockhash = hash(&[x2]);
|
||||||
|
|
||||||
let message = Message::new(storage_instruction::create_storage_account(
|
let message = Message::new(&storage_instruction::create_storage_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&Pubkey::default(),
|
&Pubkey::default(),
|
||||||
&archiver_pubkey,
|
&archiver_pubkey,
|
||||||
@@ -433,7 +433,7 @@ fn test_bank_storage() {
|
|||||||
.send_message(&[&mint_keypair, &archiver_keypair], message)
|
.send_message(&[&mint_keypair, &archiver_keypair], message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let message = Message::new(storage_instruction::create_storage_account(
|
let message = Message::new(&storage_instruction::create_storage_account(
|
||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&Pubkey::default(),
|
&Pubkey::default(),
|
||||||
&validator_pubkey,
|
&validator_pubkey,
|
||||||
@@ -445,7 +445,7 @@ fn test_bank_storage() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::advertise_recent_blockhash(
|
&[storage_instruction::advertise_recent_blockhash(
|
||||||
&validator_pubkey,
|
&validator_pubkey,
|
||||||
storage_blockhash,
|
storage_blockhash,
|
||||||
1,
|
1,
|
||||||
@@ -460,7 +460,7 @@ fn test_bank_storage() {
|
|||||||
|
|
||||||
let slot = 0;
|
let slot = 0;
|
||||||
let message = Message::new_with_payer(
|
let message = Message::new_with_payer(
|
||||||
vec![storage_instruction::mining_proof(
|
&[storage_instruction::mining_proof(
|
||||||
&archiver_pubkey,
|
&archiver_pubkey,
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
slot,
|
slot,
|
||||||
|
@@ -21,7 +21,6 @@ use crate::{
|
|||||||
transaction,
|
transaction,
|
||||||
transport::Result,
|
transport::Result,
|
||||||
};
|
};
|
||||||
use std::io;
|
|
||||||
|
|
||||||
pub trait Client: SyncClient + AsyncClient {
|
pub trait Client: SyncClient + AsyncClient {
|
||||||
fn tpu_addr(&self) -> String;
|
fn tpu_addr(&self) -> String;
|
||||||
@@ -122,10 +121,7 @@ pub trait SyncClient {
|
|||||||
|
|
||||||
pub trait AsyncClient {
|
pub trait AsyncClient {
|
||||||
/// Send a signed transaction, but don't wait to see if the server accepted it.
|
/// Send a signed transaction, but don't wait to see if the server accepted it.
|
||||||
fn async_send_transaction(
|
fn async_send_transaction(&self, transaction: transaction::Transaction) -> Result<Signature>;
|
||||||
&self,
|
|
||||||
transaction: transaction::Transaction,
|
|
||||||
) -> io::Result<Signature>;
|
|
||||||
|
|
||||||
/// Create a transaction from the given message, and send it to the
|
/// Create a transaction from the given message, and send it to the
|
||||||
/// server, but don't wait for to see if the server accepted it.
|
/// server, but don't wait for to see if the server accepted it.
|
||||||
@@ -134,7 +130,7 @@ pub trait AsyncClient {
|
|||||||
keypairs: &T,
|
keypairs: &T,
|
||||||
message: Message,
|
message: Message,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature>;
|
) -> Result<Signature>;
|
||||||
|
|
||||||
/// Create a transaction from a single instruction that only requires
|
/// Create a transaction from a single instruction that only requires
|
||||||
/// a single signer. Then send it to the server, but don't wait for a reply.
|
/// a single signer. Then send it to the server, but don't wait for a reply.
|
||||||
@@ -143,7 +139,7 @@ pub trait AsyncClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature>;
|
) -> Result<Signature>;
|
||||||
|
|
||||||
/// Attempt to transfer lamports from `keypair` to `pubkey`, but don't wait to confirm.
|
/// Attempt to transfer lamports from `keypair` to `pubkey`, but don't wait to confirm.
|
||||||
fn async_transfer(
|
fn async_transfer(
|
||||||
@@ -152,5 +148,5 @@ pub trait AsyncClient {
|
|||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> io::Result<Signature>;
|
) -> Result<Signature>;
|
||||||
}
|
}
|
||||||
|
@@ -183,7 +183,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_fee_calculator_calculate_fee() {
|
fn test_fee_calculator_calculate_fee() {
|
||||||
// Default: no fee.
|
// Default: no fee.
|
||||||
let message = Message::new(vec![]);
|
let message = Message::new(&[]);
|
||||||
assert_eq!(FeeCalculator::default().calculate_fee(&message), 0);
|
assert_eq!(FeeCalculator::default().calculate_fee(&message), 0);
|
||||||
|
|
||||||
// No signature, no fee.
|
// No signature, no fee.
|
||||||
@@ -193,13 +193,13 @@ mod tests {
|
|||||||
let pubkey0 = Pubkey::new(&[0; 32]);
|
let pubkey0 = Pubkey::new(&[0; 32]);
|
||||||
let pubkey1 = Pubkey::new(&[1; 32]);
|
let pubkey1 = Pubkey::new(&[1; 32]);
|
||||||
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
||||||
let message = Message::new(vec![ix0]);
|
let message = Message::new(&[ix0]);
|
||||||
assert_eq!(FeeCalculator::new(2).calculate_fee(&message), 2);
|
assert_eq!(FeeCalculator::new(2).calculate_fee(&message), 2);
|
||||||
|
|
||||||
// Two signatures, double the fee.
|
// Two signatures, double the fee.
|
||||||
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
let ix0 = system_instruction::transfer(&pubkey0, &pubkey1, 1);
|
||||||
let ix1 = system_instruction::transfer(&pubkey1, &pubkey0, 1);
|
let ix1 = system_instruction::transfer(&pubkey1, &pubkey0, 1);
|
||||||
let message = Message::new(vec![ix0, ix1]);
|
let message = Message::new(&[ix0, ix1]);
|
||||||
assert_eq!(FeeCalculator::new(2).calculate_fee(&message), 4);
|
assert_eq!(FeeCalculator::new(2).calculate_fee(&message), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::{convert::TryFrom, fmt, mem, str::FromStr};
|
use std::{convert::TryFrom, fmt, mem, str::FromStr};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub const HASH_BYTES: usize = 32;
|
pub const HASH_BYTES: usize = 32;
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
@@ -47,9 +48,11 @@ impl fmt::Display for Hash {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
||||||
pub enum ParseHashError {
|
pub enum ParseHashError {
|
||||||
|
#[error("string decoded to wrong size for hash")]
|
||||||
WrongSize,
|
WrongSize,
|
||||||
|
#[error("failed to decoded string to hash")]
|
||||||
Invalid,
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,96 +3,124 @@
|
|||||||
use crate::{pubkey::Pubkey, short_vec, system_instruction::SystemError};
|
use crate::{pubkey::Pubkey, short_vec, system_instruction::SystemError};
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
/// Reasons the runtime might have rejected an instruction.
|
/// Reasons the runtime might have rejected an instruction.
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Error, PartialEq, Eq, Clone)]
|
||||||
pub enum InstructionError {
|
pub enum InstructionError {
|
||||||
/// Deprecated! Use CustomError instead!
|
/// Deprecated! Use CustomError instead!
|
||||||
/// The program instruction returned an error
|
/// The program instruction returned an error
|
||||||
|
#[error("generic instruction error")]
|
||||||
GenericError,
|
GenericError,
|
||||||
|
|
||||||
/// The arguments provided to a program instruction where invalid
|
/// The arguments provided to a program were invalid
|
||||||
|
#[error("invalid program argument")]
|
||||||
InvalidArgument,
|
InvalidArgument,
|
||||||
|
|
||||||
/// An instruction's data contents was invalid
|
/// An instruction's data contents were invalid
|
||||||
|
#[error("invalid instruction data")]
|
||||||
InvalidInstructionData,
|
InvalidInstructionData,
|
||||||
|
|
||||||
/// An account's data contents was invalid
|
/// An account's data contents was invalid
|
||||||
|
#[error("invalid account data for instruction")]
|
||||||
InvalidAccountData,
|
InvalidAccountData,
|
||||||
|
|
||||||
/// An account's data was too small
|
/// An account's data was too small
|
||||||
|
#[error("account data too small for instruction")]
|
||||||
AccountDataTooSmall,
|
AccountDataTooSmall,
|
||||||
|
|
||||||
/// An account's balance was too small to complete the instruction
|
/// An account's balance was too small to complete the instruction
|
||||||
|
#[error("insufficient funds for instruction")]
|
||||||
InsufficientFunds,
|
InsufficientFunds,
|
||||||
|
|
||||||
/// The account did not have the expected program id
|
/// The account did not have the expected program id
|
||||||
|
#[error("incorrect program id for instruction")]
|
||||||
IncorrectProgramId,
|
IncorrectProgramId,
|
||||||
|
|
||||||
/// A signature was required but not found
|
/// A signature was required but not found
|
||||||
|
#[error("missing required signature for instruction")]
|
||||||
MissingRequiredSignature,
|
MissingRequiredSignature,
|
||||||
|
|
||||||
/// An initialize instruction was sent to an account that has already been initialized.
|
/// An initialize instruction was sent to an account that has already been initialized.
|
||||||
|
#[error("instruction requires an uninitialized account")]
|
||||||
AccountAlreadyInitialized,
|
AccountAlreadyInitialized,
|
||||||
|
|
||||||
/// An attempt to operate on an account that hasn't been initialized.
|
/// An attempt to operate on an account that hasn't been initialized.
|
||||||
|
#[error("instruction requires an initialized account")]
|
||||||
UninitializedAccount,
|
UninitializedAccount,
|
||||||
|
|
||||||
/// Program's instruction lamport balance does not equal the balance after the instruction
|
/// Program's instruction lamport balance does not equal the balance after the instruction
|
||||||
|
#[error("sum of account balances before and after instruction do not match")]
|
||||||
UnbalancedInstruction,
|
UnbalancedInstruction,
|
||||||
|
|
||||||
/// Program modified an account's program id
|
/// Program modified an account's program id
|
||||||
|
#[error("instruction modified the program id of an account")]
|
||||||
ModifiedProgramId,
|
ModifiedProgramId,
|
||||||
|
|
||||||
/// Program spent the lamports of an account that doesn't belong to it
|
/// Program spent the lamports of an account that doesn't belong to it
|
||||||
|
#[error("instruction spent from the balance of an account it does not own")]
|
||||||
ExternalAccountLamportSpend,
|
ExternalAccountLamportSpend,
|
||||||
|
|
||||||
/// Program modified the data of an account that doesn't belong to it
|
/// Program modified the data of an account that doesn't belong to it
|
||||||
|
#[error("instruction modified data of an account it does not own")]
|
||||||
ExternalAccountDataModified,
|
ExternalAccountDataModified,
|
||||||
|
|
||||||
/// Read-only account modified lamports
|
/// Read-only account modified lamports
|
||||||
|
#[error("instruction changed balance of a read-only account")]
|
||||||
ReadonlyLamportChange,
|
ReadonlyLamportChange,
|
||||||
|
|
||||||
/// Read-only account modified data
|
/// Read-only account modified data
|
||||||
|
#[error("instruction modified data of a read-only account")]
|
||||||
ReadonlyDataModified,
|
ReadonlyDataModified,
|
||||||
|
|
||||||
/// An account was referenced more than once in a single instruction
|
/// An account was referenced more than once in a single instruction
|
||||||
// Deprecated, instructions can now contain duplicate accounts
|
// Deprecated, instructions can now contain duplicate accounts
|
||||||
|
#[error("instruction contains duplicate accounts")]
|
||||||
DuplicateAccountIndex,
|
DuplicateAccountIndex,
|
||||||
|
|
||||||
/// Executable bit on account changed, but shouldn't have
|
/// Executable bit on account changed, but shouldn't have
|
||||||
|
#[error("instruction changed executable bit of an account")]
|
||||||
ExecutableModified,
|
ExecutableModified,
|
||||||
|
|
||||||
/// Rent_epoch account changed, but shouldn't have
|
/// Rent_epoch account changed, but shouldn't have
|
||||||
|
#[error("instruction modified rent epoch of an account")]
|
||||||
RentEpochModified,
|
RentEpochModified,
|
||||||
|
|
||||||
/// The instruction expected additional account keys
|
/// The instruction expected additional account keys
|
||||||
|
#[error("insufficient account key count for instruction")]
|
||||||
NotEnoughAccountKeys,
|
NotEnoughAccountKeys,
|
||||||
|
|
||||||
/// A non-system program changed the size of the account data
|
/// A non-system program changed the size of the account data
|
||||||
|
#[error("non-system instruction changed account size")]
|
||||||
AccountDataSizeChanged,
|
AccountDataSizeChanged,
|
||||||
|
|
||||||
/// The instruction expected an executable account
|
/// The instruction expected an executable account
|
||||||
|
#[error("instruction expected an executable account")]
|
||||||
AccountNotExecutable,
|
AccountNotExecutable,
|
||||||
|
|
||||||
/// Failed to borrow a reference to account data, already borrowed
|
/// Failed to borrow a reference to account data, already borrowed
|
||||||
|
#[error("instruction tries to borrow reference for an account which is already borrowed")]
|
||||||
AccountBorrowFailed,
|
AccountBorrowFailed,
|
||||||
|
|
||||||
/// Account data has an outstanding reference after a program's execution
|
/// Account data has an outstanding reference after a program's execution
|
||||||
|
#[error("instruction left account with an outstanding reference borrowed")]
|
||||||
AccountBorrowOutstanding,
|
AccountBorrowOutstanding,
|
||||||
|
|
||||||
/// The same account was multiply passed to an on-chain program's entrypoint, but the program
|
/// The same account was multiply passed to an on-chain program's entrypoint, but the program
|
||||||
/// modified them differently. A program can only modify one instance of the account because
|
/// modified them differently. A program can only modify one instance of the account because
|
||||||
/// the runtime cannot determine which changes to pick or how to merge them if both are modified
|
/// the runtime cannot determine which changes to pick or how to merge them if both are modified
|
||||||
|
#[error("instruction modifications of multiply-passed account differ")]
|
||||||
DuplicateAccountOutOfSync,
|
DuplicateAccountOutOfSync,
|
||||||
|
|
||||||
/// Allows on-chain programs to implement program-specific error types and see them returned
|
/// Allows on-chain programs to implement program-specific error types and see them returned
|
||||||
/// by the Solana runtime. A program-specific error may be any type that is represented as
|
/// by the Solana runtime. A program-specific error may be any type that is represented as
|
||||||
/// or serialized to a u32 integer.
|
/// or serialized to a u32 integer.
|
||||||
|
#[error("program error: {0}")]
|
||||||
CustomError(u32),
|
CustomError(u32),
|
||||||
|
|
||||||
/// The return value from the program was invalid. Valid errors are either a defined builtin
|
/// The return value from the program was invalid. Valid errors are either a defined builtin
|
||||||
/// error value or a user-defined error in the lower 32 bits.
|
/// error value or a user-defined error in the lower 32 bits.
|
||||||
|
#[error("program returned invalid error code")]
|
||||||
InvalidError,
|
InvalidError,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@ fn position(keys: &[Pubkey], key: &Pubkey) -> u8 {
|
|||||||
keys.iter().position(|k| k == key).unwrap() as u8
|
keys.iter().position(|k| k == key).unwrap() as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_instruction(ix: Instruction, keys: &[Pubkey]) -> CompiledInstruction {
|
fn compile_instruction(ix: &Instruction, keys: &[Pubkey]) -> CompiledInstruction {
|
||||||
let accounts: Vec<_> = ix
|
let accounts: Vec<_> = ix
|
||||||
.accounts
|
.accounts
|
||||||
.iter()
|
.iter()
|
||||||
@@ -27,10 +27,8 @@ fn compile_instruction(ix: Instruction, keys: &[Pubkey]) -> CompiledInstruction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_instructions(ixs: Vec<Instruction>, keys: &[Pubkey]) -> Vec<CompiledInstruction> {
|
fn compile_instructions(ixs: &[Instruction], keys: &[Pubkey]) -> Vec<CompiledInstruction> {
|
||||||
ixs.into_iter()
|
ixs.iter().map(|ix| compile_instruction(ix, keys)).collect()
|
||||||
.map(|ix| compile_instruction(ix, keys))
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A helper struct to collect pubkeys referenced by a set of instructions and read-only counts
|
/// A helper struct to collect pubkeys referenced by a set of instructions and read-only counts
|
||||||
@@ -185,17 +183,17 @@ impl Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(instructions: Vec<Instruction>) -> Self {
|
pub fn new(instructions: &[Instruction]) -> Self {
|
||||||
Self::new_with_payer(instructions, None)
|
Self::new_with_payer(instructions, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_payer(instructions: Vec<Instruction>, payer: Option<&Pubkey>) -> Self {
|
pub fn new_with_payer(instructions: &[Instruction], payer: Option<&Pubkey>) -> Self {
|
||||||
let InstructionKeys {
|
let InstructionKeys {
|
||||||
mut signed_keys,
|
mut signed_keys,
|
||||||
unsigned_keys,
|
unsigned_keys,
|
||||||
num_readonly_signed_accounts,
|
num_readonly_signed_accounts,
|
||||||
num_readonly_unsigned_accounts,
|
num_readonly_unsigned_accounts,
|
||||||
} = get_keys(&instructions, payer);
|
} = get_keys(instructions, payer);
|
||||||
let num_required_signatures = signed_keys.len() as u8;
|
let num_required_signatures = signed_keys.len() as u8;
|
||||||
signed_keys.extend(&unsigned_keys);
|
signed_keys.extend(&unsigned_keys);
|
||||||
let instructions = compile_instructions(instructions, &signed_keys);
|
let instructions = compile_instructions(instructions, &signed_keys);
|
||||||
@@ -220,7 +218,7 @@ impl Message {
|
|||||||
&nonce_authority_pubkey,
|
&nonce_authority_pubkey,
|
||||||
);
|
);
|
||||||
instructions.insert(0, nonce_ix);
|
instructions.insert(0, nonce_ix);
|
||||||
Self::new_with_payer(instructions, payer)
|
Self::new_with_payer(&instructions, payer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
@@ -426,11 +424,11 @@ mod tests {
|
|||||||
let program_id = Pubkey::default();
|
let program_id = Pubkey::default();
|
||||||
let id0 = Pubkey::default();
|
let id0 = Pubkey::default();
|
||||||
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]);
|
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
assert_eq!(message.header.num_required_signatures, 0);
|
assert_eq!(message.header.num_required_signatures, 0);
|
||||||
|
|
||||||
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]);
|
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]);
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
assert_eq!(message.header.num_required_signatures, 1);
|
assert_eq!(message.header.num_required_signatures, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,7 +461,7 @@ mod tests {
|
|||||||
let id0 = Pubkey::default();
|
let id0 = Pubkey::default();
|
||||||
let keypair1 = Keypair::new();
|
let keypair1 = Keypair::new();
|
||||||
let id1 = keypair1.pubkey();
|
let id1 = keypair1.pubkey();
|
||||||
let message = Message::new(vec![
|
let message = Message::new(&[
|
||||||
Instruction::new(program_id0, &0, vec![AccountMeta::new(id0, false)]),
|
Instruction::new(program_id0, &0, vec![AccountMeta::new(id0, false)]),
|
||||||
Instruction::new(program_id1, &0, vec![AccountMeta::new(id1, true)]),
|
Instruction::new(program_id1, &0, vec![AccountMeta::new(id1, true)]),
|
||||||
Instruction::new(program_id0, &0, vec![AccountMeta::new(id1, false)]),
|
Instruction::new(program_id0, &0, vec![AccountMeta::new(id1, false)]),
|
||||||
@@ -489,11 +487,11 @@ mod tests {
|
|||||||
let id0 = Pubkey::default();
|
let id0 = Pubkey::default();
|
||||||
|
|
||||||
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]);
|
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]);
|
||||||
let message = Message::new_with_payer(vec![ix], Some(&payer));
|
let message = Message::new_with_payer(&[ix], Some(&payer));
|
||||||
assert_eq!(message.header.num_required_signatures, 1);
|
assert_eq!(message.header.num_required_signatures, 1);
|
||||||
|
|
||||||
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]);
|
let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]);
|
||||||
let message = Message::new_with_payer(vec![ix], Some(&payer));
|
let message = Message::new_with_payer(&[ix], Some(&payer));
|
||||||
assert_eq!(message.header.num_required_signatures, 2);
|
assert_eq!(message.header.num_required_signatures, 2);
|
||||||
|
|
||||||
let ix = Instruction::new(
|
let ix = Instruction::new(
|
||||||
@@ -501,7 +499,7 @@ mod tests {
|
|||||||
&0,
|
&0,
|
||||||
vec![AccountMeta::new(payer, true), AccountMeta::new(id0, true)],
|
vec![AccountMeta::new(payer, true), AccountMeta::new(id0, true)],
|
||||||
);
|
);
|
||||||
let message = Message::new_with_payer(vec![ix], Some(&payer));
|
let message = Message::new_with_payer(&[ix], Some(&payer));
|
||||||
assert_eq!(message.header.num_required_signatures, 2);
|
assert_eq!(message.header.num_required_signatures, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +526,7 @@ mod tests {
|
|||||||
let program_id0 = Pubkey::default();
|
let program_id0 = Pubkey::default();
|
||||||
let program_id1 = Pubkey::new_rand();
|
let program_id1 = Pubkey::new_rand();
|
||||||
let id = Pubkey::new_rand();
|
let id = Pubkey::new_rand();
|
||||||
let message = Message::new(vec![
|
let message = Message::new(&[
|
||||||
Instruction::new(program_id0, &0, vec![AccountMeta::new(id, false)]),
|
Instruction::new(program_id0, &0, vec![AccountMeta::new(id, false)]),
|
||||||
Instruction::new(program_id1, &0, vec![AccountMeta::new(id, true)]),
|
Instruction::new(program_id1, &0, vec![AccountMeta::new(id, true)]),
|
||||||
]);
|
]);
|
||||||
@@ -571,7 +569,7 @@ mod tests {
|
|||||||
let id1 = Pubkey::new_rand();
|
let id1 = Pubkey::new_rand();
|
||||||
let id2 = Pubkey::new_rand();
|
let id2 = Pubkey::new_rand();
|
||||||
let id3 = Pubkey::new_rand();
|
let id3 = Pubkey::new_rand();
|
||||||
let message = Message::new(vec![
|
let message = Message::new(&[
|
||||||
Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]),
|
Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]),
|
||||||
Instruction::new(program_id, &0, vec![AccountMeta::new(id1, true)]),
|
Instruction::new(program_id, &0, vec![AccountMeta::new(id1, true)]),
|
||||||
Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id2, false)]),
|
Instruction::new(program_id, &0, vec![AccountMeta::new_readonly(id2, false)]),
|
||||||
|
@@ -107,9 +107,11 @@ impl Into<[u8; 64]> for Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
||||||
pub enum ParseSignatureError {
|
pub enum ParseSignatureError {
|
||||||
|
#[error("string decoded to wrong size for signature")]
|
||||||
WrongSize,
|
WrongSize,
|
||||||
|
#[error("failed to decode string to signature")]
|
||||||
Invalid,
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -92,7 +92,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_payer(instructions: Vec<Instruction>, payer: Option<&Pubkey>) -> Self {
|
pub fn new_with_payer(instructions: Vec<Instruction>, payer: Option<&Pubkey>) -> Self {
|
||||||
let message = Message::new_with_payer(instructions, payer);
|
let message = Message::new_with_payer(&instructions, payer);
|
||||||
Self::new_unsigned(message)
|
Self::new_unsigned(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ impl Transaction {
|
|||||||
signing_keypairs: &T,
|
signing_keypairs: &T,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let message = Message::new_with_payer(instructions, payer);
|
let message = Message::new_with_payer(&instructions, payer);
|
||||||
Self::new(signing_keypairs, message, recent_blockhash)
|
Self::new(signing_keypairs, message, recent_blockhash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_unsigned_instructions(instructions: Vec<Instruction>) -> Self {
|
pub fn new_unsigned_instructions(instructions: Vec<Instruction>) -> Self {
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
Self::new_unsigned(message)
|
Self::new_unsigned(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ impl Transaction {
|
|||||||
instructions: Vec<Instruction>,
|
instructions: Vec<Instruction>,
|
||||||
recent_blockhash: Hash,
|
recent_blockhash: Hash,
|
||||||
) -> Transaction {
|
) -> Transaction {
|
||||||
let message = Message::new(instructions);
|
let message = Message::new(&instructions);
|
||||||
Self::new(from_keypairs, message, recent_blockhash)
|
Self::new(from_keypairs, message, recent_blockhash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,7 +482,7 @@ mod tests {
|
|||||||
AccountMeta::new(to, false),
|
AccountMeta::new(to, false),
|
||||||
];
|
];
|
||||||
let instruction = Instruction::new(program_id, &(1u8, 2u8, 3u8), account_metas);
|
let instruction = Instruction::new(program_id, &(1u8, 2u8, 3u8), account_metas);
|
||||||
let message = Message::new(vec![instruction]);
|
let message = Message::new(&[instruction]);
|
||||||
Transaction::new(&[&keypair], message, Hash::default())
|
Transaction::new(&[&keypair], message, Hash::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +513,7 @@ mod tests {
|
|||||||
let expected_instruction_size = 1 + 1 + ix.accounts.len() + 1 + expected_data_size;
|
let expected_instruction_size = 1 + 1 + ix.accounts.len() + 1 + expected_data_size;
|
||||||
assert_eq!(expected_instruction_size, 17);
|
assert_eq!(expected_instruction_size, 17);
|
||||||
|
|
||||||
let message = Message::new(vec![ix]);
|
let message = Message::new(&[ix]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
serialized_size(&message.instructions[0]).unwrap() as usize,
|
serialized_size(&message.instructions[0]).unwrap() as usize,
|
||||||
expected_instruction_size,
|
expected_instruction_size,
|
||||||
|
@@ -1,20 +1,15 @@
|
|||||||
use crate::transaction::TransactionError;
|
use crate::transaction::TransactionError;
|
||||||
use std::{error, fmt, io};
|
use std::io;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum TransportError {
|
pub enum TransportError {
|
||||||
IoError(io::Error),
|
#[error("transport io error: {0}")]
|
||||||
TransactionError(TransactionError),
|
IoError(#[from] io::Error),
|
||||||
}
|
#[error("transport transaction error: {0}")]
|
||||||
|
TransactionError(#[from] TransactionError),
|
||||||
impl error::Error for TransportError {}
|
#[error("transport custom error: {0}")]
|
||||||
impl fmt::Display for TransportError {
|
Custom(String),
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
TransportError::IoError(err) => write!(formatter, "{:?}", err),
|
|
||||||
TransportError::TransactionError(err) => write!(formatter, "{:?}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransportError {
|
impl TransportError {
|
||||||
@@ -27,16 +22,4 @@ impl TransportError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for TransportError {
|
|
||||||
fn from(err: io::Error) -> TransportError {
|
|
||||||
TransportError::IoError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TransactionError> for TransportError {
|
|
||||||
fn from(err: TransactionError) -> TransportError {
|
|
||||||
TransportError::TransactionError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, TransportError>;
|
pub type Result<T> = std::result::Result<T, TransportError>;
|
||||||
|
@@ -9,10 +9,12 @@ use solana_clap_utils::{
|
|||||||
input_parsers::pubkeys_of,
|
input_parsers::pubkeys_of,
|
||||||
input_validators::{is_pubkey_or_keypair, is_url},
|
input_validators::{is_pubkey_or_keypair, is_url},
|
||||||
};
|
};
|
||||||
use solana_client::{rpc_client::RpcClient, rpc_response::RpcVoteAccountStatus};
|
use solana_client::{
|
||||||
|
client_error::Result as ClientResult, rpc_client::RpcClient, rpc_response::RpcVoteAccountStatus,
|
||||||
|
};
|
||||||
use solana_metrics::{datapoint_error, datapoint_info};
|
use solana_metrics::{datapoint_error, datapoint_info};
|
||||||
use solana_sdk::{hash::Hash, native_token::lamports_to_sol, pubkey::Pubkey};
|
use solana_sdk::{hash::Hash, native_token::lamports_to_sol, pubkey::Pubkey};
|
||||||
use std::{error, io, str::FromStr, thread::sleep, time::Duration};
|
use std::{error, str::FromStr, thread::sleep, time::Duration};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
interval: Duration,
|
interval: Duration,
|
||||||
@@ -115,7 +117,7 @@ fn get_config() -> Config {
|
|||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cluster_info(rpc_client: &RpcClient) -> io::Result<(u64, Hash, RpcVoteAccountStatus)> {
|
fn get_cluster_info(rpc_client: &RpcClient) -> ClientResult<(u64, Hash, RpcVoteAccountStatus)> {
|
||||||
let transaction_count = rpc_client.get_transaction_count()?;
|
let transaction_count = rpc_client.get_transaction_count()?;
|
||||||
let recent_blockhash = rpc_client.get_recent_blockhash()?.0;
|
let recent_blockhash = rpc_client.get_recent_blockhash()?.0;
|
||||||
let vote_accounts = rpc_client.get_vote_accounts()?;
|
let vote_accounts = rpc_client.get_vote_accounts()?;
|
||||||
|
Reference in New Issue
Block a user