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

Migrate Forest to jsonrpsee crate #3943

Merged
merged 71 commits into from
Feb 20, 2024
Merged

Migrate Forest to jsonrpsee crate #3943

merged 71 commits into from
Feb 20, 2024

Conversation

elmattic
Copy link
Contributor

@elmattic elmattic commented Feb 6, 2024

Summary of changes

Changes introduced in this pull request:

  • Migrate to jsonrpsee server
$ ./forest-tool api compare --lotus /ip4/127.0.0.1/tcp/1234/http --forest /ip4/127.0.0.1/tcp/2345/http forest_snapshot_calibnet_2024-02-05_height_1326491.forest.car.zst

| RPC Method                                     | Forest              | Lotus               |
|------------------------------------------------|---------------------|---------------------|
| Filecoin.BeaconGetEntry                        | Valid               | Valid               |
| Filecoin.ChainGetBlock                         | Valid               | Valid               |
| Filecoin.ChainGetBlockMessages (61)            | Valid               | Valid               |
| Filecoin.ChainGetGenesis                       | Valid               | Valid               |
| Filecoin.ChainGetMessage (2)                   | Valid               | Valid               |
| Filecoin.ChainGetMessagesInTipset (20)         | Valid               | Valid               |
| Filecoin.ChainGetParentMessages (61)           | Valid               | Valid               |
| Filecoin.ChainGetParentReceipts (61)           | Valid               | Valid               |
| Filecoin.ChainGetTipSet                        | Valid               | Valid               |
| Filecoin.ChainGetTipSetByHeight                | Valid               | Valid               |
| Filecoin.ChainHasObj                           | Valid               | Valid               |
| Filecoin.ChainHead                             | Valid               | Valid               |
| Filecoin.ChainReadObj                          | Valid               | Valid               |
| Filecoin.EthAccounts                           | Valid               | Valid               |
| Filecoin.EthBlockNumber                        | Valid               | Valid               |
| Filecoin.EthChainId                            | Valid               | Valid               |
| Filecoin.EthGasPrice                           | Valid               | Valid               |
| Filecoin.EthGetBalance (4)                     | Valid               | Valid               |
| Filecoin.MinerGetBaseInfo (7)                  | InvalidResponse     | Valid               |
| Filecoin.MinerGetBaseInfo (54)                 | Valid               | Valid               |
| Filecoin.MpoolGetNonce (2)                     | Valid               | Valid               |
| Filecoin.MpoolPending                          | Valid               | Valid               |
| Filecoin.MsigGetAvailableBalance               | Valid               | Valid               |
| Filecoin.MsigGetPending                        | Valid               | Valid               |
| Filecoin.NetAddrsListen                        | Valid               | Valid               |
| Filecoin.NetPeers                              | Valid               | Valid               |
| Filecoin.Session                               | Valid               | Valid               |
| Filecoin.StartTime                             | Valid               | Valid               |
| Filecoin.StateAccountKey (4)                   | Valid               | Valid               |
| Filecoin.StateCall (7)                         | Valid               | Valid               |
| Filecoin.StateCirculatingSupply (20)           | Valid               | Valid               |
| Filecoin.StateGetActor                         | Valid               | Valid               |
| Filecoin.StateGetRandomnessFromBeacon          | Valid               | Valid               |
| Filecoin.StateGetRandomnessFromTickets         | Valid               | Valid               |
| Filecoin.StateListMessages (2)                 | InternalServerError | InternalServerError |
| Filecoin.StateListMessages (4)                 | Valid               | Valid               |
| Filecoin.StateListMiners                       | Valid               | Valid               |
| Filecoin.StateLookupID (4)                     | Valid               | Valid               |
| Filecoin.StateMinerActiveSectors (62)          | Valid               | Valid               |
| Filecoin.StateMinerDeadlines (61)              | Valid               | Valid               |
| Filecoin.StateMinerFaults (61)                 | Valid               | Valid               |
| Filecoin.StateMinerInfo (2)                    | InvalidResponse     | Valid               |
| Filecoin.StateMinerInfo (59)                   | Valid               | Valid               |
| Filecoin.StateMinerPower (61)                  | Valid               | Valid               |
| Filecoin.StateMinerProvingDeadline (61)        | Valid               | Valid               |
| Filecoin.StateMinerRecoveries (61)             | Valid               | Valid               |
| Filecoin.StateMinerSectorCount (61)            | Valid               | Valid               |
| Filecoin.StateNetworkName                      | Valid               | Valid               |
| Filecoin.StateNetworkVersion                   | Valid               | Valid               |
| Filecoin.StateReadState (2)                    | Valid               | Valid               |
| Filecoin.StateSearchMsg                        | InternalServerError | InternalServerError |
| Filecoin.StateSearchMsg                        | Valid               | InternalServerError |
| Filecoin.StateSearchMsgLimited                 | InternalServerError | Valid               |
| Filecoin.StateSearchMsgLimited                 | InvalidResponse     | Valid               |
| Filecoin.StateSectorGetInfo                    | Valid               | Valid               |
| Filecoin.StateVMCirculatingSupplyInternal (20) | Valid               | Valid               |
| Filecoin.StateVerifiedClientStatus (2)         | Valid               | Valid               |
| Filecoin.StateWaitMsg                          | Timeout             | Timeout             |
| Filecoin.StateWaitMsg                          | Valid               | Timeout             |
| Filecoin.Version                               | Valid               | Valid               |
| Filecoin.WalletBalance                         | Valid               | Valid               |
| Filecoin.WalletValidateAddress                 | Valid               | Valid               |
| Filecoin.WalletVerify                          | Valid               | Valid               |

