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

Use secp256k1 for validator keys. #3377

Merged
merged 6 commits into from
Feb 24, 2025
Merged

Use secp256k1 for validator keys. #3377

merged 6 commits into from
Feb 24, 2025

Conversation

deuszx
Copy link
Contributor

@deuszx deuszx commented Feb 20, 2025

Motivation

We want to make certificates easily verifiable on EVM and there's no precompile for ed25519 on Ethereum.

Proposal

Use Secp256k1* for Validator* keys.

This required adding a secondary key - called account_key - to ValidatorState. That's b/c validators can also act as fallback owners during block proposals and blocks are still signed with Account* keys - ed25519.

Test Plan

CI should catch regressions. New tests have been added to verify signature/public key (de)serialization and conversions to/from gRPC protobuf.

Release Plan

This is a breaking change and as such requires full network restart.

Links

@deuszx deuszx force-pushed the secp256k1-validator-keys branch 8 times, most recently from f34441a to 9d991e5 Compare February 21, 2025 13:45
@deuszx deuszx marked this pull request as ready for review February 21, 2025 13:46
@@ -112,7 +115,7 @@ async fn test_block_size_limit() {
let mut chain = ChainStateView::new(chain_id).await;

// The size of the executed valid block below.
let maximum_executed_block_size = 685;
let maximum_executed_block_size = 720;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: need to investigate this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's exactly as much as the 33 bytes for Secp256k1PublicKey + 2 bytes for length prefix but I don't know where that'd come from.

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we create an issue for it and add a TODO here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll do that if I don't figure this out before merging.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I think where this might come from - there's a ExecutionOutcome::System(SystemMessage::CreateCommittee(Committee))) and that innermost struct contains ValidatorState which now also gets AccountPublicKey.

@deuszx deuszx force-pushed the secp256k1-validator-keys branch 3 times, most recently from 42cf98a to 74a0942 Compare February 21, 2025 15:22
CONTENT: U8
SIZE: 33
Secp256k1Signature:
NEWTYPESTRUCT: BYTES
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: Serialize as array, not vector.

Copy link
Contributor Author

@deuszx deuszx Feb 22, 2025

Choose a reason for hiding this comment

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

Switched to serialization with compact representation (which is always 64 bytes). See Serialize secp256k1 signatures in a compact form rather than DER..

// 1. Record samples for types with custom deserializers.
// 2. Trace the main entry point(s) + every enum separately.
{
Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM. This code is meant to be between // 1. and // 2..

Copy link
Contributor

Choose a reason for hiding this comment

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

^^ please fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in Review part 2..

@@ -112,7 +115,7 @@ async fn test_block_size_limit() {
let mut chain = ChainStateView::new(chain_id).await;

// The size of the executed valid block below.
let maximum_executed_block_size = 685;
let maximum_executed_block_size = 720;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we create an issue for it and add a TODO here?

@deuszx deuszx force-pushed the secp256k1-validator-keys branch 2 times, most recently from a2a3dab to ab824fb Compare February 22, 2025 18:56
@deuszx deuszx requested review from ma2bd and afck February 22, 2025 19:05
Comment on lines 411 to +414
* `--public-key <PUBLIC_KEY>` — The public key of the validator
* `--account-key <ACCOUNT_KEY>` — The public key of the account controlled by the validator
Copy link
Contributor

@ma2bd ma2bd Feb 22, 2025

Choose a reason for hiding this comment

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

I would expect --xxx-public-key in both cases for some value xxx.

Couple of naming options: (key = private or public key depending on the context)

  • validator key vs user key
  • validator key vs owner key
  • (validator's) server key vs (validator's) client key <-- seems like the most precise because both keys belong to the validator node.

What do you think @deuszx @afck ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, but let's do the renaming in a single sweep in a separate PR. This one is already too big and it (rename) is orthogonal.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, this works.

For the records, ideally, you would start by renaming ValidatorState::public_key into something more specific like ValidatorState::server_public_key in order to "make space". Then this PR would add (say) ValidatorState::client_public_key.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Initially it was "authority key" which I think made sense (since validator can have many keys but only one is signing blocks).

Copy link
Contributor

@ma2bd ma2bd Feb 22, 2025

Choose a reason for hiding this comment

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

"authority key" is nice. Something like: "validator authority key" vs "validator user/owner/client key" then

Copy link
Contributor

@afck afck Feb 24, 2025

Choose a reason for hiding this comment

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

No strong opinion about the names, but let's do the renaming in a separate PR, yes. 👍

@deuszx deuszx force-pushed the secp256k1-validator-keys branch from ab824fb to 75ebeba Compare February 24, 2025 09:19
@deuszx deuszx merged commit fb36a49 into main Feb 24, 2025
24 checks passed
@deuszx deuszx deleted the secp256k1-validator-keys branch February 24, 2025 09:58
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