Skip to content

Conversation

@AlexD10S
Copy link
Collaborator

@AlexD10S AlexD10S commented Mar 12, 2025

This PR integrates an external provider for chain deployment, enabling seamless and automated deployment processes.

It introduces the ability to deploy a chain to a deployment provider within the existing flow introduced in #404, which handles rollup reservation and registration on a relay chain.
Currently, only one deployment provider is supported, but the implementation is designed with scalability in mind, allowing for the addition of more providers in the future. This follows a similar approach to how template providers are managed.

Additional Flow for Deploying a Chain Using the External Provider:

  1. API Key Handling:
    Prompt the user for the API_KEY, or retrieve it from an environment variable if available.

  2. Query API for Collator Keys
    Retrieve the collator keys required to run the chain and inject them into the chain spec.
    This PR extends the existing ChainSpec module to handle key injection (Pop Docs) and updates the build process to regenerate the genesis artifacts without regenerating the chain spec file.

  3. Chain Deployment Request:
    After registration, send a POST request with the raw chain spec and necessary deployment details, including:

    • Sudo key – Extracted from the chain spec
    • Proxy key – Provided during the registration process
    • Collator file ID – Retrieved from the previous GET request
    • Template used – Identifies the parachain template

Flow diagram

Captura de pantalla 2025-03-13 a las 11 15 15 Captura de pantalla 2025-03-13 a las 12 38 15 Captura de pantalla 2025-03-13 a las 13 09 04

Other considerations

  1. Template Identification in pop-cli:
    pop-cli needs to identify the template used to include this information in the API request. To achieve this, we introduce a metadata field in the chain spec:
"basedOn": "template_name"

This metadata is set when creating a new template using pop new parachain for both Pop and Parity templates. This approach aligns with what OpenZeppelin (OZ) was already using OpenZeppelin/polkadot-runtime-templates#406.

  1. Pure Proxy Registration:
    The external provider strongly recommends using a pure proxy for registration. Previously, only "proxy" was mentioned in the messaging. This PR improves the messaging and adds pure proxy as a predefined action in the pop call list to simplify its creation.
Captura de pantalla 2025-03-13 a las 12 20 27

Improvements after feedback

Based on Tin's testing flow—where he was able to reserve and register the parachain, but the deployment failed due to an API issue (#459 (review)). I found it useful to include an option to attempt only the deployment to the external provider.
To address this, I added the --skip-registration flag (included in 7dab5ee) and a --chain-spec parameter (introduced in
ed32ffc).
The --chain-spec parameter prevents regenerating the full chain spec and instead only generates the raw chain spec and artifacts. This enables retrying only the deployment step without redoing the registration process and rebuilding the chain spec.

Limitations

How to test

  1. Get Access to the Deployment Platform
    You need an account on https://staging.deploypolkadot.xyz/ and there you can obtain the API_KEY in settings. Ping me in private, and I'll provide the details if needed.
  2. You need tokens in PASEO (Or the chain you will test on)
    Use the faucet https://faucet.polkadot.io/ to obtain them.
  3. Create a pure proxy account
    Run pop call chain to create a pure proxy account. Retrieve the proxy address from the events and request tokens for the pure proxy address using the faucet.
  4. Run pop up and follow all the steps in the interactive guide!

[sc-2615]

@AlexD10S AlexD10S force-pushed the feat/deploy-provider branch from fafb3da to abf4870 Compare March 12, 2025 16:37
@codecov
Copy link

codecov bot commented Mar 12, 2025

Codecov Report

Attention: Patch coverage is 81.40604% with 283 lines in your changes missing coverage. Please review.

Project coverage is 76.82%. Comparing base (b7c07b2) to head (ed182a5).

