-
Notifications
You must be signed in to change notification settings - Fork 461
Add rpc processor trait #5541
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
base: master
Are you sure you want to change the base?
Add rpc processor trait #5541
Conversation
I'll take a look at this as well, but requested additional reviews from other RPC people. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you made a wrapper trait that holds on one of two JsonRpcRequestProcessor
instances (as base
) and then sort of proxies calls into them.
Would it instead be possible to generate the trait from the existing impl of JsonRpcRequestProcessor
, then make two implementors (LiveJsonRpcRequestProcessor
and TestJsonRpcRequestProcessor
) with the exact same interface, but different implementations and private methods? That way you wouldn't have to do the whole ‘cast through Any
’ thing to convince Hyper that it's dealing with a usable request processor.

}) | ||
.await | ||
.expect("Failed to spawn blocking task") | ||
fn genesis_creation_time(&self) -> UnixTimestamp { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, consider a method like this one. This impl is identical between TestJsonRpcRequestProcessor
and LiveJsonRpcRequestProcessor
. Could we instead make it the default implementation on the trait itself?
The annoying thing is that traits can't have properties, so you need to turn every property into a getter.
pub trait JsonRpcRequestProcessorForResult<T>: JsonRpcRequestProcessorClone + Send + Sync {
// An abstract getter for `blockstore`
fn blockstore(&self) -> &Arc<Blockstore>;
// A concrete implementation for `check_blockstore_root()` that uses that getter: `blockstore()`.
fn check_blockstore_root(
&self,
result: &std::result::Result<T, BlockstoreError>,
slot: Slot,
) -> Result<()> {
if let Err(err) = result {
debug!(
"check_blockstore_root, slot: {:?}, max root: {:?}, err: {:?}",
slot,
self.blockstore().max_root(),
err
);
if slot >= self.blockstore().max_root() {
return Err(RpcCustomError::BlockNotAvailable { slot }.into());
}
if self.blockstore().is_skipped(slot) {
return Err(RpcCustomError::SlotSkipped { slot }.into());
}
}
Ok(())
}
}
// Now the only code you have to duplicate is the getters.
#[async_trait]
impl<T> JsonRpcRequestProcessorForResult<T> for LiveJsonRpcRequestProcessor {
fn blockstore(&self) -> &Arc<Blockstore> {
&self.blockstore
}
}
#[async_trait]
impl<T> JsonRpcRequestProcessorForResult<T> for TestJsonRpcRequestProcessor {
fn blockstore(&self) -> &Arc<Blockstore> {
&self.blockstore
}
}
Note the annoying thing you have to do (ie. create multiple traits for each type parameter.
Does that work and cut down on copypasta?
Problem
Recent dev feedback has been surrounding the local testing experience, requesting to update our testing environment to mimic the functionality of Anvil, which would include additional methods that all work dynamically while the validator is running, like updating account state, cloning accounts from multiple clusters, manipulating token balances in accounts, slot warping, etc.
To be able to safely add these methods without effecting security of mainnet validators, we need to create an RPC processor trait & have two different processor types.
Summary of Changes
This PR covers creating the new trait and adding the ability to run the test validator with an
-- enable-test-features
flag that will use the new test validator RPC processor type, while ensuring the mainnet validators will always run with the standard RPC processor type and not have the ability to change processor types.The
TestValidatorJsonRpcRequestProcessor
derefs theJsonRpcRequestProcessor
to access methods and fields fromJsonRpcRequestProcessor
& the plan is to then add the additional test validator functionality onto theTestValidatorJsonRpcRequestProcessor
.All public methods on the
JsonRpcRequestProcessor
type were moved to theRpcRequestProcessorTrait
, while private methods remained just on theJsonRpcRequestProcessor
.For more context: #5852
Fixes #