Skip to content

Feat/via verify en data#302

Draft
0xatomFusion wants to merge 2 commits intomainfrom
feat/via-verify-en-data
Draft

Feat/via verify en data#302
0xatomFusion wants to merge 2 commits intomainfrom
feat/via-verify-en-data

Conversation

@0xatomFusion
Copy link
Copy Markdown
Collaborator

What ❔

  • Verify that the data returned by the Node matches the commitment hash recorded DA layer.

Why ❔

When the verifier falls back to the node to fetch DA, it must verify that the returned data matches the on-chain commitment hash stored on Celestia, rather than trusting the node to provide honest and valid data.

Checklist

  • PR title corresponds to the body of PR (we generate changelog entries from PRs).
  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.
  • Code has been formatted via zkstack dev fmt and zkstack dev lint.

@0xatomFusion 0xatomFusion self-assigned this Nov 24, 2025
@0xatomFusion 0xatomFusion added the enhancement New feature or request label Nov 24, 2025
@romanornr
Copy link
Copy Markdown
Collaborator

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a crucial verification step to ensure data fetched from a fallback node matches the on-chain commitment. The implementation is mostly correct, but I've found a critical issue in the validation logic, along with some leftover debugging code and a missed validation case. My review includes suggestions to fix the critical bug, clean up the code, and ensure the verification is applied consistently.

Comment on lines +34 to 92
pub fn validate_commitment(&self, blob_id: &str, data: &[u8]) -> anyhow::Result<(), DAError> {
let commitment =
Commitment::from_blob(self.namespace, &data, SHARE_VERSION_ZERO).map_err(|error| {
DAError {
error: anyhow!("Error to create commitment: {}", error.to_string()),
is_retriable: false,
}
})?;

// let commitment_result =
// match Commitment::from_blob(self.namespace, SHARE_VERSION_ZERO, data) {
// Ok(commit) => commit,
// Err(error) => {
// return Err(DAError {
// error: error.into(),
// is_retriable: false,
// })
// }
// };

let blob_id_bytes = hex::decode(blob_id).map_err(|error| DAError {
error: error.into(),
is_retriable: true,
})?;

// Prepend the block height to the blob_id
// let mut blob_id_with_block_height = Vec::with_capacity(8 + 32);
// blob_id_with_block_height.extend_from_slice(&(0 as u64).to_be_bytes());
// blob_id_with_block_height.extend_from_slice(&blob_id_bytes);
// let blob_id_str = hex::encode(blob_id_with_block_height.clone());

// println!(
// "*****************************: {:?}",
// blob_id_with_block_height
// );

let (commitment, _) = parse_blob_id(&blob_id).map_err(|error| DAError {
error: error.into(),
is_retriable: true,
})?;

println!(
"-----------------------------------------------: {:?}",
commitment.0
);

println!(
"-----------------------------------------------: {:?}",
commitment_result.0
);

if commitment.0 != commitment_result.0 {
return Err(DAError {
error: anyhow::anyhow!("Commitment mismatch"),
is_retriable: false,
});
}
Ok(())
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

The validate_commitment function has several issues that need to be addressed:

  • Incorrect Argument Order: The arguments to Commitment::from_blob appear to be swapped. Based on its usage elsewhere, the signature is likely (Namespace, u8, &[u8]). The current implementation will fail to compile or produce an incorrect commitment, defeating the purpose of this validation.
  • Leftover Debug Code: The function contains println! statements and large blocks of commented-out code, which should be removed.
  • Redundant Logic: The function decodes blob_id manually, even though parse_blob_id is also called and performs the same operation.
  • Uncompilable Code: The function references a commitment_result variable that is not defined in the uncommented code, which will cause a compilation error.

I suggest refactoring the entire function for clarity and correctness.

    pub fn validate_commitment(&self, blob_id: &str, data: &[u8]) -> Result<(), DAError> {
        let calculated_commitment =
            Commitment::from_blob(self.namespace, SHARE_VERSION_ZERO, data).map_err(|error| {
                DAError {
                    error: error.into(),
                    is_retriable: false,
                }
            })?;

        let (expected_commitment, _) = parse_blob_id(blob_id).map_err(|error| DAError {
            error: error.into(),
            is_retriable: true,
        })?;

        if calculated_commitment.0 != expected_commitment.0 {
            return Err(DAError {
                error: anyhow::anyhow!("Commitment mismatch"),
                is_retriable: false,
            });
        }
        Ok(())
    }

Comment on lines +128 to +132
// self.validate_commitment(blob_id, &data)
// .map_err(|e| DAError {
// error: e.into(),
// is_retriable: false,
// })?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The commitment validation is commented out for blobs that are proofs (blob.is_proof). To ensure all data from the external node is verified against its on-chain commitment, this validation should be enabled for all blob types.

                    self.validate_commitment(blob_id, &data)
                        .map_err(|e| DAError {
                            error: e.into(),
                            is_retriable: false,
                        })?;

Comment on lines +140 to +143
println!(
"-----------------------------------------------{:?}",
blob.pub_data
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This println! statement appears to be leftover debugging code and should be removed.

Comment on lines +113 to +116
println!(
"----------------------PUBDATA-------------------------: {:?}",
hex::encode(batch.pubdata.clone())
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This println! statement appears to be for debugging and should be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants