# Blockchain

The blockchain stores the metadata of files published by the user, profile data, and social interactions. The blockchain is implemented according to the Peernet Whitepaper published at [peernet.org](https://peernet.org).

The blockchain is a consecutive sequence of blocks linked together by their previous hash. Each block may contain one or multiple records.

All blocks and the blockchain header are stored locally in a key-value database.

# Encoding

## Header

The blockchain header is not part of the Peernet specification. Below is the encoding of the blockchain header. The public key can be extracted from the signature.

```
Offset  Size   Info
0       8      Height of the blockchain
8       8      Version of the blockchain
16      2      Format of the blockchain. This provides backward compatibility.
18      65     Signature
```

## Block

Encoding of a block (it is the same stored in the database and shared in a message):

```
Offset  Size   Info
0       65     Signature of entire block
65      32     Hash (blake3) of last block. 0 for first one.
97      8      Blockchain version number
105     4      Block number
109     4      Size of entire block including this header
113     2      Count of records that follow
```

Each record inside the block has this basic structure:

```
Offset  Size   Info
0       1      Record type
1       8      Date created. This remains the same in case of block refactoring.
9       4      Size of data
13      ?      Data (encoding depends on record type)
```

# Internals

## Block Size

Peers must accept a minimum block size of 1 KB.

The target block size (for generating new blocks) is defined via `TargetBlockSize`. If records cannot fit within that target size, they are added into a new block.

Small block sizes ensure that the block will be transferred via blockchain exchange and cached in DHT.
Large blocks may be ignored by clients for size and spam reasons, resulting in decreased discoverability.

## Edge Cases

### Deleting vs Replacing Records

If a specific record shall be replaced, it should be deleted and a new block containing the replacement record shall be created.

Inline replacement of a record in a block would lead to problems:
* The block size could increase which could push the block size above the recommended limit.
* In case of `RecordTypeFile` records, they may use `RecordTypeTagData` records for compression. If a single record is to be replaced 1:1 with another record, this could not take advantage of this embedded compression algorithm.