Files with missing lines Patch % Lines
crates/pop-cli/src/commands/up/rollup.rs 73.45% 101 Missing and 54 partials ⚠️
crates/pop-cli/src/commands/build/spec.rs 65.90% 47 Missing and 13 partials ⚠️
crates/pop-cli/src/deployment_api.rs 85.38% 11 Missing and 33 partials ⚠️
crates/pop-parachains/src/build/mod.rs 94.42% 0 Missing and 13 partials ⚠️
crates/pop-parachains/src/deployer_providers.rs 93.24% 4 Missing and 1 partial ⚠️
crates/pop-common/src/account_id.rs 91.66% 1 Missing and 2 partials ⚠️
crates/pop-cli/src/cli.rs 50.00% 0 Missing and 1 partial ⚠️
crates/pop-cli/src/commands/new/parachain.rs 0.00% 0 Missing and 1 partial ⚠️
crates/pop-parachains/src/new_parachain.rs 50.00% 0 Missing and 1 partial ⚠️
@@            Coverage Diff             @@
##             main     #459      +/-   ##
==========================================
+ Coverage   76.21%   76.82%   +0.60%     
==========================================
  Files          82       84       +2     
  Lines       18377    19720    +1343     
  Branches    18377    19720    +1343     
==========================================
+ Hits        14006    15149    +1143     
- Misses       2485     2589     +104     
- Partials     1886     1982      +96     
Files with missing lines Coverage Δ
crates/pop-cli/src/commands/build/parachain.rs 74.11% <ø> (ø)
crates/pop-cli/src/commands/mod.rs 24.24% <ø> (ø)
crates/pop-cli/src/commands/up/mod.rs 81.19% <100.00%> (+3.19%) ⬆️
crates/pop-cli/src/main.rs 36.78% <ø> (ø)
crates/pop-cli/src/style.rs 95.12% <100.00%> (+2.52%) ⬆️
crates/pop-parachains/src/call/metadata/action.rs 94.18% <100.00%> (+0.43%) ⬆️
crates/pop-parachains/src/generator/parachain.rs 0.00% <ø> (ø)
crates/pop-parachains/src/templates.rs 98.93% <100.00%> (+0.27%) ⬆️
crates/pop-parachains/src/utils/helpers.rs 80.43% <100.00%> (+0.65%) ⬆️
crates/pop-cli/src/cli.rs 65.41% <50.00%> (+2.67%) ⬆️
... and 8 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AlexD10S AlexD10S force-pushed the feat/deploy-provider branch from 2f180e9 to bbbb041 Compare March 13, 2025 09:06
@AlexD10S AlexD10S marked this pull request as ready for review March 13, 2025 12:09
@AlexD10S AlexD10S requested a review from chungquantin March 13, 2025 12:09
Copy link
Contributor

@chungquantin chungquantin left a comment

Choose a reason for hiding this comment

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

This PR is very detailed and enjoyable to test and review! I left a couples of suggestions and questions. Haven't reviewed the rollup.rs, deployment_api.rs and the overall functionalities completely. Will finish my review after setting up on my local to test the PDP.

@AlexD10S AlexD10S requested a review from chungquantin March 14, 2025 09:49
@AlexD10S AlexD10S force-pushed the feat/deploy-provider branch from 78553c8 to 351b7be Compare March 15, 2025 16:32
Copy link
Contributor

@chungquantin chungquantin left a comment

Choose a reason for hiding this comment

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

I found a couple of UX issues that can be improved, see comments. Another issue is I could not deploy to PDP because the ParaId in the provided chainspec can't be identified.

At this step, it asks:

◇  Provide the chain specification to use (e.g. dev, local, custom or a path to an existing file)
│  dev
│
◇  Name or path for the plain chain spec file:
│  ./chain-spec.json

After I provided my chainspec file path, I provided the protocol ID

◇  Enter the protocol ID that will identify your network:
│  4727
|
◇  Would you like to use local host as a bootnode ?
│  No
│
◇  Would you like to build the runtime deterministically? This requires a containerization solution (Docker/Podman) and is recommended for production builds.
│  No
│
⚙  Building your chain spec
│
◇  Chain specification built successfully.
│
◆  Generated files:
│  ● Plain text chain specification file generated at: ./chain-spec.json
│  ● Raw chain specification file generated at: ./chain-spec-raw.json
│  ● WebAssembly runtime file exported at: ./para-4727.wasm
│  ● Genesis State file exported at: ./para-4727-genesis-state
│
└  Need help? Learn more at https://learn.onpop.io

