|
| 1 | +--- |
| 2 | +title: Coretime Renewal |
| 3 | +description: Learn how to renew coretime manually or automatically to ensure uninterrupted parachain operation with predictable pricing and minimal risk. |
| 4 | +--- |
| 5 | + |
| 6 | +# Coretime Renewal |
| 7 | + |
| 8 | +## Introduction |
| 9 | + |
| 10 | +Coretime can be purchased in bulk for a period of 28 days, providing access to Polkadot's shared security and interoperability for Polkadot parachains. The bulk purchase of coretime includes a rent-control mechanism that keeps future purchases within a predictable price range of the initial purchase. This allows cores to be renewed at a known price without competing against other participants in the open market. |
| 11 | + |
| 12 | +## Bulk Sale Phases |
| 13 | + |
| 14 | +The bulk sale process consists of three distinct phases: |
| 15 | + |
| 16 | +1. **Interlude phase** - the period between bulk sales when renewals are prioritized |
| 17 | +2. **Lead-in phase** - following the interlude phase, a new `start_price` is set, and a Dutch auction begins, lasting for `leadin_length` blocks. During this phase, prices experience downward pressure as the system aims to find market equilibrium. The final price at the end of this phase becomes the `regular_price`, which will be used in the subsequent fixed price phase |
| 18 | +3. **Fixed price phase** - the final phase where remaining cores are sold at the `regular_price` established during the lead-in phase. This provides a stable and predictable pricing environment for participants who did not purchase during the price discovery period |
| 19 | + |
| 20 | +For more comprehensive information about the coretime sales process, refer to the [Coretime Sales](https://wiki.polkadot.network/learn/learn-agile-coretime/#coretime-sales){target=\_blank} section in the Polkadot Wiki. |
| 21 | + |
| 22 | +## Renewal Timing |
| 23 | + |
| 24 | +While renewals can technically be made during any phase, it is strongly recommended that they be completed during the interlude phase. Delaying renewal introduces the risk that the core could be sold to another market participant, preventing successful renewal. Renewals must be initiated well in advance to avoid the scenario above. |
| 25 | + |
| 26 | +For example, if you purchase a core in bulk sale #1, you obtain coretime for the upcoming bulk period (during which bulk sale #2 takes place). |
| 27 | +Your renewal must be completed during bulk sale #2, ideally during its interlude phase, to secure coretime for the subsequent period. |
| 28 | + |
| 29 | +## Manual Renewal |
| 30 | + |
| 31 | +Cores can be renewed by issuing the [`broker.renew(core)`](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/pallet/struct.Pallet.html#method.renew){target=\_blank} extrinsic during the coretime sale period. While this process is straightforward, it requires manual action that must not be overlooked. Failure to complete this renewal step before all available cores are sold could result in your parachain being unable to secure a core for the next operational period. |
| 32 | + |
| 33 | +To manually renew a core: |
| 34 | + |
| 35 | +1. In [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank}, connect to the Coretime chain, navigate to the **Developer** dropdown, and select the **Extrinsics** option |
| 36 | + |
| 37 | +  |
| 38 | + |
| 39 | +2. Submit the `broker.renew` extrinsic |
| 40 | + 1. Select the **broker** pallet |
| 41 | + 2. Choose the **renew** extrinsic |
| 42 | + 3. Fill in the **core** parameter |
| 43 | + 4. Click the **Submit Transaction** button |
| 44 | + |
| 45 | +  |
| 46 | + |
| 47 | +For optimal results, the renewal should be performed during the interlude phase. Upon successful submission, your core will be renewed for the next coretime period, ensuring the continued operation of your parachain. |
| 48 | + |
| 49 | +## Auto-Renewal |
| 50 | + |
| 51 | +The coretime auto-renewal feature simplifies maintaining continuous coretime allocation by automatically renewing cores at the beginning of each sale period. This eliminates the need for parachains to manually renew their cores for each bulk period, reducing operational overhead and the risk of missing renewal deadlines. |
| 52 | + |
| 53 | +When auto-renewal is enabled, the system follows this process at the start of each sale: |
| 54 | + |
| 55 | +1. The system scans all registered auto-renewal records |
| 56 | +2. For each record, it attempts to process renewal payments from the task's [sovereign account](/polkadot-protocol/glossary/#sovereign-account){target=\_blank} (which is the sibling account on the Coretime chain derived from the parachain ID) |
| 57 | +3. Upon successful payment, the system emits a `Renewed` event and secures the core for the next period |
| 58 | +4. If payment fails due to insufficient funds or other issues, the system emits an `AutoRenewalFailed` event |
| 59 | + |
| 60 | +Even if an auto-renewal attempt fails, the auto-renewal setting remains active for subsequent sales. This means the setting persists across multiple periods once you've configured auto-renewal. |
| 61 | + |
| 62 | +To enable auto-renewal for your parachain, you must configure several components, as detailed in the following sections. |
| 63 | + |
| 64 | +### Set Up an HRMP Channel |
| 65 | + |
| 66 | +A Horizontal Relay-routed Message Passing (HRMP) channel must be opened between your parachain and the Coretime system chain before configuring auto-renewal. |
| 67 | + |
| 68 | +For instructions on establishing this connection, consult the [Opening HRMP Channels with System Parachains](/tutorials/interoperability/xcm-channels/para-to-system/){target=\_blank} guide. |
| 69 | + |
| 70 | +### Fund Sovereign Account |
| 71 | + |
| 72 | +The [sovereign account](https://github.com/polkadot-fellows/xcm-format/blob/10726875bd3016c5e528c85ed6e82415e4b847d7/README.md?plain=1#L50){target=\_blank} of your parachain on the Coretime chain needs adequate funding to cover both XCM transaction fees and the recurring coretime renewal payments. |
| 73 | + |
| 74 | +To determine your parachain's sovereign account address, you can: |
| 75 | + |
| 76 | +- Use the **"Para ID" to Address** section in [Substrate Utilities](https://www.shawntabrizi.com/substrate-js-utilities/){target=\_blank} with the **Sibling** option selected |
| 77 | + |
| 78 | +- Calculate it manually: |
| 79 | + |
| 80 | + 1. Identify the appropriate prefix: |
| 81 | + |
| 82 | + - For sibling chains - `0x7369626c` (decodes to `b"sibl"`) |
| 83 | + |
| 84 | + 2. Encode your parachain ID as a u32 [SCALE](https://docs.polkadot.com/polkadot-protocol/basics/data-encoding/#data-types){target=\_blank} value: |
| 85 | + |
| 86 | + - For parachain 2000, this would be `d0070000` |
| 87 | + |
| 88 | + 3. Combine the prefix with the encoded ID to form the sovereign account address: |
| 89 | + |
| 90 | + - **Hex** - `0x7369626cd0070000000000000000000000000000000000000000000000000000` |
| 91 | + - **SS58 format** - `5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmSuC8` |
| 92 | + |
| 93 | +### Auto-Renewal Configuration Extrinsics |
| 94 | + |
| 95 | +The Coretime chain provides two primary extrinsics for managing the auto-renewal functionality: |
| 96 | + |
| 97 | +- [**`enable_auto_renew(core, task, workload_end_hint)`**](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/pallet/struct.Pallet.html#method.enable_auto_renew){target=\_blank} - use this extrinsic to activate automatic renewals for a specific core. This transaction must originate from the sovereign account of the parachain task |
| 98 | + |
| 99 | + **Parameters:** |
| 100 | + |
| 101 | + - **`core`** - the core currently assigned to the task |
| 102 | + - **`task`** - the task for which auto-renewal is being enabled |
| 103 | + - **`workload_end_hint`** - the timeslice at which the currently assigned core will stop being used. This value helps the system determine when auto-renewal should begin. It is recommended to always provide this value to avoid ambiguity |
| 104 | + |
| 105 | + - If the coretime expires in the current sale period, use the last timeslice of the current sale period |
| 106 | + |
| 107 | + - If the coretime expires at the end of the next sale period (e.g., because you've already renewed), use the last timeslice of the next sale period |
| 108 | + |
| 109 | + - If a lease is active, use the timeslice when the lease ends |
| 110 | + |
| 111 | +- [**`disable_auto_renew(core, task)`**](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/pallet/struct.Pallet.html#method.disable_auto_renew){target=\_blank} - use this extrinsic to stop automatic renewals. This extrinsic also requires that the origin is the sovereign account of the parachain task |
| 112 | + |
| 113 | + **Parameters:** |
| 114 | + |
| 115 | + - **`core`** - the core currently assigned to the task |
| 116 | + - **`task`** - the task for which auto-renewal is enabled |
| 117 | + |
| 118 | +### Construct the Enable Auto-Renewal Extrinsic |
| 119 | + |
| 120 | +To configure auto-renewal, you'll need to gather specific information for the `enable_auto_renew` extrinsic parameters: |
| 121 | + |
| 122 | +- **`core`** - identify which core your parachain is assigned to when it expires. This requires checking both current assignments and planned future assignments: |
| 123 | + - **For current period** - query `broker.workload()` |
| 124 | + - **For next period** - query `broker.workplan()` |
| 125 | + |
| 126 | + **Example for parachain `2000`:** |
| 127 | + |
| 128 | + - Current assignment (workload) |
| 129 | + ```txt |
| 130 | + [ |
| 131 | + [50] |
| 132 | + [{ |
| 133 | + mask: 0xffffffffffffffffffff |
| 134 | + assignment: {Task: 2,000} |
| 135 | + }] |
| 136 | + ] |
| 137 | + ``` |
| 138 | +
|
| 139 | + - Future assignment (workplan) |
| 140 | + ```txt |
| 141 | + [ |
| 142 | + [[322,845, 48]] |
| 143 | + [{ |
| 144 | + mask: 0xffffffffffffffffffff |
| 145 | + assignment: {Task: 2,000} |
| 146 | + }] |
| 147 | + ] |
| 148 | + ``` |
| 149 | +
|
| 150 | + **Note:** use the core from workplan (`48` in this example) if your task appears there. Only use the core from workload if it's not listed in workplan. |
| 151 | +
|
| 152 | +- **`task`** - use your parachain ID, which can be verified by connecting to your parachain and querying `parachainInfo.parachainId()` |
| 153 | +
|
| 154 | +- **`workload_end_hint`** - you should always set it explicitly to avoid misbehavior. This value indicates when your assigned core will expire. Here's how to calculate the correct value based on how your core is assigned: |
| 155 | + - If the parachain uses bulk coretime, query `broker.saleinfo`. You’ll get a result like: |
| 156 | +
|
| 157 | + ```json |
| 158 | + { |
| 159 | + "saleStart": 1544949, |
| 160 | + "leadinLength": 100800, |
| 161 | + "endPrice": 922760076, |
| 162 | + "regionBegin": 322845, |
| 163 | + "regionEnd": 327885, |
| 164 | + "idealCoresSold": 18, |
| 165 | + "coresOffered": 18, |
| 166 | + "firstCore": 44, |
| 167 | + "selloutPrice": 92272712073, |
| 168 | + "coresSold": 18 |
| 169 | + } |
| 170 | + ``` |
| 171 | +
|
| 172 | + - If the core expires in the current sale, use the `regionBegin` value, which in this case is `322845` |
| 173 | +
|
| 174 | + - If the core has already been renewed and will expire in the next sale, use the `regionEnd` value. In this example, that would be `327885` |
| 175 | +
|
| 176 | +
|
| 177 | + - If the parachain has a lease, query `broker.leases`, which returns entries like: |
| 178 | +
|
| 179 | + ```json |
| 180 | + [ |
| 181 | + { |
| 182 | + "until": 359280, |
| 183 | + "task": 2035 |
| 184 | + }, |
| 185 | + ... |
| 186 | + ] |
| 187 | + ``` |
| 188 | +
|
| 189 | + - Use the `until` value of the lease that corresponds to your task. For example, `359280` would be the value for `workload_end_hint` in the case of task `2035` |
| 190 | +
|
| 191 | +Once you have these values, construct the extrinsic: |
| 192 | +
|
| 193 | +1. In [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank}, connect to the Coretime chain, navigate to the **Developer** dropdown, and select the **Extrinsics** option |
| 194 | +
|
| 195 | +  |
| 196 | +
|
| 197 | +2. Create the `broker.enable_auto_renew` extrinsic |
| 198 | + 1. Select the **broker** pallet |
| 199 | + 2. Choose the **enableAutoRenew** extrinsic |
| 200 | + 3. Fill in the parameters |
| 201 | + 4. Copy the encoded call data |
| 202 | +
|
| 203 | +  |
| 204 | +
|
| 205 | + For parachain `2000` on core `48` with `workload_end_hint` `327885`, the **encoded call data** is:`0x32153000d007000001cd000500` |
| 206 | +
|
| 207 | +3. Check the transaction weight for executing the call. You can estimate this by executing the `transactionPaymentCallApi.queryCallInfo` runtime call with the encoded call data previously obtained |
| 208 | +
|
| 209 | +  |
| 210 | +
|
| 211 | +### Submit the XCM from Your Parachain |
| 212 | +
|
| 213 | +To activate auto-renewal, you must submit an XCM from your parachain to the Coretime chain using Root origin. This can be done through the sudo pallet (if available) or your parachain's governance system. |
| 214 | +
|
| 215 | +The XCM needs to execute these operations: |
| 216 | +
|
| 217 | +1. Withdraw DOT from your parachain's sovereign account on the Coretime chain |
| 218 | +2. Buy execution to pay for transaction fees |
| 219 | +3. Execute the auto-renewal extrinsic |
| 220 | +4. Refund surplus DOT back to the sovereign account |
| 221 | +
|
| 222 | +Here's how to submit this XCM using Acala (Parachain 2000) as an example: |
| 223 | +
|
| 224 | +1. In [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank}, connect to your parachain, navigate to the **Developer** dropdown and select the **Extrinsics** option |
| 225 | +
|
| 226 | +2. Create a `sudo.sudo` extrinsic that executes `polkadotXcm.send`: |
| 227 | + 1. Use the `sudo.sudo` extrinsic to execute the following call as Root |
| 228 | + 2. Select the **polkadotXcm** pallet |
| 229 | + 3. Choose the **send** extrinsic |
| 230 | + 4. Set the **dest** parameter as the Coretime chain (Parachain 1005) |
| 231 | +
|
| 232 | +  |
| 233 | +
|
| 234 | +
|
| 235 | +3. Construct the XCM and submit it: |
| 236 | +
|
| 237 | + 1. Add a **WithdrawAsset** instruction |
| 238 | + 2. Add a **BuyExecution** instruction |
| 239 | + 3. Add a **Transact** instruction with the following parameters: |
| 240 | + - **originKind** - use `SovereignAccount` |
| 241 | + - **requireWeightAtMost** - use the weight calculated previously |
| 242 | + - **call** - use the encoded call data generated before |
| 243 | + 4. Add a **RefundSurplus** instruction |
| 244 | + 5. Add a **DepositAsset** instruction to send the remaining funds to the parachain sovereign account |
| 245 | + 6. Click the **Submit Transaction** button |
| 246 | +
|
| 247 | +  |
| 248 | +
|
| 249 | +After successful execution, your parachain should have auto-renewal enabled. To verify this, check the events emitted in the Coretime chain. You should see a confirmation event named `broker.AutoRenewalEnabled`, which includes two parameters: |
| 250 | +
|
| 251 | +- **core** - the core currently assigned to your task, in this example, `48` |
| 252 | +- **task** - the task for which auto-renewal was enabled, in this example, `2000` |
| 253 | +
|
| 254 | +You can find this event in the list of recent events. It should look similar to the following: |
| 255 | +
|
| 256 | + |
0 commit comments