-
Notifications
You must be signed in to change notification settings - Fork 35
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 compiled merkle proof with C verifier #27
base: master
Are you sure you want to change the base?
Conversation
Similar to sparse-merkle-tree, this commit adds a new stack based compiled merkle proof format. This new format can be used to build highly performant C verifier on CKB-VM. An optimized C implementation of the verifier is also included in this commit, including tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found potential overflow attack
} else { | ||
(lhs_pos, lhs_height, rhs_pos, rhs_t, lhs, rhs) | ||
}; | ||
// calculate sibling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the height var in stack is only used in Command::Hash
, can we remove it from the stack and calculate it via pos here?
// calculate sibling | |
// calculate sibling | |
let height = pos_height_in_tree(pos); |
and a step further, the pos is only used with StackItemType::Node
, we may change the enum variant to StackItemType::Node(u64)
and stack to <(T, StackItemType)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, but noticing that recalculating pos_height_in_tree
would have a noticeable impact on verifier performance (~2% in cycle consumptions of Rust code), so I would rather suggest keeping the code as it is. Counting heights only by incrementing as in current code, can be faster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, but noticing that recalculating
pos_height_in_tree
would have a noticeable impact on verifier performance (~2% in cycle consumptions of Rust code), so I would rather suggest keeping the code as it is. Counting heights only by incrementing as in current code, can be faster.
I see, can you help to try the cycle difference between StackItemType::Node(u64, u8) // pos, height | Peak(u8)
and original solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This additional commit b5b4602 which refactors as you mentioned, takes an additional 2000 cycles out of a total of 1583330 cycles, which is quite neglegible, hence I pull the trigger and include the refactored code.
} | ||
let (rhs, rhs_t) = stack.pop().unwrap(); | ||
let (lhs, lhs_t) = stack.pop().unwrap(); | ||
let (pos, height, next_pos, next_t, item, sibling_item) = match (lhs_t, &rhs_t) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an FYI: I have tried the path of introducing a pos
function to StackItemType
enum, so we don't need next_pos
variable here. But surprisingly, a common pos
function here actually will make performance worse(roughly 30000 more cycles on the overall 1583330 cycles), hence I'm keeping this next_pos
variable.
Similar to sparse-merkle-tree, this commit adds a new stack based compiled merkle proof format. This new format can be used to build highly performant C verifier on CKB-VM. An optimized C implementation of the verifier is also included in this commit, including tests.
Based on a random generated MMR of 1116 leafs, a proof containing 71 leafs is generated, the following results are then obtained: