Skip to content

eth_pubsub support #103

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

Merged
merged 42 commits into from
Sep 28, 2020
Merged

Conversation

tgmichel
Copy link
Contributor

@tgmichel tgmichel commented Aug 20, 2020

This PR add support for subscription RPC calls - eth_subscribe and eth_unsubscribe.

Included

  • EthPubSubApi implementation.
  • Service integration.
  • Support for Kind::NewHeads, Kind::Logs, Kind::NewPendingTransactions, Kind::Syncing subscriptions.

Example

While running the template locally, in PolkadotJs the subscription to Kind::NewHeads can be tested using the Javascript console provided in the UI with:

let ws = new WebSocket('ws://localhost:9944');

ws.onopen = function(){
  ws.send(JSON.stringify({"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}))
}    

ws.onmessage = function(a) {
    console.log(JSON.stringify(JSON.parse(a.data).params.result,null,2));
}

Copy link
Collaborator

@crystalin crystalin left a comment

Choose a reason for hiding this comment

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

Looks good so far

@tgmichel
Copy link
Contributor Author

tgmichel commented Aug 26, 2020

Implemented Kind::Logs subscription type.

Each subscription message expects a single Log, while the storage update for receipt logs occurs once per block, so the storage notification is triggered with a single Vec<Log> Stream. This would not send a message to the subscriber per Log, but rather a single message with a Vec<Log>. We don't want that.

The proposed solution is flat_map the notification Stream creating a second Stream that will resolve a future per Log contained in the original Vec. That will emit i.e. 5 single Log messages to the subscriber if the latest block contained 5 Logs in total.

@tgmichel
Copy link
Contributor Author

Same strategy for Kind::NewPendingTransactions.

@tgmichel
Copy link
Contributor Author

#107 will include several changes in the project, makes sense to wait until that is merged and then adapt this PR - should be reasonably easy.

As a side note, both eth and eth_pubsub modules may end up sharing some stuff like native_block_number method and the filtering logic for Logs. We will need to decouple that.

@tgmichel
Copy link
Contributor Author

@crystalin @sorpaas I tried the NewHeads today and it works. Tomorrow I will try the logs and pending subscriptions, if that works I will send the PR.

Please do a quick review over this and let me know.

@tgmichel
Copy link
Contributor Author

tgmichel commented Sep 8, 2020

Added Kind::Syncing implementation. Still not sure if this is the right way to do it, didn't find other way.

We want to keep track SyncState through the NetworkService::is_major_syncing method. Afaik there is no way of subscribe to a notification that streams whenever the NetworkWorker changes the syncing state.

What I did is just subscribe to a storage notification that streams per block, and then send to the subscriber only if the syncing state changed from the previous check.

@crystalin
Copy link
Collaborator

@tgmichel , did you look at adding the event into substrate directly ? Is that a long work

@tgmichel
Copy link
Contributor Author

tgmichel commented Sep 8, 2020

@tgmichel , did you look at adding the event into substrate directly ? Is that a long work

I don't want to mess with the NetworkWorker poll if possible, but we may end up going back to do more research on it if we find this approach does not work.

@sorpaas
Copy link
Member

sorpaas commented Sep 11, 2020

Please pull master.

# Conflicts:
#	frame/ethereum/src/lib.rs
#	rpc/Cargo.toml
#	rpc/src/lib.rs
#	template/runtime/src/lib.rs
@tgmichel tgmichel requested a review from sorpaas as a code owner September 21, 2020 08:41
@tgmichel
Copy link
Contributor Author

@sorpaas Updated. Pushed some minor runtime changes for pallet-balances, required once paritytech/substrate#7048 goes through and we merge master to https://github.com/paritytech/substrate/tree/frontier.

@tgmichel
Copy link
Contributor Author

Bumped jsonrpc-core and jsonrpc-pubsub to 15.0.0 to not overlap with https://github.com/paritytech/substrate/tree/frontier.

Added a minor runtime fix to add WeightInfo to pallet-grandpa.

@sorpaas
Copy link
Member

sorpaas commented Sep 28, 2020

Really sorry about this, but can you pull master again?

@tgmichel
Copy link
Contributor Author

tgmichel commented Sep 28, 2020

@ermalkaleci @crystalin @sorpaas

This test https://github.com/paritytech/frontier/blob/master/ts-tests/tests/test-block.ts#L120 was previously skipped and recently was changed to be included in this PR:

https://github.com/paritytech/frontier/pull/135/files

I'm getting random behaviour from it.

You can reproduce it locally by running the tests. Sometimes passes and sometimes fails. The error is this - returned by createAndFinalizeBlock:

Error: Unexpected result: {"jsonrpc":"2.0","error":{"code":20000,"message":"Execution: Runtime panicked: Timestamp must be updated once in the block"},"id":1}

I will revert it back to skip so I can move forward. Please let me know.

@sorpaas
Copy link
Member

sorpaas commented Sep 28, 2020

@tgmichel I think that's alright. The error was not related to this PR -- we probably just missed a timestamp inherent or something like that in the manual seal. Still good to have it fixed in a separate PR though.

@sorpaas sorpaas merged commit c288899 into polkadot-evm:master Sep 28, 2020
@tgmichel tgmichel deleted the tgmichel-pubsub2 branch April 1, 2022 09:56
abhijeetbhagat pushed a commit to web3labs/frontier that referenced this pull request Jan 11, 2023
* Pubsub service setup

* Add LatestHeader StorageValue, change Module name

* Implement Kind::NewHeads for eth_subscribe

* Styling fix

* Add .cargo-remote.toml to .gitignore

* Update Cargo.lock

* pallet_ethereum LatestHeader to LatestBlock

* Refactor to accommodate new Kinds

* Implement Kind::Logs

* Move Vec<Log> build to its own function

* Added missing fields from Log response

* Implement Kind::NewPendingTransactions

* Implement eth_unsubscribe

* Implement filtering for Kind::Logs

* Small fixes

* Add stream_build macro

* Adapt to frontier consensus

* Indentation cleanup

* Formatting and cleanup

* Remove unused imports

* Remove Pending.take and add on_initialize

* Fix Kind:NewPendingTransactions

* Add NetworkService to pubsub rpc handler

* Implement Kind::Syncing

* Fix checker

* pallet_ethereum handle Log response from evm execution

* Runtime update substrate#12d0b7e

* Return Vec<Log> in handle_exec

* Fix checker

* Runtime update substrate#93b2c36

* Bump jsonrpc-ore and jsonrpc-pubsub version

* Update Cargo.lock

* Update pallet-ethereum mock

* Add missing const

* Move internal error handler to crate root

* Update pubsub to one-to-many

* Skip previous block hash as parent test
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.

None yet

4 participants