Fix Rpc inconsistencies (#7826)

* Update rpc account format: remove byte arrays

* Base58-encode pubkeys in getStoragePubkeysForSlot

* Update docs
This commit is contained in:
Tyera Eulberg 2020-01-15 15:33:53 -07:00 committed by GitHub
parent 8ffccfbaff
commit da165d6943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 128 additions and 75 deletions

View File

@ -146,8 +146,8 @@ The result value will be an RpcResponse JSON object containing an AccountInfo JS
* `RpcResponse<AccountInfo>`, RpcResponse JSON object with `value` field set to AccountInfo, a JSON object containing: * `RpcResponse<AccountInfo>`, RpcResponse JSON object with `value` field set to AccountInfo, a JSON object containing:
* `lamports`, number of lamports assigned to this account, as a u64 * `lamports`, number of lamports assigned to this account, as a u64
* `owner`, array of 32 bytes representing the program this account has been assigned to * `owner`, base-58 encoded pubkey of the program this account has been assigned to
* `data`, array of bytes representing any data associated with the account * `data`, base-58 encoded data associated with the account
* `executable`, boolean indicating if the account contains a program \(and is strictly read-only\) * `executable`, boolean indicating if the account contains a program \(and is strictly read-only\)
#### Example: #### Example:
@ -157,7 +157,7 @@ The result value will be an RpcResponse JSON object containing an AccountInfo JS
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["2gVkYWexTHR5Hb2aLeQN3tnngvWzisFKXDUPrgMHpdST"]}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["2gVkYWexTHR5Hb2aLeQN3tnngvWzisFKXDUPrgMHpdST"]}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.23.0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]}},"id":1} {"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"executable":false,"owner":"4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM","lamports":1,"data":"Joig2k8Ax4JPMpWhXRyc2jMa7Wejz4X1xqVi3i7QRkmVj1ChUgNc4VNpGUQePJGBAui3c6886peU9GEbjsyeANN8JGStprwLbLwcw5wpPjuQQb9mwrjVmoDQBjj3MzZKgeHn6wmnQ5k8DBFuoCYKWWsJfH2gv9FvCzrN6K1CRcQZzF"}},"id":1}
``` ```
### getBalance ### getBalance
@ -500,18 +500,18 @@ The result field will be an array of arrays. Each sub array will contain:
* `string` - the account Pubkey as base-58 encoded string and a JSON object, with the following sub fields: * `string` - the account Pubkey as base-58 encoded string and a JSON object, with the following sub fields:
* `lamports`, number of lamports assigned to this account, as a u64 * `lamports`, number of lamports assigned to this account, as a u64
* `owner`, array of 32 bytes representing the program this account has been assigned to * `owner`, base-58 encoded pubkey of the program this account has been assigned to
* `data`, array of bytes representing any data associated with the account * `data`, base-58 encoded data associated with the account
* `executable`, boolean indicating if the account contains a program \(and is strictly read-only\) * `executable`, boolean indicating if the account contains a program \(and is strictly read-only\)
#### Example: #### Example:
```bash ```bash
// Request // Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getProgramAccounts", "params":["8nQwAgzN2yyUzrukXsCa3JELBYqDQrqJ3UyHiWazWxHR"]}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getProgramAccounts", "params":["4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T"]}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":[["BqGKYtAKu69ZdWEBtZHh4xgJY1BYa2YBiBReQE3pe383", {"executable":false,"owner":[50,28,250,90,221,24,94,136,147,165,253,136,1,62,196,215,225,34,222,212,99,84,202,223,245,13,149,99,149,231,91,96],"lamports":1,"data":[]], ["4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T", {"executable":false,"owner":[50,28,250,90,221,24,94,136,147,165,253,136,1,62,196,215,225,34,222,212,99,84,202,223,245,13,149,99,149,231,91,96],"lamports":10,"data":[]]]},"id":1} {"jsonrpc":"2.0","result":[["BqGKYtAKu69ZdWEBtZHh4xgJY1BYa2YBiBReQE3pe383", {"executable":false,"owner":"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T","lamports":1,"data":"", ["8nQwAgzN2yyUzrukXsCa3JELBYqDQrqJ3UyHiWazWxHR", {"executable":false,"owner":"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T","lamports":10,"data":[]]]},"id":1}
``` ```
### getRecentBlockhash ### getRecentBlockhash
@ -524,7 +524,7 @@ Returns a recent block hash from the ledger, and a fee schedule that can be used
#### Results: #### Results:
An RpcResponse containing an array consisting of a string blockhash and FeeCalculator JSON object. An RpcResponse containing a JSON object consisting of a string blockhash and FeeCalculator JSON object.
* `RpcResponse<array>` - RpcResponse JSON object with `value` field set to a JSON object including: * `RpcResponse<array>` - RpcResponse JSON object with `value` field set to a JSON object including:
* `blockhash` - a Hash as base-58 encoded string * `blockhash` - a Hash as base-58 encoded string
@ -537,7 +537,7 @@ An RpcResponse containing an array consisting of a string blockhash and FeeCalcu
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getRecentBlockhash"}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getRecentBlockhash"}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":["GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC",{"lamportsPerSignature": 0}]},"id":1} {"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"blockhash": "GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC","feeCalculator":{"lamportsPerSignature": 0}}},"id":1}
``` ```
### getSignatureStatus ### getSignatureStatus
@ -870,7 +870,7 @@ Subscribe to an account to receive notifications when the lamports or data for a
#### Notification Format: #### Notification Format:
```bash ```bash
{"jsonrpc": "2.0","method": "accountNotification", "params": {"result": {"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.23.0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"subscription":0}} {"jsonrpc": "2.0","method": "accountNotification", "params": {"result": {"executable":false,"owner":"4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM","lamports":1,"data":"Joig2k8Ax4JPMpWhXRyc2jMa7Wejz4X1xqVi3i7QRkmVj1ChUgNc4VNpGUQePJGBAui3c6886peU9GEbjsyeANN8JGStprwLbLwcw5wpPjuQQb9mwrjVmoDQBjj3MzZKgeHn6wmnQ5k8DBFuoCYKWWsJfH2gv9FvCzrN6K1CRcQZzF"},"subscription":0}}
``` ```
### accountUnsubscribe ### accountUnsubscribe
@ -928,7 +928,7 @@ Subscribe to a program to receive notifications when the lamports or data for a
* `object` - account info JSON object \(see [getAccountInfo](jsonrpc-api.md#getaccountinfo) for field details\) * `object` - account info JSON object \(see [getAccountInfo](jsonrpc-api.md#getaccountinfo) for field details\)
```bash ```bash
{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["8Rshv2oMkPu5E4opXTRyuyBeZBqQ4S477VG26wUTFxUM",{"executable":false,"lamports":1,"owner":[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"data":[1,1,1,0,0,0,0,0,0,0.23.0,0,0,0,0,0,0,50,48,49,56,45,49,50,45,50,52,84,50,51,58,53,57,58,48,48,90,235,233,39,152,15,44,117,176,41,89,100,86,45,61,2,44,251,46,212,37,35,118,163,189,247,84,27,235,178,62,55,89,0,0,0,0,50,0,0,0,0,0,0,0,235,233,39,152,15,44,117,176,41,89,100,86,45,61,2,44,251,46,212,37,35,118,163,189,247,84,27,235,178,62,45,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}],"subscription":0}} {"jsonrpc":"2.0","method":"programNotification","params":{{"result":["8Rshv2oMkPu5E4opXTRyuyBeZBqQ4S477VG26wUTFxUM",{"executable":false,"lamports":1,"owner":"9gZbPtbtHrs6hEWgd6MbVY9VPFtS5Z8xKtnYwA2NynHV","data":"4SZWhnbSt3njU4QHVgPrWeekz1BudU4ttmdr9ezmrL4X6XeLeL83xVAo6ZdxwU3oXgHNeF2q6tWZbnVnBXmvNyeLVEGt8ZQ4ZmgjHfVNCEwBtzh2aDrHgQSjBFLYAdmM3uwBhcm1EyHJLeUiFqpsoAUhn6Vphwrpf44dWRAGsAJZbzvVrUW9bfucpR7xudHHg2MxQ2CdqsfS3TfWUJY3vaf2A4AUNzfAmNPHBGi99nU2hYubGSVSPcpVPpdRWQkydgqasBmTosd"}],"subscription":0}}
``` ```
### programUnsubscribe ### programUnsubscribe

View File

@ -2012,7 +2012,7 @@ mod tests {
use solana_client::{ use solana_client::{
mock_rpc_client_request::SIGNATURE, mock_rpc_client_request::SIGNATURE,
rpc_request::RpcRequest, rpc_request::RpcRequest,
rpc_response::{Response, RpcResponseContext}, rpc_response::{Response, RpcAccount, RpcResponseContext},
}; };
use solana_sdk::{ use solana_sdk::{
account::Account, account::Account,
@ -2700,12 +2700,14 @@ mod tests {
let blockhash = Hash::default(); let blockhash = Hash::default();
let nonce_response = json!(Response { let nonce_response = json!(Response {
context: RpcResponseContext { slot: 1 }, context: RpcResponseContext { slot: 1 },
value: json!(Account::new_data( value: json!(RpcAccount::encode(
1, Account::new_data(
&NonceState::Initialized(NonceMeta::new(&config.keypair.pubkey()), blockhash), 1,
&system_program::ID, &NonceState::Initialized(NonceMeta::new(&config.keypair.pubkey()), blockhash),
) &system_program::ID,
.unwrap()), )
.unwrap()
)),
}); });
let mut mocks = HashMap::new(); let mut mocks = HashMap::new();
mocks.insert(RpcRequest::GetAccountInfo, nonce_response); mocks.insert(RpcRequest::GetAccountInfo, nonce_response);
@ -2726,12 +2728,14 @@ mod tests {
let blockhash = Hash::default(); let blockhash = Hash::default();
let nonce_authority_response = json!(Response { let nonce_authority_response = json!(Response {
context: RpcResponseContext { slot: 1 }, context: RpcResponseContext { slot: 1 },
value: json!(Account::new_data( value: json!(RpcAccount::encode(
1, Account::new_data(
&NonceState::Initialized(NonceMeta::new(&bob_pubkey), blockhash), 1,
&system_program::ID, &NonceState::Initialized(NonceMeta::new(&bob_pubkey), blockhash),
) &system_program::ID,
.unwrap()), )
.unwrap()
)),
}); });
let mut mocks = HashMap::new(); let mut mocks = HashMap::new();
mocks.insert(RpcRequest::GetAccountInfo, nonce_authority_response); mocks.insert(RpcRequest::GetAccountInfo, nonce_authority_response);

View File

@ -5,8 +5,9 @@ use crate::{
rpc_client_request::RpcClientRequest, rpc_client_request::RpcClientRequest,
rpc_request::RpcRequest, rpc_request::RpcRequest,
rpc_response::{ rpc_response::{
Response, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo, Response, RpcAccount, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo,
RpcLeaderSchedule, RpcResponse, RpcVersionInfo, RpcVoteAccountStatus, RpcEpochInfo, RpcKeyedAccount, RpcLeaderSchedule, RpcResponse, RpcVersionInfo,
RpcVoteAccountStatus,
}, },
}; };
use bincode::serialize; use bincode::serialize;
@ -578,9 +579,16 @@ impl RpcClient {
format!("AccountNotFound: pubkey={}", pubkey), format!("AccountNotFound: pubkey={}", pubkey),
)); ));
} }
let result = serde_json::from_value::<Response<Option<Account>>>(result_json)?; let Response {
trace!("Response account {:?} {:?}", pubkey, result); context,
Ok(result) value: rpc_account,
} = serde_json::from_value::<Response<Option<RpcAccount>>>(result_json)?;
trace!("Response account {:?} {:?}", pubkey, rpc_account);
let account = rpc_account.and_then(|rpc_account| rpc_account.decode().ok());
Ok(Response {
context,
value: account,
})
}) })
.map_err(|err| { .map_err(|err| {
io::Error::new( io::Error::new(
@ -675,8 +683,8 @@ impl RpcClient {
) )
})?; })?;
let accounts: Vec<(String, Account)> = let accounts: Vec<RpcKeyedAccount> =
serde_json::from_value::<Vec<(String, Account)>>(response).map_err(|err| { serde_json::from_value::<Vec<RpcKeyedAccount>>(response).map_err(|err| {
io::Error::new( io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
format!("GetProgramAccounts parse failure: {:?}", err), format!("GetProgramAccounts parse failure: {:?}", err),
@ -684,14 +692,14 @@ impl RpcClient {
})?; })?;
let mut pubkey_accounts: Vec<(Pubkey, Account)> = Vec::new(); let mut pubkey_accounts: Vec<(Pubkey, Account)> = Vec::new();
for (string, account) in accounts.into_iter() { for RpcKeyedAccount { pubkey, account } in accounts.into_iter() {
let pubkey = string.parse().map_err(|err| { let pubkey = pubkey.parse().map_err(|err| {
io::Error::new( io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
format!("GetProgramAccounts parse failure: {:?}", err), format!("GetProgramAccounts parse failure: {:?}", err),
) )
})?; })?;
pubkey_accounts.push((pubkey, account)); pubkey_accounts.push((pubkey, account.decode().unwrap()));
} }
Ok(pubkey_accounts) Ok(pubkey_accounts)
} }

View File

@ -1,3 +1,4 @@
use crate::rpc_request::RpcError;
use bincode::serialize; use bincode::serialize;
use jsonrpc_core::Result as JsonResult; use jsonrpc_core::Result as JsonResult;
use solana_sdk::{ use solana_sdk::{
@ -5,9 +6,10 @@ use solana_sdk::{
clock::{Epoch, Slot}, clock::{Epoch, Slot},
fee_calculator::FeeCalculator, fee_calculator::FeeCalculator,
message::MessageHeader, message::MessageHeader,
pubkey::Pubkey,
transaction::{Result, Transaction}, transaction::{Result, Transaction},
}; };
use std::{collections::HashMap, io, net::SocketAddr}; use std::{collections::HashMap, io, net::SocketAddr, str::FromStr};
pub type RpcResponseIn<T> = JsonResult<Response<T>>; pub type RpcResponseIn<T> = JsonResult<Response<T>>;
pub type RpcResponse<T> = io::Result<Response<T>>; pub type RpcResponse<T> = io::Result<Response<T>>;
@ -145,7 +147,45 @@ pub struct RpcBlockhashFeeCalculator {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RpcKeyedAccount { pub struct RpcKeyedAccount {
pub pubkey: String, pub pubkey: String,
pub account: Account, pub account: RpcAccount,
}
/// A duplicate representation of a Message for pretty JSON serialization
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcAccount {
pub lamports: u64,
pub data: String,
pub owner: String,
pub executable: bool,
pub rent_epoch: Epoch,
}
impl RpcAccount {
pub fn encode(account: Account) -> Self {
RpcAccount {
lamports: account.lamports,
data: bs58::encode(account.data.clone()).into_string(),
owner: account.owner.to_string(),
executable: account.executable,
rent_epoch: account.rent_epoch,
}
}
pub fn decode(&self) -> std::result::Result<Account, RpcError> {
Ok(Account {
lamports: self.lamports,
data: bs58::decode(self.data.clone()).into_vec().map_err(|_| {
RpcError::RpcRequestError("Could not parse encoded account data".to_string())
})?,
owner: Pubkey::from_str(&self.owner).map_err(|_| {
RpcError::RpcRequestError("Could not parse encoded account owner".to_string())
})?,
executable: self.executable,
rent_epoch: self.rent_epoch,
..Account::default()
})
}
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]

View File

@ -12,10 +12,10 @@ use bincode::serialize;
use jsonrpc_core::{Error, Metadata, Result}; use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use solana_client::rpc_response::{ use solana_client::rpc_response::{
Response, RpcBlockCommitment, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo, Response, RpcAccount, RpcBlockCommitment, RpcBlockhashFeeCalculator, RpcConfirmedBlock,
RpcEpochInfo, RpcKeyedAccount, RpcLeaderSchedule, RpcResponseContext, RpcSignatureConfirmation, RpcContactInfo, RpcEpochInfo, RpcKeyedAccount, RpcLeaderSchedule, RpcResponseContext,
RpcStorageTurn, RpcTransactionEncoding, RpcVersionInfo, RpcVoteAccountInfo, RpcSignatureConfirmation, RpcStorageTurn, RpcTransactionEncoding, RpcVersionInfo,
RpcVoteAccountStatus, RpcVoteAccountInfo, RpcVoteAccountStatus,
}; };
use solana_faucet::faucet::request_airdrop_transaction; use solana_faucet::faucet::request_airdrop_transaction;
use solana_ledger::{ use solana_ledger::{
@ -23,7 +23,6 @@ use solana_ledger::{
}; };
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_sdk::{ use solana_sdk::{
account::Account,
clock::{Slot, UnixTimestamp}, clock::{Slot, UnixTimestamp},
commitment_config::{CommitmentConfig, CommitmentLevel}, commitment_config::{CommitmentConfig, CommitmentLevel},
epoch_schedule::EpochSchedule, epoch_schedule::EpochSchedule,
@ -112,10 +111,10 @@ impl JsonRpcRequestProcessor {
&self, &self,
pubkey: Result<Pubkey>, pubkey: Result<Pubkey>,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<Account>> { ) -> RpcResponse<Option<RpcAccount>> {
let bank = &*self.bank(commitment); let bank = &*self.bank(commitment);
match pubkey { match pubkey {
Ok(key) => new_response(bank, bank.get_account(&key)), Ok(key) => new_response(bank, bank.get_account(&key).map(RpcAccount::encode)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -141,7 +140,7 @@ impl JsonRpcRequestProcessor {
.into_iter() .into_iter()
.map(|(pubkey, account)| RpcKeyedAccount { .map(|(pubkey, account)| RpcKeyedAccount {
pubkey: pubkey.to_string(), pubkey: pubkey.to_string(),
account, account: RpcAccount::encode(account),
}) })
.collect()) .collect())
} }
@ -307,10 +306,14 @@ impl JsonRpcRequestProcessor {
Ok(self.bank(commitment).slots_per_segment()) Ok(self.bank(commitment).slots_per_segment())
} }
fn get_storage_pubkeys_for_slot(&self, slot: Slot) -> Result<Vec<Pubkey>> { fn get_storage_pubkeys_for_slot(&self, slot: Slot) -> Result<Vec<String>> {
Ok(self let pubkeys: Vec<String> = self
.storage_state .storage_state
.get_pubkeys_for_slot(slot, &self.bank_forks)) .get_pubkeys_for_slot(slot, &self.bank_forks)
.iter()
.map(|pubkey| pubkey.to_string())
.collect();
Ok(pubkeys)
} }
pub fn validator_exit(&self) -> Result<bool> { pub fn validator_exit(&self) -> Result<bool> {
@ -412,7 +415,7 @@ pub trait RpcSol {
meta: Self::Metadata, meta: Self::Metadata,
pubkey_str: String, pubkey_str: String,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<Account>>; ) -> RpcResponse<Option<RpcAccount>>;
#[rpc(meta, name = "getProgramAccounts")] #[rpc(meta, name = "getProgramAccounts")]
fn get_program_accounts( fn get_program_accounts(
@ -548,7 +551,7 @@ pub trait RpcSol {
) -> Result<u64>; ) -> Result<u64>;
#[rpc(meta, name = "getStoragePubkeysForSlot")] #[rpc(meta, name = "getStoragePubkeysForSlot")]
fn get_storage_pubkeys_for_slot(&self, meta: Self::Metadata, slot: u64) -> Result<Vec<Pubkey>>; fn get_storage_pubkeys_for_slot(&self, meta: Self::Metadata, slot: u64) -> Result<Vec<String>>;
#[rpc(meta, name = "validatorExit")] #[rpc(meta, name = "validatorExit")]
fn validator_exit(&self, meta: Self::Metadata) -> Result<bool>; fn validator_exit(&self, meta: Self::Metadata) -> Result<bool>;
@ -618,7 +621,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata, meta: Self::Metadata,
pubkey_str: String, pubkey_str: String,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<Account>> { ) -> RpcResponse<Option<RpcAccount>> {
debug!("get_account_info rpc request received: {:?}", pubkey_str); debug!("get_account_info rpc request received: {:?}", pubkey_str);
let pubkey = verify_pubkey(pubkey_str); let pubkey = verify_pubkey(pubkey_str);
meta.request_processor meta.request_processor
@ -1024,7 +1027,7 @@ impl RpcSol for RpcSolImpl {
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
slot: Slot, slot: Slot,
) -> Result<Vec<Pubkey>> { ) -> Result<Vec<String>> {
meta.request_processor meta.request_processor
.read() .read()
.unwrap() .unwrap()
@ -1547,9 +1550,9 @@ pub mod tests {
"result": { "result": {
"context":{"slot":0}, "context":{"slot":0},
"value":{ "value":{
"owner": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "owner": "11111111111111111111111111111111",
"lamports": 20, "lamports": 20,
"data": [], "data": "",
"executable": false, "executable": false,
"rentEpoch": 0 "rentEpoch": 0
}, },
@ -1589,9 +1592,9 @@ pub mod tests {
{{ {{
"pubkey": "{}", "pubkey": "{}",
"account": {{ "account": {{
"owner": {:?}, "owner": "{}",
"lamports": 20, "lamports": 20,
"data": [], "data": "",
"executable": false, "executable": false,
"rentEpoch": 0 "rentEpoch": 0
}} }}
@ -1600,7 +1603,7 @@ pub mod tests {
"id":1}} "id":1}}
"#, "#,
bob.pubkey(), bob.pubkey(),
new_program_id.as_ref() new_program_id
); );
let expected: Response = let expected: Response =
serde_json::from_str(&expected).expect("expected response deserialization"); serde_json::from_str(&expected).expect("expected response deserialization");

View File

@ -4,8 +4,8 @@ use crate::rpc_subscriptions::{Confirmations, RpcSubscriptions, SlotInfo};
use jsonrpc_core::{Error, ErrorCode, Result}; use jsonrpc_core::{Error, ErrorCode, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use jsonrpc_pubsub::{typed::Subscriber, Session, SubscriptionId}; use jsonrpc_pubsub::{typed::Subscriber, Session, SubscriptionId};
use solana_client::rpc_response::RpcKeyedAccount; use solana_client::rpc_response::{RpcAccount, RpcKeyedAccount};
use solana_sdk::{account::Account, pubkey::Pubkey, signature::Signature, transaction}; use solana_sdk::{pubkey::Pubkey, signature::Signature, transaction};
use std::sync::{atomic, Arc}; use std::sync::{atomic, Arc};
// Suppress needless_return due to // Suppress needless_return due to
@ -26,7 +26,7 @@ pub trait RpcSolPubSub {
fn account_subscribe( fn account_subscribe(
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
subscriber: Subscriber<Account>, subscriber: Subscriber<RpcAccount>,
pubkey_str: String, pubkey_str: String,
confirmations: Option<Confirmations>, confirmations: Option<Confirmations>,
); );
@ -133,7 +133,7 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
fn account_subscribe( fn account_subscribe(
&self, &self,
_meta: Self::Metadata, _meta: Self::Metadata,
subscriber: Subscriber<Account>, subscriber: Subscriber<RpcAccount>,
pubkey_str: String, pubkey_str: String,
confirmations: Option<Confirmations>, confirmations: Option<Confirmations>,
) { ) {
@ -467,9 +467,9 @@ mod tests {
"method": "accountNotification", "method": "accountNotification",
"params": { "params": {
"result": { "result": {
"owner": budget_program_id, "owner": budget_program_id.to_string(),
"lamports": 51, "lamports": 51,
"data": expected_data, "data": bs58::encode(expected_data).into_string(),
"executable": false, "executable": false,
"rentEpoch": 1, "rentEpoch": 1,
}, },
@ -614,9 +614,9 @@ mod tests {
"method": "accountNotification", "method": "accountNotification",
"params": { "params": {
"result": { "result": {
"owner": system_program::id(), "owner": system_program::id().to_string(),
"lamports": 100, "lamports": 100,
"data": [], "data": "",
"executable": false, "executable": false,
"rentEpoch": 1, "rentEpoch": 1,
}, },

View File

@ -4,7 +4,7 @@ use core::hash::Hash;
use jsonrpc_core::futures::Future; use jsonrpc_core::futures::Future;
use jsonrpc_pubsub::{typed::Sink, SubscriptionId}; use jsonrpc_pubsub::{typed::Sink, SubscriptionId};
use serde::Serialize; use serde::Serialize;
use solana_client::rpc_response::RpcKeyedAccount; use solana_client::rpc_response::{RpcAccount, RpcKeyedAccount};
use solana_ledger::bank_forks::BankForks; use solana_ledger::bank_forks::BankForks;
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_sdk::{ use solana_sdk::{
@ -26,7 +26,7 @@ pub struct SlotInfo {
} }
type RpcAccountSubscriptions = type RpcAccountSubscriptions =
RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<Account>, Confirmations)>>>; RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<RpcAccount>, Confirmations)>>>;
type RpcProgramSubscriptions = type RpcProgramSubscriptions =
RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<RpcKeyedAccount>, Confirmations)>>>; RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<RpcKeyedAccount>, Confirmations)>>>;
type RpcSignatureSubscriptions = RwLock< type RpcSignatureSubscriptions = RwLock<
@ -130,13 +130,10 @@ fn check_confirmations_and_notify<K, S, F, N, X>(
} }
} }
fn notify_account<S>(result: Option<(S, Slot)>, sink: &Sink<S>, root: Slot) fn notify_account(result: Option<(Account, Slot)>, sink: &Sink<RpcAccount>, root: Slot) {
where
S: Clone + Serialize,
{
if let Some((account, fork)) = result { if let Some((account, fork)) = result {
if fork >= root { if fork >= root {
sink.notify(Ok(account)).wait().unwrap(); sink.notify(Ok(RpcAccount::encode(account))).wait().unwrap();
} }
} }
} }
@ -154,7 +151,7 @@ fn notify_program(accounts: Vec<(Pubkey, Account)>, sink: &Sink<RpcKeyedAccount>
for (pubkey, account) in accounts.iter() { for (pubkey, account) in accounts.iter() {
sink.notify(Ok(RpcKeyedAccount { sink.notify(Ok(RpcKeyedAccount {
pubkey: pubkey.to_string(), pubkey: pubkey.to_string(),
account: account.clone(), account: RpcAccount::encode(account.clone()),
})) }))
.wait() .wait()
.unwrap(); .unwrap();
@ -237,7 +234,7 @@ impl RpcSubscriptions {
pubkey: &Pubkey, pubkey: &Pubkey,
confirmations: Option<Confirmations>, confirmations: Option<Confirmations>,
sub_id: &SubscriptionId, sub_id: &SubscriptionId,
sink: &Sink<Account>, sink: &Sink<RpcAccount>,
) { ) {
let mut subscriptions = self.account_subscriptions.write().unwrap(); let mut subscriptions = self.account_subscriptions.write().unwrap();
add_subscription(&mut subscriptions, pubkey, confirmations, sub_id, sink); add_subscription(&mut subscriptions, pubkey, confirmations, sub_id, sink);
@ -384,7 +381,7 @@ mod tests {
let string = transport_receiver.poll(); let string = transport_receiver.poll();
if let Async::Ready(Some(response)) = string.unwrap() { if let Async::Ready(Some(response)) = string.unwrap() {
let expected = format!( let expected = format!(
r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rentEpoch":1}},"subscription":0}}}}"# r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"data":"1111111111111111","executable":false,"lamports":1,"owner":"Budget1111111111111111111111111111111111111","rentEpoch":1}},"subscription":0}}}}"#
); );
assert_eq!(expected, response); assert_eq!(expected, response);
} }
@ -441,7 +438,7 @@ mod tests {
let string = transport_receiver.poll(); let string = transport_receiver.poll();
if let Async::Ready(Some(response)) = string.unwrap() { if let Async::Ready(Some(response)) = string.unwrap() {
let expected = format!( let expected = format!(
r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":{{"account":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rentEpoch":1}},"pubkey":"{:?}"}},"subscription":0}}}}"#, r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":{{"account":{{"data":"1111111111111111","executable":false,"lamports":1,"owner":"Budget1111111111111111111111111111111111111","rentEpoch":1}},"pubkey":"{:?}"}},"subscription":0}}}}"#,
alice.pubkey() alice.pubkey()
); );
assert_eq!(expected, response); assert_eq!(expected, response);

View File

@ -1,6 +1,7 @@
//! configuration for network inflation //! configuration for network inflation
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug, Copy)] #[derive(Serialize, Deserialize, PartialEq, Clone, Debug, Copy)]
#[serde(rename_all = "camelCase")]
pub struct Inflation { pub struct Inflation {
/// Initial inflation percentage, from time=0 /// Initial inflation percentage, from time=0
pub initial: f64, pub initial: f64,