Skip to content
This repository has been archived by the owner on Feb 18, 2025. It is now read-only.

TIP-24 Tangle Block (Stardust) #55

Merged
merged 15 commits into from
Jul 21, 2022
178 changes: 178 additions & 0 deletions tips/TIP-0024/tip-0024.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
tip: 24
title: Tangle Block
description: Generalization of the Tangle transaction concept
author: Wolfgang Welz (@Wollac) <wolfgang.welz@iota.org>
discussions-to: https://github.com/iotaledger/tips/pull/55
status: Draft
type: Standards
layer: Core
replaces: 6
created: 2022-01-24
---

# Abstract

The Tangle is the graph data structure behind IOTA. In the legacy IOTA protocol, the vertices of the Tangle are represented by transactions. This document proposes an abstraction of this idea where the vertices are generalized *blocks*, which then contain the transactions or other structures that are processed by the IOTA protocol. Just as before, each block directly approves other blocks, which are known as _parents_.

The blocks can contain payloads. These are core payloads that will be processed by all nodes as part of the IOTA protocol. Some payloads may have other nested payloads embedded inside. Hence, parsing is done layer by layer.

# Motivation

To better understand this layered design, consider the Internet Protocol (IP), for example: There is an Ethernet frame that contains an IP payload. This in turn contains a TCP packet that encapsulates an HTTP payload. Each layer has a certain responsibility and once this responsibility is completed, we move on to the next layer.

The same is true with how blocks are parsed. The outer layer of the block enables the mapping of the block to a vertex in the Tangle and allows us to perform some basic validation. The next layer may be a transaction that mutates the ledger state, and one layer further may provide some extra functionality on the transactions to be used by applications.

By making it possible to add and exchange payloads, an architecture is being created that can easily be extended to accommodate future needs.

# Specification

## Block ID

The *Block ID* is the [BLAKE2b-256](https://tools.ietf.org/html/rfc7693) hash of the entire serialized block.

## Serialized Layout

The following table describes the serialization of a _Block_ 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>Protocol Version</td>
<td>uint8</td>
<td> Protocol version number of the block.</td>
</tr>
<tr>
<td>Parents Count</td>
<td>uint8</td>
<td>The number of blocks 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 block.
</blockquote>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>Block ID</td>
<td>ByteArray[32]</td>
<td>The Block ID of the parent.</td>
</tr>
</table>
</details>
</td>
</tr>
<tr>
<td>Payload Length</td>
<td>uint32</td>
<td>The length of the following payload in bytes. A length of 0 means no payload will be attached.</td>
</tr>
<tr>
<td valign="top">Payload <code>optOneOf</code></td>
<td colspan="2">
<details open="true">
<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>
<td>Nonce</td>
<td>uint64</td>
<td>The nonce which lets this block fulfill the PoW requirement.</td>
</tr>
</table>

## Syntactic validation

The Tangle can only contain syntactically valid blocks. Invalid must be rejected by the node.
The following criteria defines whether the block passes the syntactic validation:

- The total length of the serialized block must not exceed `Max Block Length`.
- `Protocol Version` must match the `Protocol Version` config parameter of the node.
- Parents:
- `Parents Count` must be at least 1 and not larger than `Max Parents Count`.
- `Parents` must be sorted in lexicographical order.
- Each `Block ID` must be unique.
- 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.
- `Nonce` must be valid with respect to the PoW condition described under [Payloads](#payloads). The PoW score itself is computed according to [TIP-12](../TIP-0012/tip-0012.md).
- There must be no trailing bytes after all block fields have been parsed.

### PoW validation

The PoW that needs to be performed for each block protects the network against denial-of-service attacks where in a short time too many blocks are issued for the nodes to process. As the processing time of a block heavily depends on the contained payload, the PoW check can also depend on the `Payload Type` and is described under [Payloads](#payloads).
It is important to note, that the actual parsing and validating of a payload can be computationally expensive. Thus, it is recommended to first parse the block with all its fields including `Payload Type` (but not parsing or validating the actual payload `Data Fields`). Now, simple syntactic validation steps &ndash; including PoW validation &ndash; can be performed and invalid blocks already filtered out before the payload is validated. With this approach, payload-based PoW validation is not significantly more expensive than payload-agnostic validation.

## Payloads

While blocks without a payload, i.e. `Payload Length` set to zero, are valid, such blocks do not contain any information. As such, blocks usually contain a payload. The detailed specification of each payload type is out of scope of this TIP. The following table lists all currently specified payloads that can be part of a block and links to their specification:

| Payload Name | Type Value | TIP | PoW Condition |
| ------------ | ---------- | --------------------------------- | ------------------------------ |
| No Payload | - | - | PoW score ≥ `Min PoW Score` |
| Tagged Data | 5 | [TIP-23](../TIP-0023/tip-0023.md) | PoW score ≥ `Min PoW Score` |
| Transaction | 6 | [TIP-20](../TIP-0020/tip-0020.md) | PoW score ≥ `Min PoW Score` |
| Milestone | 7 | [TIP-29](../TIP-0029/tip-0029.md) | `nonce` = `0x0000000000000000` |

## Example

Below is the full serialization of a valid block with a _Tagged Data Payload_. The tag is the "IOTA" ASCII string and the data is the "hello world" ASCII string. Bytes are expressed as hexadecimal numbers.

- Protocol Version (1-byte): `00` (0)
- Parents Count (1-byte): `02` (2)
- Parents (64-byte):
- `210fc7bb818639ac48a4c6afa2f1581a8b9525e20fda68927f2b2ff836f73578`
- `db0fa54c29f7fd928d92ca43f193dee47f591549f597a811c8fa67ab031ebd9c`
- Payload Length (4-byte): `18000000` (24)
- Payload (24-byte):
- Payload Type (4-byte): `05000000` (5)
- Tag Length (1-byte): `04` (4)
- Tag (4-byte): `494f5441` ("IOTA")
- Data (15-byte):
- Length (4-byte): `0b000000` (11)
- Data (11-byte): `68656c6c6f20776f726c64` ("hello world")
- Nonce (8-byte): `ce6d000000000000` (28110)

# Rationale and alternatives

Instead of creating a layered approach, we could have simply created a flat transaction block that is tailored to mutate the ledger state, and try to fit all the use cases there. For example, with the tagged data use case, we could have filled some section of the transaction with that particular data. Then, this transaction would not correspond to a ledger mutation but instead only carry data.

This approach seems less extensible. It might have made sense if we had wanted to build a protocol that is just for ledger mutating transactions, but we want to be able to extend the protocol to do more than that.

# Copyright

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