But then when deploy, it throws an error

⚙  Starting deployment with Polkadot Deployment Portal
│
└  Deployment failed: Deployment failed with status 400 Bad Request: {"error":{"issues":[{"code":"custom","message":"Invalid chainspec format: [\n  {\n    \"code\": \"invalid_type\",\n    \"expected\": \"object\",\n    \"received\": \"null\",\n    \"path\": [\n      \"properties\"\n    ],\n    \"message\": \"Expected object, received null\"\n  }\n]","path":["chainspecs","chainspecs"]},{"code":"custom","message":"ParaId in chainspec (undefined) doesn't match the provided paraId - 4727","path":["chainspecs"]}],"name":"ZodError"}}

Seems like ParaId is undefined even though my chainspec is already correct.

Screenshot 2025-03-17 at 12 29 57

However, now my parachain ID is already registered and proxy's balance is deducted. Then I want to retry by running this command: "pop up --id 4727 --genesis-state para-4727-genesis-state --genesis-code para-4727.wasm", it tries to register my parachain ID again. I signed the transaction again and receives another error:

◆  Signed payload received.
│
◇  Extrinsic submitted with hash: 0xecc98d6d6eec864ebb1c15341ca6aa78559574a3b243aa5d1e534418b0122378
│
◆  Registration successfully https://polkadot.js.org/apps/?rpc=wss://paseo.dotters.network/#/parachains
│
└  Deployment failed: No collator_file_id was found

@AlexD10S AlexD10S mentioned this pull request Mar 17, 2025
5 tasks
Base automatically changed from feat/deploy-parachain to main March 17, 2025 10:40
@AlexD10S AlexD10S force-pushed the feat/deploy-provider branch from 4f0c8ac to 0ce3b53 Compare March 17, 2025 10:48
@AlexD10S
Copy link
Collaborator Author

AlexD10S commented Mar 17, 2025

But then when deploy, it throws an error

⚙  Starting deployment with Polkadot Deployment Portal
│
└  Deployment failed: Deployment failed with status 400 Bad Request: {"error":{"issues":[{"code":"custom","message":"Invalid chainspec format: [\n  {\n    \"code\": \"invalid_type\",\n    \"expected\": \"object\",\n    \"received\": \"null\",\n    \"path\": [\n      \"properties\"\n    ],\n    \"message\": \"Expected object, received null\"\n  }\n]","path":["chainspecs","chainspecs"]},{"code":"custom","message":"ParaId in chainspec (undefined) doesn't match the provided paraId - 4727","path":["chainspecs"]}],"name":"ZodError"}}

The raw chain spec seems to have been properly generated. I've shared the details with the PDP team to investigate what might be wrong with the request.

Based on the issues in your flow, if the reserve and registration steps succeed but deployment to the provider fails, it might be useful to add a --skip-registration flag (included in 7dab5ee) and a --chain-spec parameter (introduced in
ed32ffc). The latter avoids regenerating the full chain spec and instead only generates the raw chain spec and artifacts. This would allow retrying only the deployment step without redoing the registration process.

@AlexD10S AlexD10S requested a review from chungquantin March 17, 2025 17:04
@chungquantin
Copy link
Contributor

Minor thing but if I provide --skip-registration and select "Only Register in Relay Chain", it asks me for the relaychain node URL but nothing happens. I don't think this is a bug but if --skip-registration is provided, the "Only Register in Relay Chain" should not be displayed for selection?

Screenshot 2025-03-18 at 15 38 16

@Daanvdplas Daanvdplas self-requested a review March 18, 2025 12:35
Copy link
Collaborator

@Daanvdplas Daanvdplas left a comment

Choose a reason for hiding this comment

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

Unfortunately I didn't get it to work. I have been struggling a lot to get where I got so I think we need to make some more improvements, especially because the error output is not always very helpful.

Case 1
pop:

