use-ink / cargo-contract

Setup and deployment tool for developing Wasm based smart contracts via ink!
GNU General Public License v3.0
249 stars 120 forks source link

Implement fork from live chain capabilities #988

Open cmichi opened 1 year ago

cmichi commented 1 year ago

This is an involved issue. Before any implementation is started, please discuss the design of the CLI API here.

To facilitate testing and development, it would be convenient to have the ability to implement fork capabilities in cargo-contract. This feature would allow developers to test their smart contracts using the current state of a target blockchain, which can help identify and fix potential issues before deploying the contract to a live network.

This will be more involved, there is existing tooling in the Substrate ecosystem and this command should be built just using Rust dependencies.

Starting points:

kianenigma commented 1 year ago

I think nowadays Chopsticks from Acala is also a very good tool and should be considered.

kianenigma commented 1 year ago

@brunopgalvao asked me about this and I rather write my thoughts here for the sake of posterity.

Executing the contract is at the end of the day just another call into the runtime, and if you want to "execute a particular runtime API call, on top of a particular state", then the underlying machinery used in try-runtime, or perhaps itself directly, can be used.

ATM only nodes that integrate try-runtime-cli can use the high level CLI. That means it can be part of some kind of a contract node, not this repo.

That being said, we are working with AlephZero to move it to a new repository, usable as a library. https://github.com/paritytech/try-runtime-cli/pull/1

brunopgalvao commented 1 year ago

Thanks @kianenigma.

Looks like substrate-contracts-node currently does not have the try-runtime cli configured.

A few scenarios that I see:

1) Wait for try-runtime to be its own separate tool 2) Look into integrating try-runtime into substrate-contracts-node ( this could be more involved ) 3) Acala's chopsticks could be a good solution to this ( I will look into it)

brunopgalvao commented 1 year ago

Also, one thought that I have, teams that are building with pallet-contracts most likely use Cumulus (or parachain template) (which has try-runtime already configured) and add pallet contracts vs forking substrate-contracts-node. If so this could be good because it means that they already have try-runtime available. For demo purposes, we can configure a substrate node with pallet contracts or configure substrate-contracts-node with try-runtime and run the ink! e2e tests off of this try-runtime enabled node.

kianenigma commented 1 year ago

Look into integrating try-runtime into substrate-contracts-node ( this could be more involved )

This is actually a fairly simple thing to do. If you look into now it is integrated into node-template, is is merely adding a new CLI subcommand, and the rest is handled elsewhere.

brunopgalvao commented 1 year ago

Thanks @kianenigma

This is actually a fairly simple thing to do. If you look into now it is integrated into node-template, is is merely adding a new CLI subcommand, and the rest is handled elsewhere.

I replicated how the node-template integrates try-runtime. You can see my work here:

I am running into the following issue when running try-runtime on the contracts node:

2023-04-23 10:56:06.342  INFO main try-runtime::cli: subscribing to "chain_subscribeFinalizedHeads" / "chain_unsubscribeFinalizedHeads"    
2023-04-23 10:56:06.344  INFO main remote-ext: since no prefix is filtered, the data for all pallets will be downloaded    
2023-04-23 10:56:06.345  INFO main remote-ext: scraping key-pairs from remote at block height 0x0000000000000000000000000000000000000000000000000000000000000000    
2023-04-23 10:56:06.345 ERROR main remote-ext: Error = Call(Custom(ErrorObject { code: ServerError(-32000), message: "Client error: UnknownBlock: Header was not found in the database: 0x0000000000000000000000000000000000000000000000000000000000000000", data: None }))    
Error: Input("rpc get_keys failed")

So the issue here, most likely is that the contracts node does not use BABE/GRANDPA instead it uses manual-seal. I don't believe it will be able to get keys. This PR which removes aura and grandpa and implements manual-seal may help:

Details on how to replicate the issue:

cmichi commented 1 year ago

Current state of the issue: We want to implement it via Chopsticks. Bruno got pretty far here, but it then turned out that smoldot (which Chopsticks uses) doesn't support pallet-contracts yet, due to missing support for child tries. This issue is currently blocked by this.

There are two ways how this issue can be unblocked:

ashutoshvarma commented 1 year ago

PR https://github.com/smol-dot/smoldot/issues/166 is now merged, and smoldot should support pallet-contracts now, if I understand correctly? Also chopsticks was recently updated to use new smoldot version, that should have the above PR but when running Astar (or any other runtime with pallet-contracts) it failed to deploy/interact with contracts.

brunopgalvao commented 1 year ago

You are correct. However, chopsticks is still using version 0.8.0 of smoldot:

Which it looks like it is linked to this commit:

The child trie support is in version 0.9.0 of smoldot