Skip to content
Gav Wood edited this page Nov 14, 2017 · 10 revisions

Welcome to the polkadot-spec wiki!

Polkadot is primarily described by the Relay chain protocol; key logic between parachain protocols will likely be shared between parachain implementations but are not inherently a part of the Polkadot protocol.

Relay chain

The relay chain is a proof-of-stake blockchain in a similar balance/nonce mould to Ethereum, backed by a Web Assembly (Wasm) engine.

State & Transition Function

Its state is roughly similar to Ethereum: accounts contained in it are a mapping from a U64 account index to code (H256, a SHA3 of Wasm code) and storage (H256, a Merkle-trie root for a set of H256 to U8[] mappings). All such accounts are actually known as "high accounts" since their ID is close to 2**64 and, notionally, they have a "high" privilege level.

state := U64 => [ code_hash: H256, storage_root: H256 ]

In reality almost all account indices would not represent these high accounts but rather be "virtual". High accounts would each fulfil specific functions (though over time these may expanded or contracted as changes in the protocol determine). The accounts on genesis block can be listed:

  • Account 0: Unauthenticated sender. Doesn't actually do anything but represents the unauthenticated (external transaction) origin.
  • Accounts 1...: The virtual account indices.
  • Account ~8: Timestamp contract.
  • Account ~7: Balances contract. Stores a mapping from U64 -> [U256 (balance), U64 (nonce)].
  • Account ~6: Authentication account. Basic account lookup account. Stores a mapping U64 -> H160 providing a partial public-key derivative ("address", similar to an Ethereum address) for each account index. Can be used to register new accounts (in return for some price). All U64s begin at 0x1.
  • Account ~5: Para-chain management account. Stores all things to do with para-chains including para-chain balances and current state.
  • Account ~4: Staking account. Stores all things to do with the proof-of-stake algorithm particularly currently staked amounts. Informs the Consensus account of its current validator set.
  • Account ~3: Consensus account. Stores all things consensus and code is the relay-chain consensus logic. Requires to be informed of the current validator set and can be queried for behaviour profiles.
  • Account ~2: Administration account. Stores and administers low-level chain parameters. Can unilaterally read and replace code/storage in all accounts, create DOTs, &c. Hosts and acts on stake-voting activities.
  • Account ~1: System origin. Doesn't actually do anything but represents the system origin.

For PoC-1, high accounts are likely to be built-in, though eventually they should be implemented as Wasm contracts.

The transition function may be compared to Ethereum, where:

is mostly similar to an unmetered variant of Ethereum runnong that all but removes smart contracts. Exceptions:

  • Utilisation of Wasm engine for code execution rather than EVM.
  • High accounts do not harbour or increment a nonce when deploying.
  • Wasm intrinsics replace each of the EVM externality functions/opcodes:
    • CALLDATA* -> n/a (if coming straight from a transaction message data will be passed as bytes into the function)
    • BLOCKHASH -> blocks
    • TIMESTAMP -> n/a (there is a timestamp contract)
    • NUMBER -> current_number
    • LOG* -> deposit_log
    • CREATE -> deploy (which takes a new account index and clobbers any existing code there; no init function is run).
    • CALL -> call
    • RETURN -> (return in Wasm)
    • BALANCE -> n/a
    • ORIGIN -> n/a
    • GASPRICE -> n/a
    • EXTCODE -> n/a
    • COINBASE -> n/a
    • DIFFICULTY -> n/a
    • GASLIMIT -> n/a
    • GAS -> n/a
    • CALLCODE/DELEGATECALL/SUICIDE -> n/a

Data formats

Data structures are RLP-encoded using normative Ethereum RLP.

Block

A block contains all information required to evaluate a relay-chain block. It includes extrinsic data specific to the relay chain.

Block: [
    header: Header,
    transactions: Transaction[],
    signatures: [[U256, U256, U8], ...]
]

Transaction

Transactions are isolatable components of extrinsic data used in blocks to describe specific communications from the external world.

Transaction: [
    destination: U64,
    function_name: bytes,
    message_data: [...]
]
  • destination is the contract on which the function will be called.
  • function_name is the name of the function of the contract that will be called.
  • message_data are the parameters to be passed into the function; this is a rich data segment and will be interpreted according to the function's prototype. It should contain exactly the number of the elements as the function's prototype; if any of the function's prototype elements are structured in nature, then the structure of this parameters should reflect that. A more specific mapping between RLP and Wasm ABI will be provided in due course.

Header

header: [
    parent_hash: H256,
    number: U64,
    state_root: H256,
    transaction_root: H256,
    parachain_activity_bitfield: bytes,
    logs: bytes[]
]

Relay-chain Transition Function Definition

TODO

Transaction routing

Importantly, the relay-chain validators do almost nothing regarding transaction routing. All heavy-lifting in terms of tracking egress (outgoing) queues is done by collators.

For each block of each para-chain, there exists a set of outgoing messages. Each message has a destination para-chain. This set of messages is defined by the collator, specified in the candidate block and validated as part of the Validity Function. The set of messages must fulfil certain criteria including respecting limitations on the quantity and size of outgoing queues.

We name four chain parameters:

  • routing_max_messages: The maximum number of messages that may be sent from a block in total.
  • routing_max_messages_per_chain: The maximum number of messages that may be sent from a block into a single other chain in total.
  • routing_max_bytes: The maximum number of bytes that all messages can occupy which may be sent from a block in total.
  • routing_max_bytes_per_chain: The maximum number of bytes that all messages can occupy which may be sent from a block into a single other chain in total.

Part of the process of validation includes checking these four limitations have been respected by the candidate block.

There is a notional queue for each non-equivalent ordered pair of para-chains. The trie root for each of these queues is stored on the relay chain. Collators prepare the egre

[XXXX The collators, as part of their candidates, include for each (other) destination para-chain two new trie roots; one is the trie root assuming that the destination's queue was drained on this block; the other trie root is the amalgamation of the previous queue with the new queue.]

NOTE:

With the egress queue accepted as valid,

Clone this wiki locally