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

feat: Validate conway block KES signatures #2

Merged
merged 1 commit into from
Oct 26, 2024

Conversation

AndrewWestberg
Copy link
Contributor

This code adds validation of both the Operational Certificate included in each block as well as the hot key KES signature in the block header.

dependent on pallas changes: txpipe/pallas#518

@AndrewWestberg AndrewWestberg force-pushed the amw/validate_block_kes_signature branch 2 times, most recently from 174c9b1 to 98e7a94 Compare October 12, 2024 13:53
@AndrewWestberg AndrewWestberg self-assigned this Oct 14, 2024
@AndrewWestberg AndrewWestberg marked this pull request as draft October 14, 2024 12:21
@AndrewWestberg
Copy link
Contributor Author

Converting to draft to add additional check for opcert counter. Also re-factoring Validator to pass back errors instead of just boolean.

@AndrewWestberg AndrewWestberg force-pushed the amw/validate_block_kes_signature branch from 98e7a94 to 0d80a63 Compare October 14, 2024 17:09
@AndrewWestberg AndrewWestberg marked this pull request as ready for review October 14, 2024 17:13
@AndrewWestberg
Copy link
Contributor Author

Code is ~20% faster at block validation by using parallel code.

validate_conway_block   time:   [200.97 µs 203.79 µs 206.92 µs]
                        change: [-20.985% -20.037% -18.903%] (p = 0.00 < 0.05)
                        Performance has improved.

@AndrewWestberg AndrewWestberg force-pushed the amw/validate_block_kes_signature branch from 0d80a63 to c3ff6a2 Compare October 17, 2024 14:40
FixedDecimal::from(5u64) / FixedDecimal::from(100u64);
let c = (FixedDecimal::from(1u64) - active_slots_coeff).ln();
let conway_block_tag: u8 = 6;
let multi_era_header = MultiEraHeader::decode(conway_block_tag, None, test_block).unwrap();
Copy link

Choose a reason for hiding this comment

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

Shouldn't the decoding of the header be outside of the bench? If that bench is specifically about measuring the validation, it sounds to me that it's reasonable to assume already decoded blocks?

Comment on lines +110 to +112
validation_checks
.into_par_iter()
.try_for_each(|check| check())?;
Copy link

@KtorZ KtorZ Oct 17, 2024

Choose a reason for hiding this comment

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

It would actually be interesting to benchmark whether the parallel validation here does provide a benefit over a sequential validation? Threads creation and context switching may perhaps dwarf the benefits gained from doing the validation in parallel?

It's not obvious to me that this is necessarily faster.

Copy link

Choose a reason for hiding this comment

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

Just saw this comment -> #2 (comment) 😅

Comment on lines +5 to +26
#[error("InvalidByteLength: {0}")]
InvalidByteLength(String),
#[error("Invalid VRF key for pool: expected: {0}, was: {1}")]
InvalidVrfKeyForPool(String, String),
#[error("Invalid block hash, expected: {0}, was: {1}")]
InvalidBlockHash(String, String),
#[error("Ledger error: {0}")]
LedgerError(#[from] crate::ledger::Error),
#[error("VrfVerificationError: {0}")]
VrfVerificationError(#[from] pallas_crypto::vrf::VerificationError),
#[error("InvalidVrfProofHash, expected: {0}, was: {1}")]
InvalidVrfProofHash(String, String),
#[error("InvalidVrfLeaderHash, expected: {0}, was: {1}")]
InvalidVrfLeaderHash(String, String),
#[error("InvalidOpcertSequenceNumber: {0}")]
InvalidOpcertSequenceNumber(String),
#[error("InvalidOpcertSignature")]
InvalidOpcertSignature,
#[error("KesVerificationError: {0}")]
KesVerificationError(String),
#[error("InsufficientPoolStake")]
InsufficientPoolStake,
Copy link

@KtorZ KtorZ Oct 17, 2024

Choose a reason for hiding this comment

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

It doesn't feel right to have hex-encoded strings here as part of the ValidationError types for many of those fields. It is IMO a mismatch of responsibility / representation. Having an hex-encoded string is useful for display yet should be the responsibility of the Debug or Display trait's implementation.

To give an concrete example where it can be problematic; if you end up returning the error and handling it from another place, then you end up paying the cost of hex-encoding the data for nothing. It wouldn't be problematic in a lazy language, but in Rust that'd be wasted CPU.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would decouple the representation of the error from its definition: leave raw types in the definition and provide different representations elsewhere (a Display trait is one option, but there's also the case of rendering errors as JSON or any other representation as part of structured logging)

@AndrewWestberg AndrewWestberg force-pushed the amw/validate_block_kes_signature branch from c3ff6a2 to 5d914a7 Compare October 17, 2024 19:16
@AndrewWestberg
Copy link
Contributor Author

Merging so Arnaud can have minimal changes to his pr that built on top of this. We can correct the open comments in a follow-up.

@AndrewWestberg AndrewWestberg merged commit f9b81ae into main Oct 26, 2024
6 checks passed
@AndrewWestberg AndrewWestberg deleted the amw/validate_block_kes_signature branch October 26, 2024 13:09
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.

4 participants