Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solana JSON-RPC api #960

Merged
merged 13 commits into from
Aug 18, 2018
Merged

Conversation

CriesofCarrots
Copy link
Contributor

This implements a preliminary JSON-RPC api infra, toward #702
It is currently built as a separate service (à la drone), but could be integrated into FullNode deployment instead.

Right now, the api just emulates the current wallet functionality plus several thin client functions. (0.9.0 JSON RPC Node Service step #1)

It uses a very janky method of pulling a client keypair to generate a transaction, to be rewritten as soon as integration with web-wallet progresses (in-wallet signatures).

(Incidentally, this module exposes a lot of work that needs to be done on the thin client module, including reworking of transfers to accommodate web-wallet signatures, and request timeouts. Will follow up with new issues.)

@CriesofCarrots
Copy link
Contributor Author

Parity JSON-RPC has an active issue to update its hyper crate dependency (paritytech/jsonrpc#298), which should alleviate the cargo audit vulnerability.

@garious
Copy link
Contributor

garious commented Aug 13, 2018

I was thinking this would be implemented within Fullnode and may render the RPU obsolete rather than building on top of it. I'd call it JsonRpcService.

@CriesofCarrots CriesofCarrots added the work in progress This isn't quite right yet label Aug 14, 2018
@CriesofCarrots CriesofCarrots removed the work in progress This isn't quite right yet label Aug 15, 2018
Copy link
Contributor

@garious garious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might find it helpful to run cargo cov on this. I think you'd see a lack of code coverage on cases that'd be terribly boring to write tests for, and that to up that coverage, you might find it easier to remove those cases than to write those tests!

src/fullnode.rs Outdated
@@ -54,6 +55,7 @@ impl Fullnode {
keypair: Keypair,
network_entry_for_validator: Option<SocketAddr>,
sigverify_disabled: bool,
json_rpc_enabled: bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the RPU, I'd prefer this always be enabled. If there's some port conflict, can we resolve that elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! It wasn't really a port-conflict issue, but a thread blocking issue.

src/rpc.rs Outdated
pub request_processor: Option<JsonRpcRequestProcessor>,
}
impl Metadata for Meta {}
impl Default for Meta {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does some library require we implement Default? If not, it'd be better to get rid of that Option<> and pass the request processor into a Meta constructor. Then you'd be able to get rid of all those unwrap() calls on request_processor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version of jsonrpc on crates.io requires Default for Metadata, but that has been fixed in more recent commits. I have changed the dependency to pull from github for now.

src/rpc.rs Outdated
fn confirm_transaction(&self, meta: Self::Metadata, id: String) -> Result<bool> {
let signature_vec = bs58::decode(id)
.into_vec()
.expect("base58-encoded public key");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use expect() or unwrap() here because that'd cause this thread to shut down if someone sent us bad input. Looks like it should be Err(Error::invalid_request()). Also, the string is wrong - it's not a public key.

src/rpc.rs Outdated
pub trait RpcSol {
type Metadata;

#[rpc(meta, name = "solana_confirmTransaction")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pity to have that solana_ prefix everywhere. What happens if we got rid of that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing bad. I will do that. We might want to use prefixes at some point to differentiate method types, but there's no reason to clutter it up with an meaningless one now.

src/rpc.rs Outdated
.expect("base58-encoded public key");

if signature_vec.len() != mem::size_of::<Signature>() {
Err(Error::invalid_request())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use early returns to handle edge cases, so that the main case don't need to be nested under else. The value-add here is more obvious when there are multiple edge cases, but we should do it here too to keep the codebase consistent.

src/rpc.rs Outdated
} else {
let signature = Signature::new(&signature_vec);
let req = JsonRpcRequest::GetSignature { signature };
let resp = meta.request_processor.unwrap().process_request(req);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling process_request here forces unnecessary branches below to decode the response. Since we already know this is a "GetSignature" request, I'd expect this code to call a get_signature method that returns a Result<SignatureStatus>. If we're going to do a match on the result, it should only be to convert an internal type to its JSON RPC equivalent. The Some(_) => Err case is the red flag here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nice. That's a much better method. Will build it out, thanks!

@CriesofCarrots CriesofCarrots force-pushed the rpc-api branch 4 times, most recently from bdf7d6a to 0f68c84 Compare August 15, 2018 19:06
@CriesofCarrots
Copy link
Contributor Author

CriesofCarrots commented Aug 15, 2018

@mvines , is there a way to temporarily ignore the cargo audit error for smallvec until the jsonrpc crate is updated?

...I think the large-network test timeout is unrelated to this PR; looks like the tip of master has the same issue.

@mvines
Copy link
Member

mvines commented Aug 15, 2018

Try this:

--- a/ci/test-stable.sh
+++ b/ci/test-stable.sh
@@ -23,4 +23,4 @@ echo --- ci/localnet-sanity.sh
   USE_INSTALL=1 ci/localnet-sanity.sh
 )
 
-_ ci/audit.sh
+_ ci/audit.sh || true

with an issue filed to revert of course

Copy link
Member

@mvines mvines left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

src/fullnode.rs Outdated
@@ -190,7 +191,7 @@ impl Fullnode {
let tick_duration = None;
// TODO: To light up PoH, uncomment the following line:
//let tick_duration = Some(Duration::from_millis(1000));

// let node_info = node.data.clone();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove?

src/rpc.rs Outdated
@@ -0,0 +1,278 @@
//! The `rpc` module implements the Solana rpc interface.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "... Solana RPC interface."

@CriesofCarrots CriesofCarrots force-pushed the rpc-api branch 9 times, most recently from 0396807 to 4daa494 Compare August 17, 2018 21:47
@CriesofCarrots
Copy link
Contributor Author

Woot! #996 allows this to pass the large-network test, so finally landing this.

@CriesofCarrots CriesofCarrots merged commit 1bf15ae into solana-labs:master Aug 18, 2018
vkomenda pushed a commit to vkomenda/solana that referenced this pull request Aug 29, 2021
solana-labs#1116)

* Added validator stake account list storage, deprecated old tests

* Added join and leave stake pool instructions, error messages refactoring

* Stake pool tests refactoring, tests for join and leave pool added

* Added validator stake account creation instruction, join/leave pool instructions renamed, version field added

* Formatting fixes

* Added update list/pool instructions (no tests yet), updated deposit instruction logic, claim instruction removed, refactoring

* Updated deposit logic and tests, updated withdraw logic and added tests, refactoring

* Stake pool CLI updated to work with new deposit/withdraw instructions, claim usage removed

* Added validator stake account management and balance update commands to the stake pool CLI, updated dependency versions, updated devnet program address

* Merge conflicts fixed

* Removed deprecated tests

* Fixes for review comments

* Additional program id checks across the code

* Formatting errors fixed

* Changed minimum stake balance in CLI, removed deprecated tests, removed check for stake history id

* Added TODO for stake account warmup status check

* Cargo.lock conflict fix

* Formatting fixed

* Update Cargo lock file for CI

* Pin themis version of subtle

Co-authored-by: Yuriy Savchenko <[email protected]>
jeffwashington added a commit to jeffwashington/solana that referenced this pull request Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants