Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tool to split phase2 parameters #1235

Merged
merged 2 commits into from
Aug 5, 2020
Merged

feat: add tool to split phase2 parameters #1235

merged 2 commits into from
Aug 5, 2020

Conversation

vmx
Copy link
Contributor

@vmx vmx commented Jul 30, 2020

The phase2 CLI has a new command called split-keys which allows to
split phase2 parameter output into parameters that can be used for
rust-fil-proofs.

I'm not done yet, the path handling is not robust enough. Though it would
be good to get early review.

@vmx vmx marked this pull request as ready for review July 31, 2020 11:47
@vmx
Copy link
Contributor Author

vmx commented Jul 31, 2020

It already works like the other commands. It creates the .params and .vk file in the directory the program was run from. The log file is created in the directory of the source file.

I'm now looking for ideas on how to verify that it does the right thing.

Copy link
Contributor

@DrPeterVanNostrand DrPeterVanNostrand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, everything looks good to me.

The only question that I have is whether or not it's ok to set porep_id = [0u8; 32] when generating the identifier.

And maybe whether or not the .participants file is going to be written at the end of split-keys.

filecoin-proofs/src/bin/phase2.rs Outdated Show resolved Hide resolved
filecoin-proofs/src/bin/phase2.rs Outdated Show resolved Hide resolved
filecoin-proofs/src/bin/phase2.rs Outdated Show resolved Hide resolved
filecoin-proofs/src/bin/phase2.rs Outdated Show resolved Hide resolved
let porep_config = PoRepConfig {
sector_size: SectorSize(sector_size),
partitions: PoRepProofPartitions(n_partitions),
porep_id: [0; 32],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not certain that setting the porep-id to all zeroes will produce the correct identifier for mainnet params which have a nonzero porep-id. It may, but idk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got them from

. I used the parameter of the initial files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phase2 initial parameter gen won't be affected by the porep-id, that's why it's set to all zeros. But, I didn't know whether or not the porep-id will affect the identifier

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fn identifier(&self) -> String {
format!(
"layered_drgporep::PublicParams{{ graph: {}, challenges: {:?}, tree: {} }}",
self.graph.identifier(),
self.layer_challenges,
Tree::display()
)
}
is called on the public parameters.

Example output: layered_drgporep::PublicParams{ graph: stacked_graph::StackedGraph{expansion_degree: 8 base_graph: drgraph::BucketGraph{size: 1073741824; degree: 6; hasher: poseidon_hasher} }, challenges: LayerChallenges { layers: 11, max_count: 18 }, tree: merkletree-poseidon_hasher-8-8-0 }

So it doesn't look like the porep_id is part of it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that there is a bug (no reason to expect it, and a scan of code suggests not), but for reference:

  • The identifier used to derive the working file for the parameters should not depend on porep_id.
  • There should be a 1-1 relationship between distinct groth params and file names.
  • porep_id is intentionally decoupled from the concrete circuit (by design, it can be used to change the graphs without changing the circuit).
  • This explains both why phase2 does not require porep_id and also why it must not affect the generated filename.
  • If the generated filename does depend on porep_id, that is a bug — and we should fix it.
  • Here is the code which I think shows that it does not (even though it 'could'): https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs/porep/src/stacked/vanilla/params.rs#L84-L91

So I think it should be safe to assume an arbitrary porep_id can be supplied. However, it would be worth verifying that choice of porep_id doesn't affect the final filenames — as an independent check on this important logic.

filecoin-proofs/src/bin/phase2.rs Outdated Show resolved Hide resolved
@vmx
Copy link
Contributor Author

vmx commented Aug 3, 2020

Even if this would work, I want to make one more change, which is extracting the contributions into yet another file (that's purely for the verification process).

@porcuquine
Copy link
Collaborator

One quick note, bearing in mind that I haven't had a chance to review this overall yet:

Ideally, this tool would be general-purpose in the sense that it could be used for any circuits created by phase2. That can and will change in the future when we perform more trusted setups.

I think (based on cursory discussion) it's the case that you currently extract the circuit parameters by parsing the filenames. In a perfect world, you would get all the circuit specification in the same way the initial phase2 parameters were created. Then, as long as the commands used to create initial parameters for a circuit were saved, they could be used verbatim to also perform this final splitting. I think, if designed correctly, that will allow for the final phase to happen correctly without need of any manual intervention or decision-making, and even with new, not-yet-supported circuits. In other words, we can/should reuse the circuit-selection logic used for creating initial phase2 params. This might require more refactoring than is convenient now, though — in which case it could be added as a follow-up but prior to the next trusted setup.

@vmx
Copy link
Contributor Author

vmx commented Aug 3, 2020

I think (based on cursory discussion) it's the case that you currently extract the circuit parameters by parsing the filenames.

No I don't, I copy and pasted the parameters from earlier in the file.

In a perfect world, you would get all the circuit specification in the same way the initial phase2 parameters were created.

I actually thought about refactoring the code to do that. Though I hesitated as I don't know how much we want to refactor the original trusted setup code. It's a matter of e.g. taking

fn blank_winning_post_poseidon_circuit<Tree: 'static + MerkleTreeTrait>(
sector_size: u64,
) -> FallbackPoStCircuit<Tree> {
let post_config = PoStConfig {
sector_size: SectorSize(sector_size),
challenge_count: WINNING_POST_CHALLENGE_COUNT,
sector_count: WINNING_POST_SECTOR_COUNT,
typ: PoStType::Winning,
priority: false,
};
let public_params = winning_post_public_params::<Tree>(&post_config).unwrap();
<FallbackPoStCompound<Tree> as CompoundProof<
FallbackPoSt<Tree>,
FallbackPoStCircuit<Tree>,
>>::blank_circuit(&public_params)
}

and splitting it into two functions, one that generates the parameters (which will then be re-used by my code) and the <FallbackPoStCompound<Tree> as CompoundProof< FallbackPoSt<Tree>, FallbackPoStCircuit<Tree>, >>::blank_circuit(&public_params) call.

@vmx
Copy link
Contributor Author

vmx commented Aug 3, 2020

If I should do the refactoring mentioned above, let me know.

@porcuquine
Copy link
Collaborator

@vmx I think what you're describing is the same thing I have believed is the 'right thing'. If you think this can be done practically in such a way as to be usable for the current trusted setup, then I think it's probably worth doing now. Unless @DrPeterVanNostrand sees a problem with the original code being refactored in what will be used in the last step of this trusted setup, I would proceed. If we decide we don't want to touch it now, we should still do it in a separate step for next time. This all makes me think it's probably better to do it now, fwiw.

// Writing the contributions to disk is not needed for the final parameters,
// they won't be published, they are only there for verification purpose.
let contribs_path =
format!("v{}-{}.contribs", parameter_cache::VERSION, &identifier);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a subtlety here. If we use the current value of VERSION when running the tool, then we will end up with the version corresponding to the current (untrusted) parameters.

That would imply a sequence like the following:

  • Bump VERSION.
  • Run split tool to create trusted parameters.
  • Publish parameters.
  • Release.

Note that in this sequence, the version must be bumped before the tool is run. We could bump the version here/now, but then the trusted parameters would need to be included in the very next release. For that reason, something like the sequence above is probably better. It's also possible that I'm seeing something wrong, so please let me know if so or explicitly confirm below otherwise (cc: @cryptonemo @vmx ).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use the sequence then @cryptonemo would use when he publishes new parameters. I'd expect it to be what @porcuquine outlined above, but @cryptonemo would know best.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cryptonemo Can you confirm that we're not missing anything here and that my sequence above is workable (or propose an alternative)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed

@vmx
Copy link
Contributor Author

vmx commented Aug 4, 2020

@DrPeterVanNostrand I've made the refactoring that @porcuquine proposed. If you look at the commit in isolation a6b2f94 it shows quite nicely that is is just a basic refactoring for the existing code, but makes the new code more robust as there's less duplicated code.

porcuquine
porcuquine previously approved these changes Aug 4, 2020
Copy link
Collaborator

@porcuquine porcuquine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved contingent on @cryptonemo's confirmation that we don't need any more sophistication here to best handle the version bump.

cryptonemo
cryptonemo previously approved these changes Aug 4, 2020
@vmx
Copy link
Contributor Author

vmx commented Aug 4, 2020

@DrPeterVanNostrand could you please approve or request changes? I especially would like to know if you are OK with the refactoring that also changes other parts of the code. I'd then make any needed changes (and the rebase that's needed anyway) my tomorrow and then we can hopefully merge it.

@vmx
Copy link
Contributor Author

vmx commented Aug 5, 2020

@DrPeterVanNostrand just confirmed through a side-channel that the refactoring is OK. So I'll go with that.

Those functions will be used by subsequent commits for splitting the
trusted setup results into the correct parameter files.
porcuquine
porcuquine previously approved these changes Aug 5, 2020
Copy link
Collaborator

@porcuquine porcuquine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

The `phase2` CLI has a new command called `split-keys` which allows to
split phase2 parameter output into parameters that can be used for
rust-fil-proofs.

Some auxiliary files for verification purpose are created as well.
@vmx vmx merged commit 3b01736 into master Aug 5, 2020
@vmx vmx deleted the phase2-split-keys branch August 5, 2020 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants