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

CCTP lib CommitmentTree integration #45

Merged
merged 31 commits into from
Jun 3, 2021

Conversation

i-Alex
Copy link
Contributor

@i-Alex i-Alex commented Apr 16, 2021

No description provided.

i-Alex and others added 25 commits March 18, 2021 11:26
Copy link
Member

@nastenko nastenko left a comment

Choose a reason for hiding this comment

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

In general looks fine; Most of the comments are about possible refactoring for code size optimization and minor fixes in tests

Optional<ScAbsenceProof> absenceOpt = commTree.getScAbsenceProof(scId[0]);
// TODO Uncomment this code when rust library will be able to operate with absence proof on empty commitment tree.
assertTrue("Absence proof expected to be present.", absenceOpt.isPresent());
assertTrue("Absence verification expected to be successful", commTree.verifyScAbsence(scId[0], absenceOpt.get() ,commitmentOpt.get()));
Copy link
Member

Choose a reason for hiding this comment

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

commTree.verifyScAbsence - static member is accessed via instance reference; can be replaced with CommitmentTree.verifyScAbsence



private native Optional<FieldElement[]> nativeGetCrtLeaves(byte[] scId);
public Optional<List<FieldElement>> getCrtLeaves(byte[] scId) {
Copy link
Member

Choose a reason for hiding this comment

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

Looks like this method is not covered with tests in CommitmentTreeTest

Copy link
Contributor

Choose a reason for hiding this comment

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

Done.

absenceOpt = commTree.getScAbsenceProof(scId[0]);
commitmentOpt = commTree.getCommitment();
assertTrue("Absence proof expected to be present.", absenceOpt.isPresent());
assertTrue("Absence verification expected to be successful", commTree.verifyScAbsence(scId[0], absenceOpt.get() ,commitmentOpt.get()));
Copy link
Member

Choose a reason for hiding this comment

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

static member is accessed via instance reference

absenceOpt = commTree.getScAbsenceProof(scId[2]);
commitmentOpt = commTree.getCommitment();
assertTrue("Absence proof expected to be present.", absenceOpt.isPresent());
assertTrue("Absence verification expected to be successful", commTree.verifyScAbsence(scId[2], absenceOpt.get() ,commitmentOpt.get()));
Copy link
Member

Choose a reason for hiding this comment

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

static member is accessed via instance reference

absenceOpt = commTree.getScAbsenceProof(scId[4]);
commitmentOpt = commTree.getCommitment();
assertTrue("Absence proof expected to be present.", absenceOpt.isPresent());
assertTrue("Absence verification expected to be successful", commTree.verifyScAbsence(scId[4], absenceOpt.get() ,commitmentOpt.get()));
Copy link
Member

Choose a reason for hiding this comment

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

static member is accessed via instance reference


assertTrue("Deserialized absence proof should be serialized to same bytes", Arrays.equals(deserializedAbsenceProof.serialize(), absenceProofBytes));
assertTrue("Absence verification of original proof expected to be successful", commTree.verifyScAbsence(scId[1], absenceOpt.get() ,commitmentOpt.get()));
assertTrue("Absence verification of deserialized proof expected to be successful", commTree.verifyScAbsence(scId[1], deserializedAbsenceProof ,commitmentOpt.get()));
Copy link
Member

Choose a reason for hiding this comment

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

static member is accessed via instance reference

Cargo.toml Outdated Show resolved Hide resolved
api/src/lib.rs Outdated
) -> jboolean
{
let sc_id = {
let t = _env.convert_byte_array(_sc_id)
Copy link
Member

Choose a reason for hiding this comment

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

this part of code (lines 2649 - 2657) actually is duplicated many times along the further code, so it could be implemented as an utility method like:
get_byte_array(_env: &JNIEnv, javaByteArray: &jbyteArray, length: usize) -> [u8]


let commitment_tree = {

let t =_env.get_field(_commitment_tree, "commitmentTreePointer", "J")
Copy link
Member

Choose a reason for hiding this comment

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

to avoid duplications of such a part of the code the method like this could be useful:
https://github.com/nastenko/zendoo-sc-cryptolib/blob/76e533cd3ff2de91871f354f599633140644c03e/api/src/zenbox_smt/jni_calls.rs#L31

@@ -40,6 +40,7 @@ private static native boolean nativeVerifyProof(BackwardTransfer[] btList,
byte[] endEpochBlockHash, byte[] prevEndEpochBlockHash,
FieldElement constant, long quality, byte[] proof, boolean checkProof, String verificationKeyPath, boolean checkVk);

// TODO: check type of `constant`. Why not a byte[]?
Copy link
Member

Choose a reason for hiding this comment

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

FieldElement can be passed to the Rust-side without a need for intermediate serialization into bytes

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 propose to use byte array representations everywhere.
All the objects like constant, certDataHash, customFields and others on the SDK side are kept and stored as a pure java byte arrays. And, for example, when we need to use constant to verify snark proof we need to deserialize it to Rust FieldElement object first, then pass it to verify the proof, then free the object to avoid memory leaks.
Such an approach costs a lot, because we emit 2 JNI calls: FE deserialization, proof verification.
Instead we may use only 1 JNI call by passing constant as is and deserializing it inside nativeVerifyProof method.

The main goal is to decrease number of JNI calls as much as possible. Here it's just a proposal for the further discussions.

api/src/lib.rs Outdated Show resolved Hide resolved
@i-Alex i-Alex changed the base branch from updatable_poseidon_tweedle to development_tmp May 4, 2021 06:51
@i-Alex i-Alex marked this pull request as ready for review May 6, 2021 07:19
@i-Alex i-Alex requested a review from nastenko May 7, 2021 12:47
@i-Alex i-Alex mentioned this pull request May 14, 2021
@i-Alex
Copy link
Contributor Author

i-Alex commented May 14, 2021

This PR is substituted with #49

@albertog78 albertog78 merged commit 5e918e8 into development_tmp Jun 3, 2021
@DanieleDiBenedetto DanieleDiBenedetto deleted the commitment_jni_tweedle branch March 23, 2023 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants