From bb8c94ad2c80a3c2b6e6a7c8353164b73ee54c93 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 20 Sep 2018 13:20:37 -0700 Subject: [PATCH] Add getAccount JSON RPC request --- doc/json-rpc.md | 27 ++++++++++++++++++++++++++- src/rpc.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/doc/json-rpc.md b/doc/json-rpc.md index bdd2bff07..4ccc1f043 100644 --- a/doc/json-rpc.md +++ b/doc/json-rpc.md @@ -8,7 +8,7 @@ To interact with a Solana node inside a JavaScript application, use the [solana- RPC Endpoint --- -**Default port:** 8899 +**Default port:** 8899 eg. http://localhost:8899, http://192.168.1.88:8899 Methods @@ -17,6 +17,7 @@ Methods * [confirmTransaction](#confirmtransaction) * [getAddress](#getaddress) * [getBalance](#getbalance) +* [getAccount](#getaccount) * [getLastId](#getlastid) * [getTransactionCount](#gettransactioncount) * [requestAirdrop](#requestairdrop) @@ -96,6 +97,30 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, " --- +### getAccount +Returns all information associated with the account of provided Pubkey + +##### Parameters: +* `string` - Pubkey of account to query, as base-58 encoded string + +##### Results: +The result field will be a JSON object with the following sub fields: + +* `tokens`, number of tokens assigned to this account, as a signed 64-bit integer +* `contract_id`, array of 32 bytes representing the program this account has been assigned to +* `userdata`, array of bytes representing any userdata associated with the account + +##### Example: +```bash +// Request +curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccount", "params":["FVxxngPx368XvMCoeskdd6U8cZJFsfa1BEtGWqyAxRj4"]}' http://localhost:8899 + +// Result +{"jsonrpc":"2.0","result":{"contract_id":[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],"tokens":1,"userdata":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,20,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} +``` + +--- + ### getLastId Returns the last entry ID from the ledger diff --git a/src/rpc.rs b/src/rpc.rs index 375f7790c..1c0c2b806 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -1,6 +1,6 @@ //! The `rpc` module implements the Solana RPC interface. -use bank::Bank; +use bank::{Account, Bank}; use bincode::deserialize; use bs58; use jsonrpc_core::*; @@ -102,6 +102,9 @@ build_rpc_trait! { #[rpc(meta, name = "getTransactionCount")] fn get_transaction_count(&self, Self::Metadata) -> Result; + #[rpc(meta, name = "getAccount")] + fn get_account(&self, Self::Metadata, String) -> Result; + #[rpc(meta, name= "requestAirdrop")] fn request_airdrop(&self, Self::Metadata, String, u64) -> Result; @@ -143,6 +146,16 @@ impl RpcSol for RpcSolImpl { fn get_transaction_count(&self, meta: Self::Metadata) -> Result { meta.request_processor.get_transaction_count() } + fn get_account(&self, meta: Self::Metadata, id: String) -> Result { + let pubkey_vec = bs58::decode(id) + .into_vec() + .map_err(|_| Error::invalid_request())?; + if pubkey_vec.len() != mem::size_of::() { + return Err(Error::invalid_request()); + } + let pubkey = Pubkey::new(&pubkey_vec); + meta.request_processor.get_account(pubkey) + } fn request_airdrop(&self, meta: Self::Metadata, id: String, tokens: u64) -> Result { let pubkey_vec = bs58::decode(id) .into_vec() @@ -212,6 +225,11 @@ impl JsonRpcRequestProcessor { fn get_transaction_count(&self) -> Result { Ok(self.bank.transaction_count() as u64) } + fn get_account(&self, pubkey: Pubkey) -> Result { + self.bank + .get_account(&pubkey) + .ok_or(Error::invalid_request()) + } } #[cfg(test)] @@ -270,6 +288,28 @@ mod tests { let result: Response = serde_json::from_str(&res.expect("actual response")) .expect("actual response deserialization"); assert_eq!(expected, result); + + let req = format!( + r#"{{"jsonrpc":"2.0","id":1,"method":"getAccount","params":["{}"]}}"#, + bob_pubkey + ); + + let res = io.handle_request_sync(&req, meta.clone()); + let expected = r#"{ + "jsonrpc":"2.0", + "result":{ + "contract_id": [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], + "tokens": 20, + "userdata": [] + }, + "id":1} + "#; + let expected: Response = + serde_json::from_str(&expected).expect("expected response deserialization"); + + let result: Response = serde_json::from_str(&res.expect("actual response")) + .expect("actual response deserialization"); + assert_eq!(expected, result); } #[test] fn test_rpc_request_bad_parameter_type() {