mirror of
https://github.com/pezkuwichain/pezkuwi-fellows.git
synced 2026-05-30 08:11:01 +00:00
435 lines
36 KiB
HTML
435 lines
36 KiB
HTML
|
|
<!DOCTYPE HTML>
|
|
<html lang="en" class="polkadot" dir="ltr">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>RFC-0103: Introduce a CoreIndex commitment in candidate receipts - Polkadot Fellowship RFCs</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta name="description" content="An online book of RFCs approved or proposed within the Polkadot Fellowship.">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
<link rel="icon" href="../favicon.svg">
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|
<link rel="stylesheet" href="../css/general.css">
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" href="../highlight.css">
|
|
<link rel="stylesheet" href="../tomorrow-night.css">
|
|
<link rel="stylesheet" href="../ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
<link rel="stylesheet" href="../theme/polkadot.css">
|
|
|
|
</head>
|
|
<body class="sidebar-visible no-js">
|
|
<div id="body-container">
|
|
<!-- Provide site root to javascript -->
|
|
<script>
|
|
var path_to_root = "../";
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "polkadot" : "polkadot";
|
|
</script>
|
|
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script>
|
|
try {
|
|
var theme = localStorage.getItem('mdbook-theme');
|
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script>
|
|
var theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
var html = document.querySelector('html');
|
|
html.classList.remove('polkadot')
|
|
html.classList.add(theme);
|
|
var body = document.querySelector('body');
|
|
body.classList.remove('no-js')
|
|
body.classList.add('js');
|
|
</script>
|
|
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script>
|
|
var body = document.querySelector('body');
|
|
var sidebar = null;
|
|
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
} else {
|
|
sidebar = 'hidden';
|
|
}
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
|
body.classList.remove('sidebar-visible');
|
|
body.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<div class="sidebar-scrollbox">
|
|
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../introduction.html">Introduction</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Newly Proposed</li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Proposed</li><li class="chapter-item expanded "><a href="../proposed/0088-broker-pallet-slashable-deposit-purchaser-reputation-reserved-cores.html">RFC-0088: Add slashable locked deposit, purchaser reputation, and reserved cores for on-chain identities to broker pallet</a></li><li class="chapter-item expanded "><a href="../proposed/0089-flexible-inflation.html">RFC-0089: Flexible Inflation</a></li><li class="chapter-item expanded "><a href="../proposed/0097-unbonding_queue.html">RFC-0097: Unbonding Queue</a></li><li class="chapter-item expanded "><a href="../proposed/00xx-smart-contracts-coretime-chain.html">RFC-0002: Smart Contracts on the Coretime Chain</a></li><li class="chapter-item expanded "><a href="../proposed/0100-xcm-multi-type-asset-transfer.html">RFC-0100: New XCM instruction: InitiateAssetsTransfer</a></li><li class="chapter-item expanded "><a href="../proposed/0102-offchain-parachain-runtime-upgrades.html">RFC-0000: Feature Name Here</a></li><li class="chapter-item expanded "><a href="../proposed/0103-introduce-core-index-commitment.html" class="active">RFC-0103: Introduce a CoreIndex commitment in candidate receipts</a></li><li class="chapter-item expanded "><a href="../proposed/0105-xcm-improved-fee-mechanism.html">RFC-0105: XCM improved fee mechanism</a></li><li class="chapter-item expanded "><a href="../proposed/0106-xcm-remove-fees-mode.html">RFC-0106: Remove XCM fees mode</a></li><li class="chapter-item expanded "><a href="../proposed/0107-xcm-execution-hints.html">RFC-0107: XCM Execution hints</a></li><li class="chapter-item expanded "><a href="../proposed/0109-xcm-descend-instead-of-clear-origin.html">RFC-0109: Descend XCM origin instead of clearing it where possible</a></li><li class="chapter-item expanded "><a href="../proposed/TODO-stale-nomination-reward-curve.html">RFC-TODO: Stale Nomination Reward Curve</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Approved</li><li class="chapter-item expanded "><a href="../approved/0001-agile-coretime.html">RFC-1: Agile Coretime</a></li><li class="chapter-item expanded "><a href="../approved/0005-coretime-interface.html">RFC-5: Coretime Interface</a></li><li class="chapter-item expanded "><a href="../approved/0007-system-collator-selection.html">RFC-0007: System Collator Selection</a></li><li class="chapter-item expanded "><a href="../approved/0008-parachain-bootnodes-dht.html">RFC-0008: Store parachain bootnodes in relay chain DHT</a></li><li class="chapter-item expanded "><a href="../approved/0010-burn-coretime-revenue.html">RFC-0010: Burn Coretime Revenue</a></li><li class="chapter-item expanded "><a href="../approved/0012-process-for-adding-new-collectives.html">RFC-0012: Process for Adding New System Collectives</a></li><li class="chapter-item expanded "><a href="../approved/0013-prepare-blockbuilder-and-core-runtime-apis-for-mbms.html">RFC-0013: Prepare Core runtime API for MBMs</a></li><li class="chapter-item expanded "><a href="../approved/0014-improve-locking-mechanism-for-parachains.html">RFC-0014: Improve locking mechanism for parachains</a></li><li class="chapter-item expanded "><a href="../approved/0022-adopt-encointer-runtime.html">RFC-0022: Adopt Encointer Runtime</a></li><li class="chapter-item expanded "><a href="../approved/0026-sassafras-consensus.html">RFC-0026: Sassafras Consensus Protocol</a></li><li class="chapter-item expanded "><a href="../approved/0032-minimal-relay.html">RFC-0032: Minimal Relay</a></li><li class="chapter-item expanded "><a href="../approved/0042-extrinsics-state-version.html">RFC-0042: Add System version that replaces StateVersion on RuntimeVersion</a></li><li class="chapter-item expanded "><a href="../approved/0043-storage-proof-size-hostfunction.html">RFC-0043: Introduce storage_proof_size Host Function for Improved Parachain Block Utilization</a></li><li class="chapter-item expanded "><a href="../approved/0045-nft-deposits-asset-hub.html">RFC-0045: Lowering NFT Deposits on Asset Hub</a></li><li class="chapter-item expanded "><a href="../approved/0047-assignment-of-availability-chunks.html">RFC-0047: Assignment of availability chunks to validators</a></li><li class="chapter-item expanded "><a href="../approved/0048-session-keys-runtime-api.html">RFC-0048: Generate ownership proof for SessionKeys</a></li><li class="chapter-item expanded "><a href="../approved/0050-fellowship-salaries.html">RFC-0050: Fellowship Salaries</a></li><li class="chapter-item expanded "><a href="../approved/0056-one-transaction-per-notification.html">RFC-0056: Enforce only one transaction per notification</a></li><li class="chapter-item expanded "><a href="../approved/0059-nodes-capabilities-discovery.html">RFC-0059: Add a discovery mechanism for nodes based on their capabilities</a></li><li class="chapter-item expanded "><a href="../approved/0078-merkleized-metadata.html">RFC-0078: Merkleized Metadata</a></li><li class="chapter-item expanded "><a href="../approved/0084-general-transaction-extrinsic-format.html">RFC-0084: General transactions in extrinsic format</a></li><li class="chapter-item expanded "><a href="../approved/0091-dht-record-creation-time.html">RFC-0091: DHT Authority discovery record creation time</a></li><li class="chapter-item expanded "><a href="../approved/0099-transaction-extension-version.html">RFC-0099: Introduce a transaction extension version</a></li><li class="chapter-item expanded "><a href="../approved/0101-xcm-transact-remove-max-weight-param.html">RFC-0101: XCM Transact remove require_weight_at_most parameter</a></li><li class="chapter-item expanded "><a href="../approved/0108-xcm-remove-testnet-ids.html">RFC-0108: Remove XCM testnet NetworkIds</a></li><li class="spacer"></li><li class="chapter-item expanded affix "><li class="part-title">Stale</li><li class="chapter-item expanded "><a href="../stale/0004-remove-unnecessary-allocator-usage.html">RFC-0004: Remove the host-side runtime memory allocator</a></li><li class="chapter-item expanded "><a href="../stale/0006-dynamic-pricing-for-bulk-coretime-sales.html">RFC-0006: Dynamic Pricing for Bulk Coretime Sales</a></li><li class="chapter-item expanded "><a href="../stale/0009-improved-net-light-client-requests.html">RFC-0009: Improved light client requests networking protocol</a></li><li class="chapter-item expanded "><a href="../stale/0015-market-design-revisit.html">RFC-0015: Market Design Revisit</a></li><li class="chapter-item expanded "><a href="../stale/0020-treasurer-track-confirmation-period-duration-modification.html">RFC-0020: Treasurer Track Confirmation Period Duration Modification</a></li><li class="chapter-item expanded "><a href="../stale/0034-xcm-absolute-location-account-derivation.html">RFC-34: XCM Absolute Location Account Derivation</a></li><li class="chapter-item expanded "><a href="../stale/0035-conviction-voting-delegation-modifications.html"> RFC-0035: Conviction Voting Delegation Modifications</a></li><li class="chapter-item expanded "><a href="../stale/0044-rent-based-registration.html">RFC-0044: Rent based registration model</a></li><li class="chapter-item expanded "><a href="../stale/0054-remove-heap-pages.html">RFC-0054: Remove the concept of "heap pages" from the client</a></li><li class="chapter-item expanded "><a href="../stale/0070-x-track-kusamanetwork.html">RFC-0070: X Track for @kusamanetwork</a></li><li class="chapter-item expanded "><a href="../stale/0073-referedum-deposit-track.html">RFC-0073: Decision Deposit Referendum Track</a></li><li class="chapter-item expanded "><a href="../stale/0074-stateful-multisig-pallet.html">RFC-0074: Stateful Multisig Pallet</a></li><li class="chapter-item expanded "><a href="../stale/0077-increase-max-length-of-identity-pgp-fingerprint-value.html">RFC-0077: Increase maximum length of identity PGP fingerprint values from 20 bytes</a></li><li class="chapter-item expanded "><a href="../stale/00xx-secondary-marketplace-for-regions.html">RFC-0001: Secondary Market for Regions</a></li></ol>
|
|
</div>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
|
</nav>
|
|
|
|
<!-- Track and set sidebar scroll position -->
|
|
<script>
|
|
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
|
sidebarScrollbox.addEventListener('click', function(e) {
|
|
if (e.target.tagName === 'A') {
|
|
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
|
}
|
|
}, { passive: true });
|
|
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
|
sessionStorage.removeItem('sidebar-scroll');
|
|
if (sidebarScrollTop) {
|
|
// preserve sidebar scroll position when navigating via links within sidebar
|
|
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
|
} else {
|
|
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
|
var activeSection = document.querySelector('#sidebar .active');
|
|
if (activeSection) {
|
|
activeSection.scrollIntoView({ block: 'center' });
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky">
|
|
<div class="left-buttons">
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</label>
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="polkadot">Polkadot</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
</ul>
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">Polkadot Fellowship RFCs</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script>
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<p><a href="https://github.com/polkadot-fellows/RFCs/pull/103">(source)</a></p>
|
|
<p><strong>Table of Contents</strong></p>
|
|
<ul>
|
|
<li><a href="#rfc-0103--introduce-a-coreindex-commitment-in-candidate-receipts">RFC-0103: Introduce a <code>CoreIndex</code> commitment in candidate receipts</a>
|
|
<ul>
|
|
<li><a href="#summary">Summary</a></li>
|
|
<li><a href="#motivation">Motivation</a></li>
|
|
<li><a href="#stakeholders">Stakeholders</a></li>
|
|
<li><a href="#explanation">Explanation</a>
|
|
<ul>
|
|
<li><a href="#reclaiming-unused-space-in-the-descriptor">Reclaiming unused space in the descriptor</a></li>
|
|
<li><a href="#backwards-compatibility">Backwards compatibility</a></li>
|
|
<li><a href="#ump-transport">UMP transport</a></li>
|
|
<li><a href="#polkadot-primitive-changes">Polkadot Primitive changes</a></li>
|
|
<li><a href="#parachain-block-validation">Parachain block validation</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#drawbacks">Drawbacks</a></li>
|
|
<li><a href="#testing-security-and-privacy">Testing, Security, and Privacy</a></li>
|
|
<li><a href="#performance">Performance</a></li>
|
|
<li><a href="#ergonomics">Ergonomics</a></li>
|
|
<li><a href="#compatibility">Compatibility</a>
|
|
<ul>
|
|
<li><a href="#versioning">Versioning</a></li>
|
|
<li><a href="#runtime">Runtime</a></li>
|
|
<li><a href="#validators">Validators</a></li>
|
|
<li><a href="#parachains">Parachains</a></li>
|
|
<li><a href="#tooling">Tooling</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#prior-art-and-references">Prior Art and References</a></li>
|
|
<li><a href="#unresolved-questions">Unresolved Questions</a></li>
|
|
<li><a href="#future-directions-and-related-material">Future Directions and Related Material</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<h1 id="rfc-0103--introduce-a-coreindex-commitment-in-candidate-receipts"><a class="header" href="#rfc-0103--introduce-a-coreindex-commitment-in-candidate-receipts">RFC-0103: Introduce a <code>CoreIndex</code> commitment in candidate receipts</a></h1>
|
|
<div class="table-wrapper"><table><thead><tr><th></th><th></th></tr></thead><tbody>
|
|
<tr><td><strong>Start Date</strong></td><td>15 July 2024</td></tr>
|
|
<tr><td><strong>Description</strong></td><td>Constrain parachain block validity to a specific core and session</td></tr>
|
|
<tr><td><strong>Authors</strong></td><td>Andrei Sandu</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
|
|
<p>The only requirement for collator nodes is to provide valid parachain blocks to the validators of a backing group and by definition the collator set is trustless. However, in the case of elastic scaling, for security reason, collators must be trusted - non-malicious. <code>CoreIndex</code> commitments are required to remove this limitation. Additionally we are introducing a <code>SessionIndex</code> field in the <code>CandidateReceipt</code> to make dispute resolution more secure and robust. </p>
|
|
<h2 id="motivation"><a class="header" href="#motivation">Motivation</a></h2>
|
|
<p>At present time misbehaving collator nodes, or anyone who has acquired a valid collation can prevent a parachain from effecitvely using elastic scaling by providing the same collation to all backing groups assigned to the parachain. This happens before the next parachain block is authored and will prevent the chain of candidates to be formed, reducing the throughput of the parachain to a single core.</p>
|
|
<p>This RFC solves the problem by enabling a parachain to provide a core index commitment as part of it's PVF execution output and in the associated candidate receipt data structure. </p>
|
|
<p>Once this RFC is implemented the validity of a parachain block depends on the core it is being executed on.</p>
|
|
<h2 id="stakeholders"><a class="header" href="#stakeholders">Stakeholders</a></h2>
|
|
<ul>
|
|
<li>Polkadot core developers.</li>
|
|
<li>Cumulus node developers.</li>
|
|
<li>Tooling, block explorer developers.</li>
|
|
</ul>
|
|
<p>This approach and alternatives have been considered and discussed in <a href="https://github.com/polkadot-fellows/RFCs/issues/92">this issue</a>.</p>
|
|
<h2 id="explanation"><a class="header" href="#explanation">Explanation</a></h2>
|
|
<p>The approach proposed below was chosen primarly because it minimizes the number of breaking changes, the complexity and takes less implementation and testing time. The proposal is to change the existing primitives while keeping binary compatibility with the older versions. We repurpose unused fields to introduce core index and a session index information in the <code>CandidateDescriptor</code> and extend the UMP usage to output core index information. </p>
|
|
<h3 id="reclaiming-unused-space-in-the-descriptor"><a class="header" href="#reclaiming-unused-space-in-the-descriptor">Reclaiming unused space in the descriptor</a></h3>
|
|
<p>The <code>CandidateDescriptor</code> currently includes <code>collator</code> and <code>signature</code> fields. The collator includes a signature on the following descriptor fields: parachain id, relay parent, validation data hash, validation code hash and the PoV hash.</p>
|
|
<p>However, in practice, having a collator signature in the receipt on the relay chain does not provide any benefits as there is no mechanism to punish or reward collators that have provided bad parachain blocks.</p>
|
|
<p>This proposal aims to remove the collator signature and all the logic that checks the collator signatures of candidate receipts. We use the first 6 reclaimed bytes to represent the core and session index, and fill the rest with zeroes. So, there is no change in the layout and length of the receipt. The new primitive is binary compatible with the old one.</p>
|
|
<h3 id="backwards-compatibility"><a class="header" href="#backwards-compatibility">Backwards compatibility</a></h3>
|
|
<p>There are two flavors of candidate receipts which are used in network protocols, runtime and node implementation:</p>
|
|
<ul>
|
|
<li><code>CommittedCandidateReceipt</code> which includes the <code>CanidateDescriptor</code> and the <code>CandidateCommitments</code> </li>
|
|
<li><code>CandidateReceipt</code> which includes the <code>CanidateDescriptor</code> and just a hash of the commitments</li>
|
|
</ul>
|
|
<p>We want to support both the old and new versions in the runtime and node. The implementation must be able to detect the version of a given candidate receipt.</p>
|
|
<p><code>CandidateDescriptor</code> is at version 2 if:</p>
|
|
<ul>
|
|
<li>the reserved fields are zeroed</li>
|
|
<li>the session index matches the session index of the relay parent</li>
|
|
<li>the UMP queue contains a core index commitment and it the one in the descriptor.</li>
|
|
</ul>
|
|
<h3 id="ump-transport"><a class="header" href="#ump-transport">UMP transport</a></h3>
|
|
<p><a href="https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/primitives/src/v7/mod.rs#L652">CandidateCommitments</a> remains unchanged as we will store scale encoded <code>UMPSignal</code> messages directly in the parachain UMP queue by outputing them in the <a href="https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/primitives/src/v7/mod.rs#L682">upward_messages</a>. </p>
|
|
<p>The UMP queue layout is changed to allow the relay chain to receive both the XCM messages and <code>UMPSignal</code> messages. An empty message (empty <code>Vec<u8></code>) is used to mark the end XCM messages and the start of <code>UMPSignal</code> messages.</p>
|
|
<p>This way of representing the new messages has been choose over introducing an enum wrapper to minimize breaking changes of XCM message decoding in tools like Subscan for example. </p>
|
|
<p>Example: </p>
|
|
<pre><code>[ XCM message1, XCM message2, ..., EMPTY message, UMPSignal::CoreSelector ]
|
|
</code></pre>
|
|
<h4 id="umpsignal-messages"><a class="header" href="#umpsignal-messages"><code>UMPSignal</code> messages</a></h4>
|
|
<pre><code>/// A strictly increasing sequence number, tipically this would be the parachain block number.
|
|
pub struct CoreSelector(pub BlockNumber);
|
|
|
|
/// An offset in the relay chain claim queue.
|
|
pub struct ClaimQueueOffset(pub u8);
|
|
|
|
/// Default claim queue offset
|
|
pub const DEFAULT_CLAIM_QUEUE_OFFSET: ClaimQueueOffset = ClaimQueueOffset(1);
|
|
|
|
pub enum UMPSignal {
|
|
/// A message sent by a parachain to select the core the candidate is commited to.
|
|
/// Relay chain validators, in particular backers, use the `CoreSelector` and `ClaimQueueOffset`
|
|
/// to compute the index of the core the candidate has commited to.
|
|
///
|
|
SelectCore(CoreSelector, ClaimQueueOffset),
|
|
}
|
|
</code></pre>
|
|
<p>As we dont want to have a claim queue snapshot in the parachain runtime, we need to set <code>ClaimQueueOffset</code>
|
|
statically to some sane value. Parachains should prefer to have a static value that makes sense for their usecase which can be changed by governance at some future point. Changing the value dynamically can be a friction point. It will work out fine to decrease the value to build more into the present. But if the value is increased to build more into the future, a relay chain block will be skipped.</p>
|
|
<p>Considering <code>para_assigned_cores</code> is a sorted vec of core indices assigned to a parachain at the
|
|
specified claim queue offset, validators will determine the committed core index like this:</p>
|
|
<pre><code>let assigned_core_index = core_selector % para_assigned_cores.len();
|
|
let committed_core_index = para_assigned_cores[assigned_core_index];
|
|
</code></pre>
|
|
<h3 id="polkadot-primitive-changes"><a class="header" href="#polkadot-primitive-changes">Polkadot Primitive changes</a></h3>
|
|
<h4 id="new-candidatedescriptor"><a class="header" href="#new-candidatedescriptor">New <a href="https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/primitives/src/v7/mod.rs#L482">CandidateDescriptor</a></a></h4>
|
|
<ul>
|
|
<li>reclaim 32 bytes from <code>collator: CollatorId</code> and 64 bytes from <code>signature: CollatorSignature</code> and rename to <code>reserved1</code> and <code>reserved2</code> fields.</li>
|
|
<li>take 2 bytes from <code>reserved1</code> for a new <code>core_index: u16</code> field.</li>
|
|
<li>take 4 bytes from <code>reserved2</code> for a new <code>session_index: u32</code> field.</li>
|
|
<li>the <code>reserved1</code> and <code>reserved2</code> fields are zeroed</li>
|
|
</ul>
|
|
<p>Thew new primitive will look like this:</p>
|
|
<pre><code>pub struct CandidateDescriptorV2<H = Hash> {
|
|
/// The ID of the para this is a candidate for.
|
|
para_id: Id,
|
|
/// The hash of the relay-chain block this is executed in the context of.
|
|
relay_parent: H,
|
|
/// The core index where the candidate is backed.
|
|
core_index: CoreIndex,
|
|
/// The session index in which the candidate is backed.
|
|
session_index: SessionIndex,
|
|
/// Reserved bytes.
|
|
reserved1: [u8; 26],
|
|
/// The blake2-256 hash of the persisted validation data. This is extra data derived from
|
|
/// relay-chain state which may vary based on bitfields included before the candidate.
|
|
/// Thus it cannot be derived entirely from the relay-parent.
|
|
persisted_validation_data_hash: Hash,
|
|
/// The blake2-256 hash of the PoV.
|
|
pov_hash: Hash,
|
|
/// The root of a block's erasure encoding Merkle tree.
|
|
erasure_root: Hash,
|
|
/// Reserved bytes.
|
|
reserved2: [u8; 64],
|
|
/// Hash of the para header that is being generated by this candidate.
|
|
para_head: Hash,
|
|
/// The blake2-256 hash of the validation code bytes.
|
|
validation_code_hash: ValidationCodeHash,
|
|
}
|
|
</code></pre>
|
|
<p>In future format versions, parts of the <code>reserved1</code> and <code>reserved2</code> bytes can be used to include additional information in the descriptor.</p>
|
|
<h4 id="versioned-candidatereceipt-and-committedcandidatereceipt-primitives"><a class="header" href="#versioned-candidatereceipt-and-committedcandidatereceipt-primitives">Versioned <code>CandidateReceipt</code> and <code>CommittedCandidateReceipt</code> primitives:</a></h4>
|
|
<p>We want to decouple the actual representation of the <code>CandidateReceipt</code> from the higher level code. This should make it easier to implement future format versions of this primitive. To hide the logic of versioning the descriptor fields will be private and accessor methods are provided.</p>
|
|
<pre><code>pub enum VersionedCandidateReceipt {
|
|
V1(CandidateReceipt),
|
|
V2(CandidateReceiptV2),
|
|
}
|
|
|
|
impl VersionedCandidateReceipt {
|
|
/// Returns the core index the candidate has commited to.
|
|
/// Returns `None` if the candidate receipt is the old version (v1).
|
|
fn core_index() -> Option<CoreIndex>;
|
|
|
|
/// Returns the session index of the candidate relay parent.
|
|
fn session_index() -> Option<CoreIndex>;
|
|
|
|
/// ...
|
|
}
|
|
|
|
</code></pre>
|
|
<p>A manual decode <code>Decode</code> implementation is required to account for version detection and constructing the appropriate variant.</p>
|
|
<h3 id="parachain-block-validation"><a class="header" href="#parachain-block-validation">Parachain block validation</a></h3>
|
|
<p>Backers will make use of the core index information to validate the blocks during backing and reject blocks if:</p>
|
|
<ul>
|
|
<li>the <code>core_index</code> in descriptor does not match the one determined by the <code>UMPSignal::SelectCore</code> message</li>
|
|
<li>the <code>core_index</code> in the descriptor does not match the core the backing group is assigned to</li>
|
|
<li>the <code>session_index</code> is not equal to the session of the <code>relay_parent</code> in the descriptor</li>
|
|
</ul>
|
|
<p>If core index (and session index) information is not available (backers got an old candidate receipt), there will be no changes compared to current behaviour.</p>
|
|
<h2 id="drawbacks"><a class="header" href="#drawbacks">Drawbacks</a></h2>
|
|
<p>The only drawback is that further additions to the descriptor are limited to the amount of remaining unused space.</p>
|
|
<h2 id="testing-security-and-privacy"><a class="header" href="#testing-security-and-privacy">Testing, Security, and Privacy</a></h2>
|
|
<p>Standard testing (unit tests, CI zombienet tests) for functionality and mandatory secuirty audit to ensure the implementation does not introduce any new security issues.</p>
|
|
<p>Backwards compatibility of the implementation will be tested on testnets (Versi and Westend).</p>
|
|
<p>There is no impact on privacy.</p>
|
|
<h2 id="performance"><a class="header" href="#performance">Performance</a></h2>
|
|
<p>The expectation is that performance impact is negligible for sending and processing the UMP message has negligible performance impact in the runtime as well as on the node side.</p>
|
|
<h2 id="ergonomics"><a class="header" href="#ergonomics">Ergonomics</a></h2>
|
|
<p>Parachain that use elastic scaling must send the separator empty message followed by the <code>UMPSignal::SelectCore</code> only after sending all of the UMP XCM messages.</p>
|
|
<h2 id="compatibility"><a class="header" href="#compatibility">Compatibility</a></h2>
|
|
<h3 id="versioning"><a class="header" href="#versioning">Versioning</a></h3>
|
|
<p>At this point there is a simple way to determine the version of the receipt, by testing for zeroed reserved bytes in the
|
|
descriptor. Supporting future changes will require a <code>u8</code> version field to be introduced in the reserved space. We consider the current version to be 0 and the version check implicitly done when checking for reserved space to be zeroed.</p>
|
|
<h3 id="runtime"><a class="header" href="#runtime">Runtime</a></h3>
|
|
<p>The first step is to remove collator signature checking logic in the runtime, but keep the node side collator signature
|
|
checks. </p>
|
|
<p>The runtime must be upgraded to the new primitives before any collator or node are allowed to use the new candidate receipts format. </p>
|
|
<h3 id="validators"><a class="header" href="#validators">Validators</a></h3>
|
|
<p>To ensure a smooth launch, a new node feature is required.
|
|
The feature acts as a signal for supporting the new candidate receipts on the node side and can only be safely enabled if at least 2/3 of the validators are upgraded.</p>
|
|
<p>Once enabled, the validators will skip checking the collator signature when processing the candidate receipts and verify the <code>CoreIndex</code> and <code>SessionIndex</code> fields if present in the receipit.</p>
|
|
<p>No new implementation of networking protocol versions for collation and validation are required.</p>
|
|
<h3 id="parachains"><a class="header" href="#parachains">Parachains</a></h3>
|
|
<p><code>CoreIndex</code> commitments are needed only by parachains using elastic scaling. Just upgrading the collator node and runtime should be sufficient and possible without manual changes.</p>
|
|
<h3 id="tooling"><a class="header" href="#tooling">Tooling</a></h3>
|
|
<p>Any tooling that decodes UMP XCM messages needs an update to support or ignore the new UMP messages, but they should be fine to decode the regular XCM messages that come before the separator.</p>
|
|
<h2 id="prior-art-and-references"><a class="header" href="#prior-art-and-references">Prior Art and References</a></h2>
|
|
<p>Forum discussion about a new <code>CandidateReceipt</code> format: https://forum.polkadot.network/t/pre-rfc-discussion-candidate-receipt-format-v2/3738</p>
|
|
<h2 id="unresolved-questions"><a class="header" href="#unresolved-questions">Unresolved Questions</a></h2>
|
|
<p>N/A</p>
|
|
<h2 id="future-directions-and-related-material"><a class="header" href="#future-directions-and-related-material">Future Directions and Related Material</a></h2>
|
|
<p>The implementation is extensible and future proof to some extent. With minimal or no breaking changes, additional fields can be added in the candidate descriptor until the reserved space is exhausted</p>
|
|
<p>Once the reserved space is exhausted, versioning will be implemented. The candidate receipt format will be versioned. Versioning should also be implemented for the validation function, inputs and outputs (<code>CandidateCommitments</code>).</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="../proposed/0102-offchain-parachain-runtime-upgrades.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../proposed/0105-xcm-improved-fee-mechanism.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="../proposed/0102-offchain-parachain-runtime-upgrades.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../proposed/0105-xcm-improved-fee-mechanism.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="../elasticlunr.min.js"></script>
|
|
<script src="../mark.min.js"></script>
|
|
<script src="../searcher.js"></script>
|
|
|
|
<script src="../clipboard.min.js"></script>
|
|
<script src="../highlight.js"></script>
|
|
<script src="../book.js"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|