Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIP-29 Milestone Payload (Stardust) #69

Merged
merged 21 commits into from
Sep 8, 2022
Merged
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 254 additions & 0 deletions tips/TIP-0029/tip-0029.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
---
tip: 29
title: Milestone Payload
description: Coordinator issued milestone payload with Ed25519 authentication
author: Angelo Capossele (@capossele) <angelo.capossele@iota.org>, Wolfgang Welz (@Wollac) <wolfgang.welz@iota.org>
discussions-to: https://github.com/iotaledger/tips/pull/69
status: Draft
type: Standards
layer: Core
created: 2022-03-25
replaces: 8
---

# Abstract

In IOTA, nodes use the milestones issued by the Coordinator to reach a consensus on which transactions are confirmed. This TIP proposes a milestone payload for the messages described in the IOTA protocol [TIP-6](../TIP-0006/tip-0006.md). It uses Edwards-curve Digital Signature Algorithm (EdDSA) to authenticate the milestones.

# Motivation

In order to integrate the concept of milestones consistently into Tangle messages, this TIP describes a dedicated payload type for milestones. It contains the same essential data fields that were part of a milestone bundle in the legacy IOTA protocol. Additionally, this document also describes how Ed25519 signatures are used to assure authenticity of the issued milestones. In order to make the management and security of the used private keys easier, simple multisignature features with support for key rotation have been added.

# Specification