Websocket transport flag should work as well:

$ ./forest-tool api compare --ws --lotus /ip4/127.0.0.1/tcp/1234/ws --forest /ip4/127.0.0.1/tcp/2345/ws forest_snapshot_calibnet_2024-02-14_height_1352592.forest.car.zst

Reference issue to close (if applicable)

Closes

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

@elmattic elmattic requested a review from ruseinov February 16, 2024 09:50
@elmattic elmattic mentioned this pull request Feb 16, 2024
3 tasks
Cargo.toml Show resolved Hide resolved
data: Data<RPCState<DB>>,
Params(params): Params<AuthNewParams>,
params: Params<'_>,
data: Arc<Arc<RPCState<DB>>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why we need Arc<Arc<T>> here - could you justify or remove?

Copy link
Contributor Author

@elmattic elmattic Feb 16, 2024

Choose a reason for hiding this comment

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

The first Arc is needed to share the state between two RPC modules.

let state = Arc::new(state);

We only have one module now, but to implement specific pubsub code, we will need to implement a dedicated RpcModule.
In the context of async methods, jsonrpsee creates a second Arc around the Context type:

pub struct RpcModule<Context> {
    ctx: Arc<Context, Global>,
    methods: Methods,
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Quick question: do we really need to share the state between modules?
And if so - perhaps the best approach is to type alias this Arc<Arc stuff away and keep it in one place instead of declaring it on every method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because all methods in a module need access to the state.

In our case, we will have to call chain_api::chain_notify to get the subscriber:

async fn chain_notify<DB: Blockstore>(
     data: Arc<RPCState<DB>>,
 ) -> Result<Subscriber<HeadChange>, JsonRpseeError> {
     let head_change = data.chain_store.publisher().subscribe();

     Ok(head_change)
 }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hum, there's only one Arc 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.

Ah I see why, ignore my comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's the resolution here? this is the only thing blocking an approval from me I think

Copy link
Contributor Author

@elmattic elmattic Feb 19, 2024

Choose a reason for hiding this comment

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

I think the double Arc<Arc<T>> is ok for now (I've hidden the ugliness using the Data type alias). This should resolve at the jsonrpsee crate level. Maybe with something like:

pub fn from_arc(ctx: Arc<Context>) -> Self {
  Self { ctx, methods: Default::default() }
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm grumpy about this, but if there's truly no other way then fine

Copy link
Contributor Author

@elmattic elmattic Feb 19, 2024

Choose a reason for hiding this comment

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

My from_arc works and I can remove one Arc level: pub type Data<T> = Arc<T>;

This will require change in upstream repository though.

src/rpc/auth_layer.rs Outdated Show resolved Hide resolved
src/rpc/error.rs Show resolved Hide resolved
src/rpc/mod.rs Outdated Show resolved Hide resolved
src/rpc/mod.rs Show resolved Hide resolved
src/rpc_api/data_types.rs Show resolved Hide resolved
@ruseinov
Copy link
Contributor

Seems good apart from two nits already mentioned by @aatifsyed.

Perhaps the error codes could be improved, so that we at least have a way of knowing which error type was returned.
And the double Arc thing has to be either avoided or type aliased if unavoidable.

@elmattic
Copy link
Contributor Author

Perhaps the error codes could be improved, so that we at least have a way of knowing which error type was returned.

Yes, will do. Error codes could be much more precise.

And we don't always validate params; for example, in eth_chain_id; if we send incorrect params, Lotus answers with:

    JsonRpcError {
        code: 500,
        message: "{\"jsonrpc\":\"2.0\",\"id\":0,\"error\":{\"code\":-32602,\"message\":\"wrong param count (method 'Filecoin.EthChainId'): 2 != 0\"}}\n",
    },

While for Forest, it's valid. This can be addressed in a follow-up PR, though.

src/rpc/chain_api.rs Outdated Show resolved Hide resolved
src/rpc/chain_api.rs Outdated Show resolved Hide resolved
src/rpc/chain_api.rs Outdated Show resolved Hide resolved
elmattic and others added 4 commits February 20, 2024 10:20
Co-authored-by: David Himmelstrup <david.himmelstrup@chainsafe.io>
Co-authored-by: David Himmelstrup <david.himmelstrup@chainsafe.io>
Co-authored-by: David Himmelstrup <david.himmelstrup@chainsafe.io>
@elmattic elmattic enabled auto-merge February 20, 2024 09:42
src/rpc/node_api.rs Outdated Show resolved Hide resolved
@elmattic elmattic added this pull request to the merge queue Feb 20, 2024
Merged via the queue into main with commit 4fa9103 Feb 20, 2024
27 checks passed
@elmattic elmattic deleted the elmattic/jsonrpsee-server branch February 20, 2024 11:34
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.

5 participants