IO error: command ["/Users/R0GUE/Documents/Code/Raise/bfg-node/target/release/retail-alliance", "build-spec", "--chain", "dev", "--disable-default-bootnode"] exited with code 1


without pop:

./target/release/retail-alliance build-spec --chain=devnet --disable-default-bootnode
Error: Input("Error opening spec file `devnet`: No such file or directory (os error 2)”)


Case 2 target was build with runtime-benchmarks feature
pop:

IO error: command ["/Users/R0GUE/Documents/Code/Raise/bfg-node/target/release/retail-alliance", "export-genesis-state", "--chain", "./chain-spec-raw.json", "./para-4735-genesis-state"] exited with code 1


without pop:

Error: Service(Client(VersionInvalid("Other error happened while constructing the runtime: runtime requires function imports which are not present on the host: 'env:ext_benchmarking_commit_db_version_1', 'env:ext_benchmarking_reset_read_write_count_version_1', 'env:ext_benchmarking_get_read_and_written_keys_version_1', 'env:ext_benchmarking_read_write_count_version_1', 'env:ext_benchmarking_proof_size_version_1', 'env:ext_benchmarking_set_whitelist_version_1', 'env:ext_benchmarking_add_to_whitelist_version_1', 'env:ext_benchmarking_wipe_db_version_1', 'env:ext_benchmarking_current_time_version_1'")))
2025-03-18 15:06:10 Cannot create a runtime error=Other("runtime requires function imports which are not present on the host: 'env:ext_benchmarking_commit_db_version_1', 'env:ext_benchmarking_reset_read_write_count_version_1', 'env:ext_benchmarking_get_read_and_written_keys_version_1', 'env:ext_benchmarking_read_write_count_version_1', 'env:ext_benchmarking_proof_size_version_1', 'env:ext_benchmarking_set_whitelist_version_1', 'env:ext_benchmarking_add_to_whitelist_version_1', 'env:ext_benchmarking_wipe_db_version_1', 'env:ext_benchmarking_current_time_version_1'")


I think we should do two things, one, we should always try to build the required binary to make sure it is up to date with the latest changes. This prevents the amount of things that can go wrong by a lot. We want to minimise the amount of things that can go wrong, especially with a feature that one should preferably only have to use a few times in their life, and one that is costly. In addition, we need to find the cause of these unclear errors and make sure they are improved.

On a completely other note: If the build fails after the para id is reserved, we should make it very clear how to proceed with the pop up command and the reserved para id. This to ensure the user knows that is not a big deal and it can still use that para id that it reserved, as well as being helped with what command to use to make their life a breeze.

I did all the steps, realising at the end that I was deploying pop-node, and I got this error (not sure why):
Screenshot 2025-03-18 at 21 23 22
On top of that, we also want to make sure that we provide all the info to the user about what went wrong and what the user should do to proceed, in this case the user should be told to use the --skip-registration flag because the registration did work.

In general, would it make sense to make it possible to dry run this?

Moreover, when the --skip-registration flag is provided, the artifacts are already deployed, so we shouldn't have to be queried about the chain spec etc. Moreover, we should not build all the chain specs and artifacts (perhaps even request and insert collator keys).

If I can give one piece of advice, write unit tests, it greatly improved my PR back at the time I wrote the pop build spec and it also improved my development output / quality. Especially with AI we should be able to test the full flow of things.

@AlexD10S
Copy link
Collaborator Author

Minor thing but if I provide --skip-registration and select "Only Register in Relay Chain", it asks me for the relaychain node URL but nothing happens. I don't think this is a bug but if --skip-registration is provided, the "Only Register in Relay Chain" should not be displayed for selection?

Good point. 4c050a2

@AlexD10S
Copy link
Collaborator Author

AlexD10S commented Mar 20, 2025

I think we should do two things, one, we should always try to build the required binary to make sure it is up to date with the latest changes. This prevents the amount of things that can go wrong by a lot. We want to minimise the amount of things that can go wrong, especially with a feature that one should preferably only have to use a few times in their life, and one that is costly. In addition, we need to find the cause of these unclear errors and make sure they are improved.

The errors related to generating the chain spec that you mentioned above are not related to this PR, but I agree they need to be addressed. Fixed in a separate PR.

I'm not sure if forcing a rebuild is really worth it. The code change itself is simple, just a single line at the beginning of the flow:

build_parachain(self.path.as_ref().unwrap_or(&PathBuf::from("./")), None, self.profile.as_ref().unwrap_or(&Profile::Release), None)?;

However, it introduces extra noise early in the flow, and we already trigger a build when generating the chain spec if the node hasn't been built yet. Your specific case, an error in spec generation due to a build with runtime-benchmarks is quite rare.

On a completely other note: If the build fails after the para id is reserved, we should make it very clear how to proceed with the pop up command and the reserved para id. This to ensure the user knows that is not a big deal and it can still use that para id that it reserved, as well as being helped with what command to use to make their life a breeze.

This is very good point. Improved messaging in 4c159e9
Captura de pantalla 2025-03-20 a las 9 42 32

In general, would it make sense to make it possible to dry run this?

That would be amazing! For reserve/registration, we'd need integration with Chopsticks, but for deployment, I'm not sure how we could dry-run it.

Moreover, when the --skip-registration flag is provided, the artifacts are already deployed, so we shouldn't have to be queried about the chain spec etc. Moreover, we should not build all the chain specs and artifacts (perhaps even request and insert collator keys).

We need the chain spec for deployment. If the user doesn’t want to generate it again, I’ve added the --chain-spec flag to allow providing it. I agree that requesting collator keys could be skipped, however, due to the current provider API, the collator_id_key is required in the POST request and is generated on their side in the GET response to retrieve the collator keys. So for now, we can't skip this step.

@AlexD10S AlexD10S requested a review from Daanvdplas March 20, 2025 18:08
@AlexD10S AlexD10S added the ready-for-final-review The PR is ready for final review label Mar 24, 2025
@AlexD10S AlexD10S force-pushed the feat/deploy-provider branch from 7f261de to 3929c8a Compare March 24, 2025 11:05
Copy link
Member

@al3mart al3mart left a comment

Choose a reason for hiding this comment

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

Couldn't go through all the code in detail yet. But left a couple of nits based on my first run.

I'll provide a more in depth review tomorrow. Pretty cool feat 🔥

AlexD10S added 16 commits March 26, 2025 12:03
* feat: convert_to_evm_accounts

* test: fix replace_use_evm_collator_keys_works

* refactor: use AccountIdMapper from cargo-contracts

* fix: rebase conflicts

* chore: clippy warnings
* chore: sleep after warning messages

* chore: link to provider portal

* chore: improve spinner fetch collator keys

* chore: add prefix for rogue templats

* chore: profile flag and release as default

* chore: display steps if none flags has been provided

* test: fix unit tests

* refactor: renaming variables

* refactor: format_url in style

* fix: serialize name for r0gue templates

* refactor: format_step_prefix

* refactor: stop 1 second after warnign

* test: fix prepare_for_deployment_only_register_works
@AlexD10S AlexD10S force-pushed the feat/deploy-provider branch from 47f2ade to 33858f3 Compare March 26, 2025 11:04
Copy link
Contributor

@chungquantin chungquantin left a comment

Choose a reason for hiding this comment

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

All functionalities work perfectly! Thanks for your support and improvements applied to the PR. I don't have any other feedback so I'm happy to approve.

Copy link
Member

@al3mart al3mart left a comment

Choose a reason for hiding this comment

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

I've left some nits that should be easy to address and other that are up to you to tackle if you consider that worth it.

Looking pretty nice 👌

@AlexD10S AlexD10S requested a review from al3mart March 26, 2025 19:38
Copy link
Member

@al3mart al3mart left a comment

Choose a reason for hiding this comment

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

Thanks for resolving the feedback so quickly!

@AlexD10S AlexD10S merged commit b6e228a into main Mar 27, 2025
31 of 32 checks passed
@AlexD10S AlexD10S deleted the feat/deploy-provider branch March 27, 2025 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-final-review The PR is ready for final review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants