paritytech / substrate-connect

Run Wasm Light Clients of any Substrate based chain directly in your browser.
https://paritytech.github.io/substrate-connect/
GNU General Public License v3.0
241 stars 79 forks source link

Is it possible to provide chainspec changes togehter with the chainspec? #1433

Open pgolovkin opened 1 year ago

pgolovkin commented 1 year ago

When I use smoldot I'm able to add changes from substate-connect extension to the database. Here is the example https://github.com/paritytech/substrate-connect/blob/3911d973b7e7883f763515ce74a53faaf4048922/projects/extension/src/background/index.ts#L204

However I'd like to make the same using the substrate-connect. And I see that I'm able only to run the SCProvider with predefined chainspec without latest addition from the external datasource like database or local storage.

wirednkod commented 1 year ago

Hi Pavel,

As you can see in the code you posted, the SC extension is using smoldot API instead of Substrate Connect. The actions happening there (adding specs in the localStorage etc) can be achieved if the integration of an app with smoldot API, in order to achieve the benefits of accessing the chain. Substrate connect is a wrapper around PolkadotJS API using smoldot, in order to return that PJS API to the user, for interacting with it. It is meant to be a simplified 2lines-way to integrate an app (wallet etc.) with a light client.

ScProvider is working with predefined (Wellknown) specs, but also with custom chain specs provided to it (See this doc for more info). That been said, if you have access to that latest chainspecs that you mention, then you can provide it to the ScProvider upon initializing the app and have the latest state

pgolovkin commented 1 year ago

Hi Pavel,

As you can see in the code you posted, the SC extension is using smoldot API instead of Substrate Connect. The actions happening there (adding specs in the localStorage etc) can be achieved if the integration of an app with smoldot API, in order to achieve the benefits of accessing the chain. Substrate connect is a wrapper around PolkadotJS API using smoldot, in order to return that PJS API to the user, for interacting with it. It is meant to be a simplified 2lines-way to integrate an app (wallet etc.) with a light client.

ScProvider is working with predefined (Wellknown) specs, but also with custom chain specs provided to it (See this doc for more info). That been said, if you have access to that latest chainspecs that you mention, then you can provide it to the ScProvider upon initializing the app and have the latest state

thanks for help! I'll try to explain my question better.

Pre-requiesites My application should connect to the WellKnownChain and I can't use the substrate-connect browser extension because I'm running the app not in the browser.

The goal Save the actual light client node state into the database in order to make light client start faster. It's pretty the same that substrate-connect browser extension does.

The solution

  1. When my light client is synced save into the local storage the result of the chainHead_unstable_finalizedDatabase call.
  2. When I'm running my application after some time I'd like to use saved chainHead_unstable_finalizedDatabase in order to start my light client not from the block in the chainspec but from the block from chainHead_unstable_finalizedDatabase. It's pretty the same as substrate-connect extension works. https://github.com/paritytech/substrate-connect/blob/3911d973b7e7883f763515ce74a53faaf4048922/projects/extension/src/background/index.ts#L204

But I'm wondering, if I'm using the ScProvider is it possible to pass the chainHead_unstable_finalizedDatabase somehow in order to make light client to start from the saved block but not from the block in the chainspec.

wirednkod commented 1 year ago

Its not possible to use Substrate connect for that purpose. You should replicate the implementation that extension has, and use the smoldot implementation

pgolovkin commented 1 year ago

Isn't it possible to modify SC in order to support this feature?

wirednkod commented 1 year ago

Substrate connect was created in order to allow easy integration of dApps with smoldot light client, as a polkadot JS wrapper in the browser. The feature, requested, is already supported by smoldot - which can be used in a node implementation. You can always use substrate-connect for a web app, or any browser-based app (e.g. electron), and have a small, simple implementation (same as the extension) - that will periodically fire up a light client and save the state in the cache - then your dApp can load that cached state into the substrate-connect.

We could though add this as a new feature in Substrate-connect as it could help many projects (including yours).

What do you think @josepot

josepot commented 1 year ago

Hey @pgolovkin ! I think that this is a very reasonable feature request. At a first glance it seems like this will require some changes on both APIs: substrate-connect and the SCProvider on polkadotjs, but it's definitely doable. Let me think about the best way to enable this feature and I will get back to you ASAP.

tomaka commented 1 year ago

The reason why this isn't possible is that if you connect to Polkadot/Kusama/Westend/Rococo the substrate-connect extension is supposed to automatically provide the database. And if you connect to a parachain, then providing a database is useless and doesn't speed up syncing at all.

The only situation where providing a database would be useful is: if the user doesn't have the extension installed, or if they connect to a relay chain other than Polkadot/Kusama/Westend/Rococo.

On the other hand, allowing the web page to store the database was deemed a bit dangerous. It makes it very easy for a malicious script that was somehow injected into the page to modify this database. And if the database is modified, the user would be redirected to the wrong chain, which is basically a phishing attack but with no way of detecting it. And this phishing attack would last forever until the user manually cleans their browser local storage.

josepot commented 1 year ago

The reason why this isn't possible is that if you connect to Polkadot/Kusama/Westend/Rococo the substrate-connect extension is supposed to automatically provide the database. And if you connect to a parachain, then providing a database is useless and doesn't speed up syncing at all.

The only situation where providing a database would be useful is: if the user doesn't have the extension installed, or if they connect to a relay chain other than Polkadot/Kusama/Westend/Rococo.

On the other hand, allowing the web page to store the database was deemed a bit dangerous. It makes it very easy for a malicious script that was somehow injected into the page to modify this database. And if the database is modified, the user would be redirected to the wrong chain, which is basically a phishing attack but with no way of detecting it. And this phishing attack would last forever until the user manually cleans their browser local storage.

In the context of something like a Wallet built with Electron (just to give an example), it could be very useful to provide the databaseContent when initiating a relay-chain. Most substrate-based wallets are built using polkadotjs, and the means that they have for integrating with the light-client is substrate-connect. So, I think that it makes sense to enable a way to pass the databaseContent for those users. Although, it would be their responsibility to make the correct RPC calls to get the snapshot and to store it safely, ofc.

pgolovkin commented 1 year ago

The reason why this isn't possible is that if you connect to Polkadot/Kusama/Westend/Rococo the substrate-connect extension is supposed to automatically provide the database. And if you connect to a parachain, then providing a database is useless and doesn't speed up syncing at all. The only situation where providing a database would be useful is: if the user doesn't have the extension installed, or if they connect to a relay chain other than Polkadot/Kusama/Westend/Rococo. On the other hand, allowing the web page to store the database was deemed a bit dangerous. It makes it very easy for a malicious script that was somehow injected into the page to modify this database. And if the database is modified, the user would be redirected to the wrong chain, which is basically a phishing attack but with no way of detecting it. And this phishing attack would last forever until the user manually cleans their browser local storage.

In the context of something like a Wallet built with Electron (just to give an example), it could be very useful to provide the databaseContent when initiating a relay-chain. Most substrate-based wallets are built using polkadotjs, and the means that they have for integrating with the light-client is substrate-connect. So, I think that it makes sense to enable a way to pass the databaseContent for those users. Although, it would be their responsibility to make the correct RPC calls to get the snapshot and to store it safely, ofc.

I agree with you. And you're right, I'm using Electron that is really useful for building cross-platform desktop application. Using the Electron you're actually running a browser with a single tab and you can't make run you application with the SC browser extension. Using the SC provider in the Electron application now makes the developers to update the application every time when SP provider library updates in order to add the latest chainspec into the application. Otherwise the light client start takes more and more time day by day. The feature with providing databaseContent will be really helpful for desktop application developers who use Electron and may provide a significant performance improvement when SC provider starts. As a result Light Clients may become more and more popular and application become secure that will attract more and more users to the ecosystem.