Skip to content
New issue

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

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

Already on GitHub? # to your account

Derivation proc macro for commitment encoding #121

Merged
merged 21 commits into from
May 11, 2023
Merged

Conversation

dr-orlovsky
Copy link
Member

@dr-orlovsky dr-orlovsky commented May 1, 2023

These are consensus-level changes required for solving the RGB-WG/rgb-std#36 and an upstream dependency for completing the work in RGB-WG/rgb-core#153

Derivation macro are required to get commitment encoding work properly. Let me explain what is needed to be achieved schematically.

Let's assume we have three data types, used by each other: A -> B -> Data, where Data has data which may be concealed.

#[derive(StrictType, StrictEncode)]
struct A {
  b: B
}
impl Conceal for A { self.b.conceal(); }

#[derive(StrictType, StrictEncode)]
struct B {
  data: Data
}
impl Conceal for B { self.data.conceal() }

#[derive(StrictType, StrictEncode)]
enum Data {
  Revealed(SmallBlob),
  Concealed { pedersen: [0u8; 32], bulletproofs: SmallBlob }
}
impl Conceal for Data { *self = Data::Concealed(/* .... */) }

(I am skipping some derives and code details to prevent visual clutter).

Before this PR, there was no way of getting Data committed without bulletproofs: the setup we had

impl CommitStrategy for A {
  type Strategy = strategies::StrictConceal
}

was not achieving the goal, since bulletproofs are get encoded even if we do a custom implementation of the CommitConceal for the Data type like

impl CommitEncode for Data {
  fn commit_encode(&self, e: &impl mut Write) {
     let Data::Concealed { pedersen, .. } = self.conceal() else { unreachable!() };
     pedersen.commit_encode(e);
  }
}

since when we call A::commit_encode() it does conceal for all types underneath - but instead of calling self.b.commit_encode(..) it calls self.strict_encode, thus Data::commit_encode is never get called and bulletproofs are still serialized into the hasher.

The only way of getting the whole thing to work properly is to provide a custom implementation of CommitEncode for each type above Data. In reality, for RGB it means implementing for dozens of data types - with the risk that some implementation of commit-encode will accidentially diverge from strict encoding serialization which we control in deterministic way with strict type system. I.e. this was highly undesirable.

Adding derivation macros allows to avoid this problem and achieve our goal with simply adding #[derive(CommitEncode)] for A and B types, and adding skip directive to bulletproofs:

#[derive(CommitEncode, StrictType, StrictEncode)]
struct A {
  b: B
}
impl Conceal for A { self.b.conceal(); }

#[derive(CommitEncode, StrictType, StrictEncode)]
struct B {
  data: Data
}
impl Conceal for B { self.data.conceal() }

#[derive(CommitEncode, StrictType, StrictEncode)]
enum Data {
  Revealed(SmallBlob),
  Concealed { 
    pedersen: [0u8; 32], 
    #[commit_encode(skip)]
    bulletproofs: SmallBlob 
  }
}
impl Conceal for Data { *self = Data::Concealed(/* .... */) }

In such way we clearly see where we diverge from strict encoding - while being sure that everywhere else we follow the same serialization rules.

@dr-orlovsky dr-orlovsky added enhancement New feature or request *consensus* Issues affecting distributed concensus refactoring Refactoring of the existing code labels May 1, 2023
@dr-orlovsky dr-orlovsky added this to the v0.10.x milestone May 1, 2023
crisdut
crisdut previously approved these changes May 2, 2023
Copy link
Member

@crisdut crisdut left a comment

Choose a reason for hiding this comment

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

I did the initial tests for consecutive transfers. With that version of commit_verify, everthing works!

@dr-orlovsky dr-orlovsky merged commit 46a79d2 into master May 11, 2023
@dr-orlovsky dr-orlovsky deleted the commit_encode_derive branch September 4, 2024 20:51
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
*consensus* Issues affecting distributed concensus enhancement New feature or request refactoring Refactoring of the existing code
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants