Skip to content

Commit 6b50aeb

Browse files
AliceInHunterlandAnnaShaleva
authored andcommitted
proposal: NeoFS block storage format
Signed-off-by: Ekaterina Pavlova <[email protected]>
1 parent f329e87 commit 6b50aeb

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

neofs-blocks.mediawiki

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<pre>
2+
NEP: TBD
3+
Title: NeoFS block storage format
4+
Author: Ekaterina Pavlova <[email protected]>
5+
Type: Informational
6+
Status: Draft
7+
Created: 2025-04-07
8+
</pre>
9+
10+
==Abstract==
11+
12+
This proposal outlines the specification for storing Neo blockchain blocks within
13+
NeoFS container.
14+
15+
==Motivation==
16+
17+
Neo node synchronization via P2P requires all headers and blocks (~700 bytes each, over 1 GB per year with
18+
15-second blocks) to remain available, limiting scalability as chains grow. Storing blocks in NeoFS
19+
provides a distributed alternative, reducing local storage, enabling on-demand fetches and allowing to drop
20+
blocks and headers from storage for most nodes.
21+
22+
==Specification==
23+
24+
===Block Storage Schema===
25+
26+
A single NeoFS container is used to store blocks of a single Neo network. Each container includes a fixed
27+
metadata attribute named `Magic` whose value is the network’s magic number in decimal representation. Each
28+
block is stored in a serialized representation following standard Neo block serialization rules as a
29+
separate NeoFS object with a unique OID and the following metadata attributes:
30+
31+
{| class="wikitable"
32+
! Attribute name !! Attribute value
33+
|-
34+
| Block || String representation of the block index in base 10.
35+
|-
36+
| Hash || Hexadecimal string of the block’s hash.
37+
|-
38+
| PrevHash || Hexadecimal string of the previous block’s hash.
39+
|-
40+
| BlockTime || Millisecond-precision timestamp when the block was created.
41+
|-
42+
| Timestamp || Second-precision timestamp when the block was uploaded.
43+
|}
44+
45+
These attributes are stored as NeoFS object metadata; the list of attributes MAY be extended.
46+
The object MAY include additional data after the block.
47+
48+
===Synchronization Algorithm===
49+
50+
Blocks stored in NeoFS and those synchronized via P2P both use the standard Neo block
51+
serialization format, ensuring compatibility across different synchronization methods.
52+
The NeoFS container serves as verified storage for downloading blocks.
53+
[https://github.com/nspcc-dev/neofs-api/blob/b7548cfb16426256f0a92c6d70a3ec794a6facb0/object/service.proto#L170 NeoFS SearchV2 API]
54+
should be used to fetch ordered chunks of block OIDs by Block attribute. Additional
55+
GE/GT/LE/LT SearchV2 filters may be applied to the Block attribute value to filter
56+
out required range of blocks.
57+
[https://github.com/nspcc-dev/neofs-api/blob/b7548cfb16426256f0a92c6d70a3ec794a6facb0/object/service.proto#L48 NeoFS Get API]
58+
should be used to fetch blocks by retrieved OIDs.
59+
60+
Downloaded blocks are inserted into the blockchain using the same logic as in the
61+
P2P synchronization protocol.
62+
63+
==Rationale==
64+
65+
Storing each block as a self-contained NeoFS object moves historical data off full nodes
66+
while preserving byte-exact compatibility with the P2P format. Standard metadata makes
67+
blocks easily discoverable without custom indices, and NeoFS gives durability and fast
68+
parallel fetches. The proposed scheme is implemented as an experimental extension of NeoGo
69+
node ([https://github.com/nspcc-dev/neo-go/issues/3496 nspcc-dev/neo-go#3496]) and
70+
proved to be efficient.
71+
72+
== References ==
73+
74+
* [https://github.com/neo-project/neo/issues/3463 Using NeoFS to store blocks and snapshots]
75+
76+
== Test cases ==
77+
78+
An example of a [https://rest.fs.neo.org/v1/objects/3RCdP3ZubyKyo8qFeo7EJPryidTZaGCMdUjqFJaaEKBV/by_id/Fu7yQzspvLJwSGJNK64xeeyMdWXtU5B5b1es6KSxUag1 block object]:
79+
<pre>
80+
ID: Fu7yQzspvLJwSGJNK64xeeyMdWXtU5B5b1es6KSxUag1
81+
CID: 3RCdP3ZubyKyo8qFeo7EJPryidTZaGCMdUjqFJaaEKBV
82+
Owner: NVvY1FF67XJ2GTVhy9FqiZGC4jEQtvjmHt
83+
CreatedAt: 28202
84+
Size: 697
85+
HomoHash: 45c98e627910d9b915d58368493789ce49ca194626f16ea5bf6b57bb2cce462921a1d3faf682d252a804b0555ca48905286222ee9209b3ff1ce4677a082ffd4d
86+
Checksum: fa6cedddfec3a61157c4a12e25f81e85c0f92aac70317d6df7fe193f983b4917
87+
Type: REGULAR
88+
Attributes:
89+
Block=1
90+
Primary=0
91+
Hash=5f3fbb43d1e516fe07771e2e873ebc9e2810662401acf603a775aace486220bd
92+
PrevHash=1f4d1defa46faa5e7b9b8d3f79a06bec777d7c26c4aa5f6f5899a291daa87c15
93+
BlockTime=1627894840919
94+
Timestamp=1734362616 (2024-12-16 18:23:36 +0300 MSK)
95+
ID signature:
96+
public key: 02a4920745d86db224c179c936606dc0e4620edad13d568ef036da279352e45f2b
97+
signature: 0443ff20d15952759b5101a7d223d70eb992260fd9ad5aecb404a97448b2ea54bd1ad783b12ccddba0097dd6608b55ccac9215c5715f9589ec6a555542ead6dc00
98+
[Block Binary Data]
99+
</pre>
100+
101+
== Implementation ==
102+
103+
* Go: [https://github.com/nspcc-dev/neo-go/blob/965ae2746cd1a01aba3b4114e1ea26ca7349f34b/cli/util/upload_bin.go utility tool that uploads blocks to NeoFS container]
104+
* Go: [https://github.com/nspcc-dev/neo-go/blob/965ae2746cd1a01aba3b4114e1ea26ca7349f34b/pkg/services/blockfetcher/blockfetcher.go node service that fetches blocks from NeoFS container as an alternative to P2P synchronization]

0 commit comments

Comments
 (0)