You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -20,7 +20,7 @@ a Filecoin node with a Filecoin snapshot.
20
20
## Abstract
21
21
<!--A short (~200 words) description of the technical issue being addressed.-->
22
22
23
-
The Filecoin ecosystem existed for years without specifying the snapshot format. That was fine until the advent of F3 and the resulting need to update the format in a coordinated way.
23
+
The Filecoin ecosystem existed for years without specifying the snapshot format. That was fine until the advent of F3 and the resulting need to update the format in a coordinated way.
24
24
25
25
This document outlines:
26
26
- "v1": the original accepted format found implementations through 2025 and
@@ -37,18 +37,19 @@ The time cost and the network bandwidth usage for a new Filecoin node to catch u
37
37
We propose the below changes to the Filecoin CAR snapshot format.
38
38
39
39
- Change CAR root to be a CID that points to a CBOR-encoded [`SnapshotMetadata`](#snapshotmetadata) struct that is stored as the first data block in the CAR.
40
-
- Store the raw [`F3Snapshot`](#f3snapshot) bytes as the second data block in the CAR when `F3Data != nil` in the metadata.
40
+
- Store the raw [`F3Data`](#f3data) bytes as the second data block in the CAR when `F3Data != nil` in the metadata.
41
41
42
42
### SnapshotMetadata
43
43
44
44
```go
45
45
typeSnapshotMetadata {
46
+
Versionuint64// required, format version for SnapshotMetadata. Only "2" is supported since "v1" was implied in the original format that predates `SnapshotMetadata`.
46
47
HeadTipsetKey []Cid// required
47
-
F3Data *Cid // optional
48
+
F3Data *Cid // optional, points to F3Data structure. The only supported codec is "RAW" (0x55).
48
49
}
49
50
```
50
51
51
-
### F3Snapshot
52
+
### F3Data
52
53
53
54
An F3 snapshot contains one header block and N data blocks (where N>0) in the below format:
54
55
@@ -58,24 +59,31 @@ A header block is a CBOR-encoded [`F3SnapshotHeader`](#f3snapshotheader) with a
58
59
59
60
`[varint-encoded byte length of "CBOR-encoded F3SnapshotHeader"] [CBOR-encoded F3SnapshotHeader]`
60
61
62
+
A data block is a CBOR-encoded [`FinalityCertificate`](#finalitycertificate) with a length prefix in the below format:
-`FinalityCertificate`s should be ordered by `GPBFTInstance` in ascending order for sequential validation and intermediate power table calculation. This also ensures deterministic generation of F3 snapshot from a given F3 finality certificate chain.
68
+
- The first and last `FinalityCertificate` instances should match those in the header, respectively.
69
+
- This [CARv1](https://ipld.io/specs/transport/car/carv1)-like format is ideal for dumping blocks via streaming reads as the Header can be loaded first and minimal state is required for ongoing parsing.
70
+
61
71
### F3SnapshotHeader
62
72
63
73
```go
64
74
typeF3SnapshotHeaderstruct {
65
75
Versionuint64
66
-
FirstInstanceuint64// The first FinalityCertificate.GPBFTInstance in the "data blocks" that follow the header.
67
-
LatestInstanceuint64// The last FinalityCertificate.GPBFTInstance in the "data blocks" that follow the header.
76
+
FirstInstanceuint64
77
+
LatestInstanceuint64
68
78
InitialPowerTable gpbft.PowerEntries
69
79
}
70
80
```
71
81
72
-
A data block is a CBOR-encoded [`FinalityCertificate`](#finalitycertificate) with a length prefix in the below format:
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/chain.go#L194>
107
+
//
108
+
// A chain of tipsets comprising a base (the last finalised tipset from which the chain extends).
109
+
// and (possibly empty) suffix.
110
+
// Tipsets are assumed to be built contiguously on each other,
111
+
// though epochs may be missing due to null rounds.
112
+
// The zero value is not a valid chain, and represents a "bottom" value
113
+
// when used in a Granite message.
114
+
typeECChainstruct {
115
+
TipSets []*TipSet
116
+
117
+
key ECChainKey`cborgen:"ignore"`
118
+
keyLazyLoader sync.Once`cborgen:"ignore"`
119
+
}
120
+
121
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/types.go#L123>
122
+
typeSupplementalDatastruct {
123
+
// Commitments is the Merkle-tree of instance-specific commitments. Currently
124
+
// empty but this will eventually include things like snark-friendly power-table
125
+
// commitments.
126
+
Commitments [32]byte`cborgen:"maxlen=32"`
127
+
// PowerTable is the DagCBOR-blake2b256 CID of the power table used to validate
128
+
// the next instance, taking lookback into account.
129
+
PowerTable cid.Cid// []PowerEntry
130
+
}
131
+
132
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/certs/certs.go#L31>
133
+
typePowerTableDiff []PowerTableDelta
134
+
135
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/certs/certs.go#L16>
136
+
//
137
+
// PowerTableDelta represents a single power table change between GPBFT instances. If the resulting
138
+
// power is 0 after applying the delta, the participant is removed from the power table.
139
+
typePowerTableDeltastruct {
140
+
// Participant with changed power
141
+
ParticipantID gpbft.ActorID
142
+
// Change in power from base (signed).
143
+
PowerDelta gpbft.StoragePower
144
+
// New signing key if relevant (else empty)
145
+
SigningKey gpbft.PubKey`cborgen:"maxlen=48"`
146
+
}
147
+
148
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/types.go#L15>
149
+
typeActorIDuint64
150
+
151
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/types.go#L17>
152
+
typeStoragePower = big.Int
153
+
154
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/types.go#L19>
155
+
typePubKey []byte
156
+
157
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/chain.go#L52>
158
+
//
159
+
// TipSet represents a single EC tipset.
160
+
typeTipSetstruct {
161
+
// The EC epoch (strictly increasing).
162
+
Epochint64
163
+
// The tipset's key (canonically ordered concatenated block-header CIDs).
164
+
KeyTipSetKey`cborgen:"maxlen=760"`// 20 * 38B
165
+
// Blake2b256-32 CID of the CBOR-encoded power table.
166
+
PowerTable cid.Cid
167
+
// Keccak256 root hash of the commitments merkle tree.
168
+
Commitments [32]byte`cborgen:"maxlen=32"`
169
+
}
170
+
171
+
// Defined at <https://github.com/filecoin-project/go-f3/blob/v0.8.7/gpbft/chain.go#L20>
172
+
//
173
+
// TipSetKey is the canonically ordered concatenation of the block CIDs in a tipset.
174
+
typeTipSetKey = []byte
97
175
```
98
176
99
-
Notes:
100
-
-`FinalityCertificate`s should be ordered by `GPBFTInstance` in ascending order, thus they can be validated and intermediate power tables can be generated while data blocks are being read in a stream.
101
-
- The first and last `FinalityCertificate` instances should match those in the header, respectively.
177
+
### Filecoin snapshot v1 format
178
+
179
+
We define the existing Filecoin snapshot format as v1 here for future reference.
180
+
181
+
Filecoin snapshot v1 is in [CARv1](https://ipld.io/specs/transport/car/carv1/) format.
182
+
183
+
The roots array in the `CarHeader` stores the tipset keys of the chain head in the snapshot.
184
+
185
+
The data blocks are chain IPLD blocks generated in a deterministic depth-first traversal order during chain export. Thus a snapshot is deterministic for a given chain head and the number of state trees to include. (The details of the chain traversal algorithm can be found in Filecoin node implementations)
186
+
187
+
```go
188
+
typeCarHeaderstruct {
189
+
version Int
190
+
roots [&Any]
191
+
}
192
+
```
102
193
103
194
## Backwards Compatibility
104
195
<!--All FIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The FIP must explain how the author proposes to deal with these incompatibilities. FIP submissions without a sufficient backwards compatibility treatise may be rejected outright.-->
105
196
106
-
- A Filecoin node should try to read a snapshot CAR in the proposed format. A failure to successfully decode the blocked referenced as as the CAR's single root using the schema presented above, a snapshot reader may fallback to the old format and maintain backward compatibility. Additional failures to decode original snapshot format would indicate a fatal error.
107
-
- CLI options for implementations like Forest and Lotus should remain unchanged to make it transparent to the node users.
108
-
- The code change in all Filecoin nodes should be shipped with a network upgrade, and the Filecoin snapshot providers should only start publishing with the new format after the mainnet upgrade finishes to avoid potential errors during snapshot import for node users.
197
+
- A Filecoin node should try to read a snapshot CAR in the proposed format. A failure to successfully decode the block referenced as the CAR's single root using the schema presented above, a snapshot reader may fallback to the old format and maintain backward compatibility. Additional failures to decode original snapshot format would indicate a fatal error.
198
+
- CLI options for implementations like Forest, Lotus and Venus should remain unchanged to make it transparent to the node users.
199
+
- The code change in all Filecoin nodes should be shipped with a network upgrade, and the Filecoin snapshot providers should only start publishing with the new format after the mainnet upgrade finishes to avoid potential errors during snapshot import for node users. That is to say:
200
+
- Before NV27,
201
+
- a node reads both v1 and v2 snapshots
202
+
- a node generates v1 snapshot by default
203
+
- node provides publish and host v1 snapshots.
204
+
- After NV27,
205
+
- a node reads both v1 and v2 snapshots
206
+
- a node generates v2 snapshot by default
207
+
- node providers publish and host v2 snapshots.
109
208
110
209
## Test Cases
111
210
<!--Test cases for an implementation are mandatory for FIPs affecting consensus changes. Other FIPs can choose to include links to test cases if applicable.-->
@@ -116,7 +215,8 @@ Notes:
116
215
This change has minimal security implications as the additional F3 data are also stored in the node database, unencrypted. Key considerations:
117
216
118
217
-**Integrity**: The F3 snapshot can be validated.
119
-
-**Performance** The F3 snapshot data blocks can be read, validated and imported in a stream.
218
+
-**Performance** The F3 snapshot data blocks can be read, validated and imported in a stream, without requiring to hold the entire finality certificate chain in the RAM. To facilitate this, it might require some new API(s) in the CAR reader package.
219
+
-**Cyclic structure** Not applicable. The F3 snapshot does not build any cyclic graph during import and export, only a single block(certificate) is required to be held in the RAM.
120
220
121
221
The change does not introduce new attack vectors or modify existing security properties of the protocol.
0 commit comments