-
Notifications
You must be signed in to change notification settings - Fork 54
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
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
d85fd9b
add TIP-30
Wollac d7241c8
Merge remote-tracking branch 'upstream/main' into milestone-with-sign…
Wollac c09bd70
Swap TIP number
lzpap 612d963
Introduce new payload type value
Wollac a4f3cbb
Add metadata
Wollac 8e4642b
Update with milestone options
Wollac 900a770
update receipt TIP
Wollac c1f88e4
Clarify encapsulating message
Wollac c3ab001
Remove PoW Milestone Option
Wollac ff9d8a4
Changes "Last Milestone ID" to "Previous Milestone ID"
lzpap a60274b
Rename "messages" to "blocks"
lzpap a577cb9
Add WIP Protocol Parameteres Milestone Option
lzpap 6505585
Add Protocol Version to Milestone Essence
lzpap 75cc4bc
describe Protocol Parameters Milestone Option validation
Wollac 68c26e2
add Metadata limit
Wollac 13d84da
Fix typo
Wollac f2a84e2
Remove PoW option comment
Wollac 051a20c
remove nonce reference
Wollac ff05c48
Update tips/TIP-0029/tip-0029.md
lzpap 3835532
Update tips/TIP-0029/tip-0029.md
lzpap d2ee439
remove leagacy IOTA reference
Wollac File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,242 @@ | ||
--- | ||
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 | ||
--- | ||
|
||
# Summary | ||
|
||
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. | ||
|
||
# Detailed design | ||
|
||
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. | ||
- _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_. | ||
|
||
## Structure | ||
|
||
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 structure describes the entirety of a _Milestone Payload_ in its serialized form ([TIP-6 Data Types](../TIP-0006/tip-0006.md#data-types)): | ||
|
||
<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>uint64</td> | ||
<td>The Unix time (seconds since Unix epoch) at which the milestone was issued.</td> | ||
</tr> | ||
<tr> | ||
<td>Parents Count</td> | ||
<td>uint8</td> | ||
<td>The number of messages that are directly approved.</td> | ||
</tr> | ||
<tr> | ||
<td valign="top">Parents <code>anyOf</code></td> | ||
<td colspan="2"> | ||
<details> | ||
<summary>Parent</summary> | ||
<blockquote> | ||
References another directly approved message. | ||
</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>Inclusion Merkle Root</td> | ||
<td>ByteArray[32]</td> | ||
<td>The Merkle tree hash (BLAKE2b-256) of the message IDs of all the not-ignored state-mutating transaction payloads referenced by the milestone (<a href="../TIP-0004/tip-0004.md">TIP-0004</a>).</td> | ||
</tr> | ||
<tr> | ||
<td>Next PoW Score</td> | ||
<td>uint32</td> | ||
<td>The new PoW score all messages should adhere to. If 0 then the PoW score should not change.</td> | ||
</tr> | ||
<tr> | ||
<td>Next PoW Score Milestone Index</td> | ||
<td>uint32</td> | ||
<td>The index of the first milestone that will require a new minimal pow score for applying transactions. This field comes into effect only if the <code>Next PoW Score</code> field is not 0.</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 milestone issuer, e.g. internal state. A leading uint16 denotes its length.</td> | ||
</tr> | ||
<tr> | ||
<td>Payload Length</td> | ||
<td>uint32</td> | ||
<td>The length in bytes of the optional payload.</td> | ||
</tr> | ||
<tr> | ||
<td valign="top">Payload <code>optOneOf</code></td> | ||
<td colspan="2"> | ||
<details> | ||
<summary>Generic Payload</summary> | ||
<blockquote> | ||
An outline of a generic payload | ||
</blockquote> | ||
<table> | ||
<tr> | ||
<th>Name</th> | ||
<th>Type</th> | ||
<th>Description</th> | ||
</tr> | ||
<tr> | ||
<td>Payload Type</td> | ||
<td>uint32</td> | ||
<td> | ||
The type of the payload. It will instruct the node how to parse the fields that follow. | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>Data Fields</td> | ||
<td>ANY</td> | ||
<td>A sequence of fields, where the structure depends on <code>Payload Type</code>.</td> | ||
</tr> | ||
</table> | ||
</details> | ||
<tr> | ||
</table> | ||
</details> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>Signatures Count</td> | ||
<td>uint8</td> | ||
<td>Number of signature entries. The number must match the field <code>Keys Count</code>.</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> | ||
|
||
## Generation | ||
|
||
- Generate a new _Milestone Essence_ corresponding to the Coordinator milestone. | ||
- Transmit the serialized _Milestone Essence_ to the corresponding number of signature service providers. | ||
- The signature provider service will sign the received serialized bytes as-is. | ||
- The signature provider will serialize the signature bytes and return them to the Coordinator. | ||
- Fill the `Signatures` field of the milestone payload with the received signature bytes. | ||
- Generate a *Message* as defined in [TIP-6](../TIP-0006/tip-0006.md) using the same `Parents` as in the created _Milestone Payload_. | ||
|
||
## Syntactic validation | ||
|
||
- Essence: | ||
- `Parents` of the payload must match `Parents` of the encapsulating _Message_. | ||
- PoW score: | ||
- If `Next Pow Score` is zero, `Next PoW Score Milestone Index` must also be zero. | ||
- Otherwise `Next PoW Score Milestone Index` must be larger than `Index Number`. | ||
- Payload (if present): | ||
- `Payload Type` must match one of the values described under [Payloads](#payloads). | ||
- `Data fields` must be correctly parsable in the context of the `Payload Type`. | ||
- The payload itself must pass syntactic validation. | ||
- 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. | ||
- 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_. | ||
|
||
### Payloads | ||
|
||
The _Milestone Payload_ itself can contain another payload as described in general in [TIP-6](../TIP-0006/tip-0006.md). The following table lists all the payloads types that can be nested inside a _Milestone Payload_ as well as links to the corresponding specification: | ||
|
||
| Payload Name | Type Value | TIP | | ||
| ------------ | ---------- | ------------------------------------------ | | ||
| Receipts | 4 | [TIP-15](../TIP-0015/tip-0015.md#receipts) | | ||
|
||
# Rationale and alternatives | ||
|
||
- Instead of using EdDSA we could have chosen ECDSA. Both algorithms are well supported and widespread. However, signing with ECDSA requires fresh randomness while EdDSA does not. Especially in the case of milestones where essences are signed many times using the same key, this is a crucial property. | ||
- 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. | ||
|
||
# Copyright | ||
|
||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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):
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iotaledger/hornet#1733