The [BLAKE2b-256](https://tools.ietf.org/html/rfc7693) hash of the _Milestone Essence_, consisting of the actual milestone information (like its index number or position in the tangle), is signed using the Ed25519 signature scheme as described in the IRTF [RFC 8032](https://tools.ietf.org/html/rfc8032).

To increase the security of the design, a milestone can (optionally) be independently signed by multiple keys at once. These keys should be operated by detached signature provider services running on independent infrastructure elements. This assists in mitigating the risk of an attacker having access to all the key material necessary for forging milestones. While the Coordinator takes responsibility for forming Milestone Payload Messages, it delegates signing in to these providers through an ad-hoc RPC connector. Mutual authentication should be enforced between the Coordinator and the signature providers: a [client-authenticated TLS handshake](https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake) scheme is advisable. To increase the flexibility of the mechanism, nodes can be configured to require a quorum of valid signatures to consider a milestone as genuine.

In addition, a key rotation policy can also be enforced by limiting key validity to certain milestone intervals. Accordingly, nodes need to know which public keys are applicable for which milestone index. This can be provided by configuring a list of entries consisting of the following fields:
- _Index Range_ providing the interval of milestone indices for which this entry is valid. The interval must not overlap with any other entry.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not how it is implemented!
Key ranges are allowed to overlap.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I checked the Hornet config and there it seems we have (@muXxer please correct if wrong):

  • A list of key ranges, each element with:
    • public key
    • (potentially overlapping) range
  • A global config for the threshold (which is then applied to all key ranges)

Technically, it is equivalent to either have an overlapping list of single keys or a non-overlapping list of sets of key (like in the TIP).
@muXxer, I suppose you are suggesting to change the TIP to reflect the configuration format which is already implemented in Hornet?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I misunderstood that part. Thats even better than it is implemented right now in hornet, because you can specify the threshold per range. And it's easier to read.

So the TIP is fine, maybe we should change the format in hornet in an upcoming version.

Copy link
Contributor

Choose a reason for hiding this comment

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

- _Applicable Public Keys_ defining the set of valid public keys.
- _Signature Threshold_ specifying the minimum number of valid signatures. Must be at least one and not greater than the number of _Applicable Public Keys_.

## Milestone ID

The _Milestone ID_ is the BLAKE2b-256 hash of the serialized _Milestone Essence_.
It is important to note that the signatures do not impact the _Milestone ID_.

## Structure

### Serialized Layout

All values are serialized in little-endian encoding. The serialized form of the milestone is deterministic, meaning the same logical milestone always results in the same serialized byte sequence.

The following table describes the entirety of a _Milestone Payload_ in its serialized form following the notation from [TIP-21](../TIP-0021/tip-0021.md):

<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>Payload Type</td>
<td>uint32</td>
<td>Set to <strong>value 7</strong> to denote a <i>Milestone Payload</i>.</td>
</tr>
<tr>
<td valign="top">Essence <code>oneOf</code></td>
<td colspan="2">
<details open="true">
<summary>Milestone Essence</summary>
<blockquote>Describes the signed part of a <i>Milestone Payload</i>.</blockquote>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>Index Number</td>
<td>uint32</td>
<td>The index number of the milestone.</td>
</tr>
<tr>
<td>Timestamp</td>
<td>uint32</td>
<td>The Unix time (seconds since Unix epoch) at which the milestone was issued.</td>
</tr>
<tr>
<td>Last Milestone ID</td>
<td>ByteArray[32]</td>
<td>The Milestone ID of the milestone with <code>Index Number - 1</code>.</td>
</tr>
<tr>
<td>Parents Count</td>
<td>uint8</td>
<td>The number of parents referenced by this milestone.</td>
</tr>
<tr>
<td valign="top">Parents <code>anyOf</code></td>
<td colspan="2">
<details>
<summary>Parent</summary>
<blockquote>A message that is directly referenced by this milestone.</blockquote>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>Message ID</td>
<td>ByteArray[32]</td>
<td>The Message ID of the parent.</td>
</tr>
</table>
</details>
</td>
</tr>
<tr>
<td>Confirmed Merkle Root</td>
<td>ByteArray[32]</td>
<td>The Merkle tree hash (BLAKE2b-256) of the Message IDs of all messages confirmed by this milestone.</td>
<tr>
<td>Applied Merkle Root</td>
<td>ByteArray[32]</td>
<td>The Merkle tree hash (BLAKE2b-256) of the Message IDs of all messages applied by this milestone that contain a state-mutating transaction (see <a href="../TIP-0004/tip-0004.md">TIP-4</a>).</td>
</tr>
<tr>
<td>Metadata</td>
Wollac marked this conversation as resolved.
Show resolved Hide resolved
<td>(uint16)ByteArray</td>
<td>Binary data only relevant to the milestone issuer, e.g. internal state. A leading uint16 denotes its length.</td>
</tr>
<tr>
<td>Options Count</td>
<td>uint8</td>
<td>The number of milestone options following.</td>
</tr>
<tr>
<td valign="top">Options <code>atMostOneOfEach</code></td>
<td colspan="2">
<details>
<summary>PoW Milestone Option</summary>
Wollac marked this conversation as resolved.
Show resolved Hide resolved
<blockquote>Defines dynamic changes to the PoW parameters.</blockquote>
</details>
<details>
<summary>Receipts Milestone Option</summary>
<blockquote>Defines UTXOs for newly migrated funds.</blockquote>
</details>
</td>
</tr>
</table>
</details>
</td>
</tr>
<tr>
<td>Signatures Count</td>
<td>uint8</td>
<td>The number of signature entries following.</td>
</tr>
<tr>
<td valign="top">Signatures <code>anyOf</code></td>
<td colspan="2">
<details open="true">
<summary>Ed25519 Signature</summary>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>Signature Type</td>
<td>uint8</td>
<td>
Set to <strong>value 0</strong> to denote an <i>Ed25519 Signature</i>.
</td>
</tr>
<tr>
<td>Public Key</td>
<td>ByteArray[32]</td>
<td>The Ed25519 public key of the signature.</td>
</tr>
<tr>
<td>Signature</td>
<td>ByteArray[64]</td>
<td>The Ed25519 signature signing the BLAKE2b-256 hash of the serialized <i>Milestone Essence</i>.</td>
</tr>
</table>
</details>
</td>
</tr>
</table>

### Milestone options

The `Options` field holds additional data authenticated by the milestone.

The following table lists all the `Milestone Option Type` that are currently supported as well as links to the corresponding specification:

| Payload Name | Type Value | TIP |
| ------------ | ---------- | ---------------------------------------------------------- |
| Receipt | 0 | [TIP-34](../TIP-0034/tip-0034.md#receipt-milestone-option) |
| PoW | 1 | [TIP-29](#pow-milestone-option) |

#### PoW Milestone Option

The _PoW Milestone Option_ allows to change the PoW protocol parameters.

| Name | Type | Description |
| ------------------------------ | ------ | ----------------------------------------------------------------------------------------------------- |
| Milestone Option Type | uint8 | Set to **value 1** to denote a *PoW Milestone Option*. |
| Next PoW Score | uint32 | The new PoW score all messages should adhere to. |
| Next PoW Score Milestone Index | uint32 | The index of the first milestone that will require a new minimal pow score for applying transactions. |
Wollac marked this conversation as resolved.
Show resolved Hide resolved

## Validation

Similar to transaction validation, milestone validation has been separated into two classes. For a milestone to be valid, both of them need to be true.

### Syntactic validation

Syntactic validation can be checked from the _Milestone Essence_ plus the messages in the past cone referenced by it.

- Essence:
- `Index Number` must not be smaller than `First Milestone Index`.
- If `Index Number` equals `First Milestone Index`, the following fields must be zeroed out:
- `Last Milestone ID`
- `Confirmed Merkle Root`
- `Applied Merkle Root`
- If `Index Number` is greater than `First Milestone Index`, the milestone must reference (i.e. one of the `Parents` must contain or reference) another syntactically valid milestone whose _Milestone ID_ matches `Last Milestone ID`. With respect to that referenced milestone, the following must hold:
- `Index Number` must increment by `1`.
- `Timestamp` must be strictly larger (i.e. at least one second later).
- `Confirmed Merkle Root` must match the Merkle tree hash of the IDs of all messages in _White Flag Ordering_ (as described in <a href="../TIP-0002/tip-0002.md#deterministically-ordering-the-tangle">TIP-2</a>) that are newly referenced. (This always includes at least one valid milestone message with `Last Milestone ID`.)
- `Applied Merkle Root` must match the Merkle tree hash of the not-ignored state-mutating transactions that are newly referenced (see <a href="../TIP-0002/tip-0002.md">TIP-2</a>).
- `Parents` must match the `Parents` field of the encapsulating _Message_, i.e. the _Message_ that contains the _Milestone Payload_.
- Options:
- `Milestone Option Type` must match one of the values described under [Milestone Options](#milestone-options).
- The option itself must pass syntactic validation.
- The options must be sorted in ascending order based on their `Milestone Option Type`.
- Signatures:
- `Signatures Count` must be at least the _Signature Threshold_ and at most the number of _Applicable Public Keys_ for the current milestone index.
- For each signature block the following must be true:
- `Signature Type` value must denote an `Ed25519 Signature`.
- `Public Key` must be contained in _Applicable Public Keys_ for the current milestone index.
- `Signature` must contain a valid signature for `Public Key`.
- The signature blocks must be sorted with respect to their `Public Key` in lexicographical order.
- Each `Public Key` must be unique.
- Given the type and length information, the _Milestone Payload_ must consume the entire byte array of the `Payload` field of the _Message_.

### Semantic validation

Semantic validation is defined in the context of all available messages.

- The milestone chain must not fork, i.e. there must not be two different, syntactically valid milestones with the same `Index Number`. In case of a fork, the correct state of the ledger cannot be derived from the milestones alone and usually the node implementation should alert the user and halt.

# Rationale

- Due to the layered design of messages and payloads, it is practically not possible to prevent reattachments of _Milestone Payloads_. Hence, this payload has been designed in a way to be independent from the message it is contained in. A milestone should be considered as a virtual marker (referencing `Parents`) rather than an actual message in the Tangle. This concept is compatible with reattachments and supports a cleaner separation of the message layers.
- Forcing matching `Parents` in the _Milestone Payload_ and its _Message_ makes it impossible to reattach the same payload at different positions in the Tangle. This does not prevent reattachments in general (a different, valid `Nonce`, for example would lead to a new Message ID) and it violates a strict separation of payload and message. However, it simplifies milestone processing as the position of the Message will be the same as the position encoded in the Milestone Payload. Having these clear structural properties seems to be more desirable than a strict separation of layers.
- While it is always possible to cryptographically prove that a message was confirmed by a given milestone by supplying all the messages of a path from the milestone to the message, such a proof can become rather large (depending on the messages). To simplify such proof-of-inclusions, the `Confirmed Merkle Root` of all the confirmed messages has been added.

# Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).