Fix Rpc inconsistencies (#7826)
* Update rpc account format: remove byte arrays * Base58-encode pubkeys in getStoragePubkeysForSlot * Update docs
This commit is contained in:
parent
8ffccfbaff
commit
da165d6943
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue