Skip to content

Commit dc1f6e6

Browse files
authored
Merge branch 'master' into fix/prove/request-parents-once
2 parents 4b46377 + 5fc1fce commit dc1f6e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+819
-512
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
name: Test (stable) in release profile
7979
command: |
8080
cargo +stable test --verbose --release --frozen --all
81-
cargo +stable build --examples --release --frozen --all
81+
RUSTFLAGS="-D warnings" cargo +stable build --examples --release --frozen --all
8282
8383
ffi_regression:
8484
docker:

CONTRIBUTING.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Contributing
2+
3+
Welcome, it is great that you found your way here. In order to make the best of all our time, we have gathered some notes
4+
below which we think can be helpful when contributing to this project.
5+
6+
## Getting Started
7+
8+
Please start by reviewing this file.
9+
10+
## Coding Standards
11+
12+
- No compiler warnings.
13+
- No [clippy](https://github.com/rust-lang/rust-clippy) warnings.
14+
- Minimize use of `unsafe` and justify usage in comments.
15+
- Prefer `expect` with a good description to `unwrap`.
16+
- Write unit tests in the same file.
17+
- Format your code with `rustfmt`
18+
- Code should compile on `stable` and `nightly`. If adding `nightly` only features they should be behind a flag.
19+
- Write benchmarks for performance sensitive areas. We use [criterion.rs](https://github.com/japaric/criterion.rs).
20+
21+
22+
## General Guidelines
23+
- PRs require code owner approval to merge.
24+
- Please scope PRs to areas in which you have expertise. This code is still close to research.
25+
- Welcome contribution areas might include:
26+
- SNARKs
27+
- Proof-of-replication
28+
- Rust improvements
29+
- Optimizations
30+
- Documentation (expertise would require careful reading of the code)
31+
32+
## Resources for learning Rust
33+
34+
- Beginners
35+
- [The Rust Book](https://doc.rust-lang.org/book/)
36+
- [Rust Playground](https://play.rust-lang.org/)
37+
- [Rust Docs](https://doc.rust-lang.org/)
38+
- [Clippy](https://github.com/rust-lang/rust-clippy)
39+
- [Rustfmt](https://github.com/rust-lang/rustfmt)
40+
- Advanced
41+
- What does the Rust compiler do with my code? [Godbolt compiler explorer](https://rust.godbolt.org/)
42+
- How to safely write unsafe Rust: [The Rustonomicon](https://doc.rust-lang.org/nomicon/)
43+
- Did someone say macros? [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
44+
45+
## Licensing
46+
47+
As mentioned in the [readme](README.md) all contributions are dual licensed under Apache 2 and MIT.

README.md

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Filecoin Proving Subsystem (FPS)
22

3-
The **Filecoin Proving Subsystem** provides the storage proofs required by the Filecoin protocol. It is implemented entirely in Rust, as a series of partially inter-dependent crates – some of which export C bindings to the supported API. This decomposition into distinct crates/modules is relatively recent, and in some cases current code has not been fully refactored to reflect the intended eventual organization.
3+
The **Filecoin Proving Subsystem** provides the storage proofs required by the Filecoin protocol. It is implemented entirely in Rust, as a series of partially inter-dependent crates – some of which export C bindings to the supported API. This decomposition into distinct crates/modules is relatively recent, and in some cases current code has not been fully refactored to reflect the intended eventual organization.
44

55
There are currently four different crates:
66

@@ -23,23 +23,23 @@ There are currently four different crates:
2323
A sector database abstracting away underlying storage considerations. This abstraction will allow for alternate implementations mapping logical sectors to physical storage – facilitating both support for miner specialization, and configurable adaptation to a given miner’s physical hardware and preferences.
2424

2525
- [**Storage Backend (`storage-backend`)**](./storage-backend)
26-
The `storage-backend` crate is intended to contain abstractions and implementations of non-filecoin-specific storage mechanisms require by `storage-proofs`. However, for the sake of simplicity, it is currently an empty placeholder.
26+
The `storage-backend` crate is intended to contain abstractions and implementations of non-Filecoin-specific storage mechanisms require by `storage-proofs`. However, for the sake of simplicity, it is currently an empty placeholder.
2727

2828
![FPS crate dependencies](/img/fps-dependencies.png?raw=true)
2929

3030
## Design Notes
3131

32-
Earlier in the design process, we considered implementing what has become the **FPS** in Go – as a wrapper around potentially multiple SNARK circuit libraries. We eventually decided to use [bellman](https://github.com/zkcrypto/bellman) – a library developed by ZCash, which supports efficient pedersen hashing inside of SNARKs. Having made that decision, it was natural and efficient to implement the entire subsystem in Rust. We considered the benefits (self-contained code base, ability to rely on static typing across layers) and costs (developer ramp-up, sometimes unwieldiness of borrow-checker) as part of that larger decision and determined that the overall project benefits (in particular ability to build on Zcash’s work) outweighed the costs.
32+
Earlier in the design process, we considered implementing what has become the **FPS** in Go – as a wrapper around potentially multiple SNARK circuit libraries. We eventually decided to use [bellman](https://github.com/zkcrypto/bellman) – a library developed by Zcash, which supports efficient pedersen hashing inside of SNARKs. Having made that decision, it was natural and efficient to implement the entire subsystem in Rust. We considered the benefits (self-contained codebase, ability to rely on static typing across layers) and costs (developer ramp-up, sometimes unwieldiness of borrow-checker) as part of that larger decision and determined that the overall project benefits (in particular ability to build on Zcash’s work) outweighed the costs.
3333

34-
We also considered whether the **FPS** should be implemented as a standalone binary accessed from [**`go-filecoin`**](https://github.com/filecoin-project/go-filecoin) either as a single-invocation CLI or as a long-running daemon process. We chose to bundle the **FPS** as an FFI dependency for both the simplicity of having a Filecoin node be deliverable as a single monolithic binary, and for the (perceived) relative development simplicity of the API implementation.
34+
We also considered whether the **FPS** should be implemented as a standalone binary accessed from [**`go-filecoin`**](https://github.com/filecoin-project/go-filecoin) either as a single-invocation CLI or as a long-running daemon process. Bundling the **FPS** as an FFI dependency was chosen for both the simplicity of having a Filecoin node deliverable as a single monolithic binary, and for the (perceived) relative development simplicity of the API implementation.
3535

36-
If at any point it were to become clear that the FFI approach is irredeemably problematic, the option of moving to a standalone **FPS** remains. However, we have now already solved the majority of technical problems associated with calling from Go into Rust even while allowing for a high degree of runtime configurability. Therefore, it seems most likely that we continue down the path in which we have already invested and begin to reap reward.
36+
If at any point it were to become clear that the FFI approach is irredeemably problematic, the option of moving to a standalone **FPS** remains. However, the majority of technical problems associated with calling from Go into Rust are now solved, even while allowing for a high degree of runtime configurability. Therefore, continuing down the same path we have already invested in, and have begun to reap rewards from, seems likely.
3737

3838
## Install and configure Rust
3939

40-
**NOTE:** If you have installed `rust-proofs` incidentally, as a submodule of `go-filecoin`, then you may already have installed Rust.
40+
**NOTE:** If you have installed `rust-fil-proofs` incidentally, as a submodule of `go-filecoin`, then you may already have installed Rust.
4141

42-
The instructions below assume you have independently installed `rust-proofs` in order to test, develop, or experiment with it.
42+
The instructions below assume you have independently installed `rust-fil-proofs` in order to test, develop, or experiment with it.
4343

4444
[Install Rust.](https://www.rust-lang.org/en-US/install.html)
4545

@@ -93,13 +93,13 @@ To benchmark the examples you can [bencher](src/bin/bencher.rs).
9393

9494
The results are written into the `.bencher` directory, as JSON files. The benchmarks are controlled through the [bench.config.toml](bench.config.toml) file.
9595

96-
Note: on macOS you need `gtime` (`brew install gnu-time`), as the built in `time` command is not enough.
96+
Note: On macOS you need `gtime` (`brew install gnu-time`), as the built in `time` command is not enough.
9797

9898
## Logging
9999

100100
For better logging with backtraces on errors, developers should use `expects` rather than `expect` on `Result<T, E>` and `Option<T>`.
101101

102-
Developers can control `rust-proofs` logging through environment variables:
102+
Developers can control `rust-fil-proofs` logging through environment variables:
103103

104104
-
105105
`RUST_PROOFS_LOG_JSON`
@@ -138,7 +138,7 @@ can run the following command:
138138
RUSTFLAGS="-Z sanitizer=leak" cargo run --release --package filecoin-proofs --example ffi --target x86_64-unknown-linux-gnu
139139
```
140140

141-
If using OSX, you'll have to run the leak detection from within a Docker
141+
If using mac OS, you'll have to run the leak detection from within a Docker
142142
container. After installing Docker, run the following commands to build and run
143143
the proper Docker image and then the leak detector itself:
144144

@@ -156,25 +156,25 @@ docker build -t foo -f ./Dockerfile-ci . && \
156156

157157
## Generate Documentation
158158

159-
First, navigate to the `rust-proofs` directory.
160-
- If you installed `rust-proofs` automatically as a submodule of `go-filecoin`:
159+
First, navigate to the `rust-fil-proofs` directory.
160+
- If you installed `rust-fil-proofs` automatically as a submodule of `go-filecoin`:
161161
```
162-
> cd <go-filecoin-install-path>/go-filecoin/proofs/rust-proofs
162+
> cd <go-filecoin-install-path>/go-filecoin/proofs/rust-fil-proofs
163163
```
164164

165-
- If you cloned `rust-proofs` manually, it will be wherever you cloned it:
165+
- If you cloned `rust-fil-proofs` manually, it will be wherever you cloned it:
166166
```
167-
> cd <install-path>/rust-proofs
167+
> cd <install-path>/rust-fil-proofs
168168
```
169169

170-
[Note that the version of `rust-proofs` included in `go-filecoin` as a submodule is not always the current head of `rust-proofs/master`. For documentation corresponding to the latest source, you should clone `rust-proofs` yourself.]
170+
[Note that the version of `rust-fil-proofs` included in `go-filecoin` as a submodule is not always the current head of `rust-fil-proofs/master`. For documentation corresponding to the latest source, you should clone `rust-fil-proofs` yourself.]
171171

172172
Now, generate the documentation:
173173
```
174174
> cargo doc --all --no-deps
175175
```
176176

177-
View the docs by pointing your browser at: `…/rust-proofs/target/doc/proofs/index.html`.
177+
View the docs by pointing your browser at: `…/rust-fil-proofs/target/doc/proofs/index.html`.
178178

179179
---
180180

@@ -184,20 +184,24 @@ The **FPS** is accessed from [**go-filecoin**](https://github.com/filecoin-proje
184184

185185
The Rust source code serves as the source of truth defining the **FPS** APIs. View the source directly:
186186

187-
- [**filecoin-proofs**](https://github.com/filecoin-project/rust-proofs/blob/master/filecoin-proofs/src/api/mod.rs)
188-
- [**sector-base**](https://github.com/filecoin-project/rust-proofs/blob/master/sector-base/README.md#api-reference).
187+
- [**filecoin-proofs**](https://github.com/filecoin-project/rust-fil-proofs/blob/master/filecoin-proofs/src/api/mod.rs)
188+
- [**sector-base**](https://github.com/filecoin-project/rust-fil-proofs/blob/master/sector-base/README.md#api-reference).
189189

190190

191191
Or better, generate the documentation locally (until repository is public). Follow the instructions to generate documentation above. Then navigate to:
192-
- **Sector Base API:** `…/rust-proofs/target/doc/sector_base/api/index.html`
193-
- **Filecoin Proofs API:** `…/rust-proofs/target/doc/filecoin_proofs/api/index.html`
192+
- **Sector Base API:** `…/rust-fil-proofs/target/doc/sector_base/api/index.html`
193+
- **Filecoin Proofs API:** `…/rust-fil-proofs/target/doc/filecoin_proofs/api/index.html`
194194

195195
- [Go implementation of filecoin-proofs API](https://github.com/filecoin-project/go-filecoin/blob/master/proofs/rustprover.go) and [associated interface structures](https://github.com/filecoin-project/go-filecoin/blob/master/proofs/interface.go).
196196
- [Go implementation of sector-base API](https://github.com/filecoin-project/go-filecoin/blob/master/proofs/disk_backed_sector_store.go).
197197

198+
## Contributing
199+
200+
See [Contributing](CONTRIBUTING.md)
201+
198202
## License
199203

200204
The Filecoin Project is dual-licensed under Apache 2.0 and MIT terms:
201205

202-
- Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/filecoin-project/rust-proofs/blob/master/LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
203-
- MIT license ([LICENSE-MIT](https://github.com/filecoin-project/rust-proofs/blob/master/LICENSE-MIT) or http://opensource.org/licenses/MIT)
206+
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
207+
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

filecoin-proofs/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ itertools = "0.7.3"
3232
serde_cbor = "0.9.0"
3333
serde = { version = "1", features = ["rc"] }
3434
serde_derive = "1.0"
35+
serde_json = "1.0"
3536
blake2 = "0.8"
3637
slog = { version = "2.4.1", features = ["max_level_trace", "release_max_level_trace"] }
38+
regex = "1"
3739

3840
[dev-dependencies]
3941
gperftools = { git = "https://github.com/dignifiedquire/rust-gperftools" }

filecoin-proofs/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn main() {
7575
pc_file,
7676
"Name: libfilecoin_proofs
7777
Version: {version}
78-
Description: rust-proofs library
78+
Description: rust-fil-proofs library
7979
Libs: {libs}
8080
",
8181
version = git_hash.trim(),

filecoin-proofs/examples/ffi/main.rs

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use ffi_toolkit::c_str_to_rust_str;
1616
use ffi_toolkit::free_c_str;
1717
use ffi_toolkit::rust_str_to_c_str;
1818
use rand::{thread_rng, Rng};
19+
use std::env;
1920
use std::error::Error;
2021
use std::ptr;
2122
use std::sync::atomic::AtomicPtr;
@@ -64,9 +65,9 @@ unsafe fn create_sector_builder(
6465
sealed_dir: &TempDir,
6566
prover_id: [u8; 31],
6667
last_committed_sector_id: u64,
67-
) -> (*mut SectorBuilder, u64) {
68+
sector_store_config: ConfiguredStore,
69+
) -> (*mut SectorBuilder, usize) {
6870
let mut prover_id: [u8; 31] = prover_id;
69-
let sector_store_config: ConfiguredStore = ConfiguredStore_ProofTest;
7071

7172
let c_metadata_dir = rust_str_to_c_str(metadata_dir.path().to_str().unwrap());
7273
let c_sealed_dir = rust_str_to_c_str(sealed_dir.path().to_str().unwrap());
@@ -100,24 +101,56 @@ unsafe fn create_sector_builder(
100101

101102
(
102103
(*resp).sector_builder,
103-
(*resp_2).max_staged_bytes_per_sector,
104+
(*resp_2).max_staged_bytes_per_sector as usize,
104105
)
105106
}
106107

107-
unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
108+
struct ConfigurableSizes {
109+
store: ConfiguredStore,
110+
max_bytes: usize,
111+
first_piece_bytes: usize,
112+
second_piece_bytes: usize,
113+
third_piece_bytes: usize,
114+
}
115+
116+
unsafe fn sector_builder_lifecycle(use_live_store: bool) -> Result<(), Box<Error>> {
108117
let metadata_dir = tempfile::tempdir().unwrap();
109118
let staging_dir = tempfile::tempdir().unwrap();
110119
let sealed_dir = tempfile::tempdir().unwrap();
111120

112-
let (sector_builder_a, max_bytes) =
113-
create_sector_builder(&metadata_dir, &staging_dir, &sealed_dir, [0; 31], 123);
121+
let sizes = if use_live_store {
122+
ConfigurableSizes {
123+
store: ConfiguredStore_Live,
124+
max_bytes: 266338304,
125+
first_piece_bytes: 26214400,
126+
second_piece_bytes: 131072000,
127+
third_piece_bytes: 157286400,
128+
}
129+
} else {
130+
ConfigurableSizes {
131+
store: ConfiguredStore_Test,
132+
max_bytes: 1016,
133+
first_piece_bytes: 100,
134+
second_piece_bytes: 500,
135+
third_piece_bytes: 600,
136+
}
137+
};
138+
139+
let (sector_builder_a, max_bytes) = create_sector_builder(
140+
&metadata_dir,
141+
&staging_dir,
142+
&sealed_dir,
143+
[0; 31],
144+
123,
145+
sizes.store,
146+
);
114147

115148
// TODO: Replace the hard-coded byte amounts with values computed
116149
// from whatever was retrieved from the SectorBuilder.
117-
if max_bytes != 127 {
150+
if max_bytes != sizes.max_bytes {
118151
panic!(
119152
"test assumes the wrong number of bytes (expected: {}, actual: {})",
120-
127, max_bytes
153+
sizes.max_bytes, max_bytes
121154
);
122155
}
123156

@@ -144,7 +177,7 @@ unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
144177

145178
// add first piece, which lazily provisions a new staged sector
146179
{
147-
let (_, _, resp) = create_and_add_piece(sector_builder_a, 10);
180+
let (_, _, resp) = create_and_add_piece(sector_builder_a, sizes.first_piece_bytes);
148181
defer!(destroy_add_piece_response(resp));
149182

150183
if (*resp).status_code != 0 {
@@ -156,7 +189,7 @@ unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
156189

157190
// add second piece, which fits into existing staged sector
158191
{
159-
let (_, _, resp) = create_and_add_piece(sector_builder_a, 50);
192+
let (_, _, resp) = create_and_add_piece(sector_builder_a, sizes.second_piece_bytes);
160193
defer!(destroy_add_piece_response(resp));
161194

162195
if (*resp).status_code != 0 {
@@ -168,7 +201,7 @@ unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
168201

169202
// add third piece, which won't fit into existing staging sector
170203
{
171-
let (_, _, resp) = create_and_add_piece(sector_builder_a, 100);
204+
let (_, _, resp) = create_and_add_piece(sector_builder_a, sizes.third_piece_bytes);
172205
defer!(destroy_add_piece_response(resp));
173206

174207
if (*resp).status_code != 0 {
@@ -197,13 +230,20 @@ unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
197230

198231
// create a new sector builder using same prover id, which should
199232
// initialize with metadata persisted by previous sector builder
200-
let (sector_builder_b, _) =
201-
create_sector_builder(&metadata_dir, &staging_dir, &sealed_dir, [0; 31], 123);
233+
let (sector_builder_b, _) = create_sector_builder(
234+
&metadata_dir,
235+
&staging_dir,
236+
&sealed_dir,
237+
[0; 31],
238+
123,
239+
sizes.store,
240+
);
202241
defer!(destroy_sector_builder(sector_builder_b));
203242

204243
// add fourth piece, where size(piece) == max (will trigger sealing)
205244
let (bytes_in, piece_key) = {
206-
let (piece_bytes, piece_key, resp) = create_and_add_piece(sector_builder_b, 127);
245+
let (piece_bytes, piece_key, resp) =
246+
create_and_add_piece(sector_builder_b, sizes.max_bytes);
207247
defer!(destroy_add_piece_response(resp));
208248

209249
if (*resp).status_code != 0 {
@@ -251,7 +291,11 @@ unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
251291
});
252292

253293
// wait up to 5 minutes for sealing to complete
254-
let now_sealed_sector_id = result_rx.recv_timeout(Duration::from_secs(300)).unwrap();
294+
let now_sealed_sector_id = if use_live_store {
295+
result_rx.recv().unwrap()
296+
} else {
297+
result_rx.recv_timeout(Duration::from_secs(300)).unwrap()
298+
};
255299

256300
assert_eq!(now_sealed_sector_id, 126);
257301
}
@@ -294,5 +338,12 @@ unsafe fn sector_builder_lifecycle() -> Result<(), Box<Error>> {
294338
}
295339

296340
fn main() {
297-
unsafe { sector_builder_lifecycle().unwrap() };
341+
// If TEST_LIVE_SEAL is set, use the Live configuration, and don't unseal
342+
// — so process running time will closely approximate sealing time.
343+
let use_live_store = match env::var("TEST_LIVE_SEAL") {
344+
Ok(_) => true,
345+
Err(_) => false,
346+
};
347+
348+
unsafe { sector_builder_lifecycle(use_live_store).unwrap() };
298349
}

0 commit comments

Comments
 (0)