Skip to content

feat: cometbft header verifier library#366

Merged
rnbguy merged 38 commits into
mainfrom
farhad/impl-cometbft-verifier
Apr 2, 2025
Merged

feat: cometbft header verifier library#366
rnbguy merged 38 commits into
mainfrom
farhad/impl-cometbft-verifier

Conversation

@Farhad-Shabani

@Farhad-Shabani Farhad-Shabani commented Mar 19, 2025

Copy link
Copy Markdown
Contributor

Closes #367

Description

This PR includes my most recent local changes toward implementing CometBFT header verification. It provides the scaffolding types and functions needed for the verifier, though it's not yet complete. There are still some other underlying functions and types that need to be defined.

You can think of this as a continuation of PR #361, as it aims to integrate the signature verifier into the header verification process. The logic for these parts is included, but should be considered a first pass that definitely needs to be validated with unit tests.

Up to the team whether you want to continue implementation on top of this PR, break it down into smaller changes, or any other approach that better suits your progress.
cc @rnbguy @mpoke

Remark

I initially scaffolded everything in a new separate cometbft_verifier library, similar to how it exists as a standalone package under tendermint-rs. However, after consideration, I thought this might create unnecessary compilation overhead and complexity for our needs. For Starknet, I think the entire verifier implementation can live within the cometbft library, which should meet all our requirements.

@Farhad-Shabani Farhad-Shabani force-pushed the farhad/impl-cometbft-verifier branch from c411c77 to 1c51780 Compare March 19, 2025 20:52
@rnbguy rnbguy changed the title feat: scaffold CometBFT verifier types and functions (WIP) feat: cometbft header verifier library Mar 21, 2025
use protobuf::{base64, hex};

#[test]
fn test_verify_update_header() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Managed to get tendermint light client verified !

This test called the top verify_update_header 🙂

The header data is captured directly from hermes-sdk update client payload.

@rnbguy

rnbguy commented Mar 31, 2025

Copy link
Copy Markdown
Contributor

Remaining

  • add a failing test for verify_update_header
  • code cleaup

Comment thread cairo-libs/packages/protobuf/src/primitives/utils.cairo
pub struct UntrustedBlockState {
pub signed_header: SignedHeader,
pub validators: ValidatorSet,
// pub next_validators: Option<ValidatorSet>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this field is present in tendermint-rs but never used in IBC and always set to None in ibc-rs.

I removed this, as Option<T> implements Copy, not Clone. And ValidatoSet only impls Clone.

@rnbguy rnbguy requested a review from ljoss17 April 1, 2025 12:02
@rnbguy rnbguy marked this pull request as ready for review April 1, 2025 12:02
pub proposer_priority: i64,
pub voting_power: u64,
pub proposer_priority: u64,
// pub name: Option<ByteArray>, // not present in protobuf

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we keeping this on purpose?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Farhad created the first version of these structs from tendermint-rs domain types -- which has this field. But in Cairo, I am using the structs for protobuf messages as well -- which doesn't have this field.

I guess, we can remove this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment on lines +578 to +579
eq = false;
break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We could do an early return and remove the need of eq variable

Suggested change
eq = false;
break;
return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

good catch! in old Cairo version, we couldn't return within a loop. It seems, it is allowed in the latest version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/// Type of vote (prevote or precommit)
pub vote_type: VoteType,
/// Block height
pub height: i64,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Didn't we change height to be u64?

Suggested change
pub height: i64,
pub height: u64,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am not sure, why this was made to u64. i64 and u64 have different encoding in protobuf. e.g. encoding of 1u64 and 1i64 will be totally different.

maybe we can have protobuf types and then domain types (which may validate and maintain only u64) -- but for now, let's maintain a single version of the types.

Comment on lines +42 to +44
// validator_sets_match(
// untrusted.next_validators, untrusted.signed_header.header.next_validators_hash,
// );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why don't we check next validators?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment on lines +103 to +106
let mut context2 = Self::new();
value.encode_raw(ref context2);
context2.buffer.len().encode_raw(ref self);
self.buffer.append(@context2.buffer);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason for naming it context2?

Suggested change
let mut context2 = Self::new();
value.encode_raw(ref context2);
context2.buffer.len().encode_raw(ref self);
self.buffer.append(@context2.buffer);
let mut context = Self::new();
value.encode_raw(ref context);
context.buffer.len().encode_raw(ref self);
self.buffer.append(@context.buffer);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

good catch ! I was copy-pasting 😄

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah. I just realized that I was using context2 to signify it is a second context or sub-context -- self being the first context or parent-context.

@rnbguy rnbguy requested a review from ljoss17 April 2, 2025 08:32

@ljoss17 ljoss17 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me!

@rnbguy rnbguy merged commit a858e38 into main Apr 2, 2025
@rnbguy rnbguy deleted the farhad/impl-cometbft-verifier branch April 2, 2025 08:57
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.

implement cometbft header verifier types and methods

3 participants