Skip to content

Commit f1e6ff1

Browse files
authored
feat(signer): add ECDSA proxy keys (#87)
1 parent 828b108 commit f1e6ff1

File tree

24 files changed

+1053
-369
lines changed

24 files changed

+1053
-369
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ blst = "0.3.11"
6262
tree_hash = "0.5"
6363
tree_hash_derive = "0.5"
6464
eth2_keystore = { git = "https://github.com/sigp/lighthouse", rev = "9e12c21f268c80a3f002ae0ca27477f9f512eb6f" }
65+
k256 = "0.13"
6566

6667
# docker
6768
docker-compose-types = "0.12.0"
@@ -79,4 +80,4 @@ dotenvy = "0.15.7"
7980
indexmap = "2.2.6"
8081
lazy_static = "1.5.0"
8182
bimap = { version = "0.6.3", features = ["serde"] }
82-
derive_more = "0.99.18"
83+
derive_more = { version = "1.0.0", features = ["from", "into", "deref", "display"] }

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ async fn main() {
5151
let pubkey = *pubkeys.consensus.first().unwrap();
5252

5353
let datagram = Datagram { data: 42 };
54-
let request = SignRequest::builder(pubkey).with_msg(&datagram);
54+
let request = SignConsensusRequest::builder(pubkey).with_msg(&datagram);
5555
let signature = config
5656
.signer_client
57-
.request_signature(&request)
57+
.request_consensus_signature(&request)
5858
.await
5959
.unwrap();
6060

api/signer-api.yml

Lines changed: 102 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ paths:
1515
- BearerAuth: []
1616
responses:
1717
"200":
18-
description: A list of Bls pubkeys
18+
description: "All public keys available to the module: consensus pubkeys (BLS) and proxy pubkeys (BLS and ECDSA)"
1919
content:
2020
application/json:
2121
schema:
@@ -25,18 +25,17 @@ paths:
2525
description: Consensus validator pubkeys
2626
type: array
2727
items:
28-
type: string
29-
format: hex
30-
pattern: "^0x[a-fA-F0-9]{96}$"
31-
example: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
32-
proxy:
33-
description: Proxy validator pubkeys
28+
$ref: '#/components/schemas/BlsPubkey'
29+
proxy_bls:
30+
description: BLS proxy validator pubkeys
3431
type: array
3532
items:
36-
type: string
37-
format: hex
38-
pattern: "^0x[a-fA-F0-9]{96}$"
39-
example: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
33+
$ref: '#/components/schemas/BlsPubkey'
34+
proxy_ecdsa:
35+
description: ECDSA proxy validator pubkeys
36+
type: array
37+
items:
38+
$ref: '#/components/schemas/EcdsaPubkey'
4039
"500":
4140
description: Internal error
4241
content:
@@ -67,34 +66,55 @@ paths:
6766
application/json:
6867
schema:
6968
type: object
69+
required: [type, pubkey, object_root]
7070
properties:
71-
pubkey:
72-
description: BLS public key of validator
71+
type:
72+
description: Type of the sign request
7373
type: string
74-
format: hex
75-
pattern: "^0x[a-fA-F0-9]{96}$"
76-
example: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
77-
is_proxy:
78-
description: Whether the request is for a proxy pubkey
79-
type: boolean
80-
example: false
74+
enum: [consensus, proxy_bls, proxy_ecdsa]
75+
pubkey:
76+
description: Public key of the validator
77+
oneOf:
78+
- $ref: '#/components/schemas/BlsPubkey'
79+
- $ref: '#/components/schemas/EcdsaPubkey'
8180
object_root:
8281
description: The root of the object to be signed
8382
type: string
8483
format: hex
8584
pattern: "^0x[a-fA-F0-9]{64}$"
8685
example: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9"
86+
examples:
87+
Consensus:
88+
value:
89+
type: "consensus"
90+
pubkey: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
91+
object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9"
92+
ProxyBls:
93+
value:
94+
type: "proxy_bls"
95+
pubkey: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
96+
object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9"
97+
ProxyEcdsa:
98+
value:
99+
type: "proxy_ecdsa"
100+
pubkey: "0x023b2806b1b1dfa34dd90b01546906cef3e4c8e0fc0cba60480e9eb4d0a0828311"
101+
object_root: "0x3e9f4a78b5c21d64f0b8e3d9a7f5c02b4d1e67a3c8f29b5d6e4a3b1c8f72e6d9"
87102
responses:
88103
"200":
89-
description: Successs
104+
description: Success
90105
content:
91106
application/json:
92107
schema:
93-
type: string
94-
description: The validator signature
95-
format: hex
96-
pattern: "^0x[a-fA-F0-9]{192}$"
97-
example: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
108+
oneOf:
109+
- $ref: '#/components/schemas/BlsSignature'
110+
- $ref: '#/components/schemas/EcdsaSignature'
111+
examples:
112+
Consensus:
113+
value: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
114+
ProxyBls:
115+
value: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
116+
ProxyEcdsa:
117+
value: "0xe6a0c0c41a6d4af9794882c18c5280376cbfb7921453612dea02ed8f47b1208455f07931dc12c4b70c4e8ae216db0136000ec2cf17244189f012de356ac46cec"
98118
"404":
99119
description: Unknown value (pubkey, etc.)
100120
content:
@@ -141,13 +161,25 @@ paths:
141161
application/json:
142162
schema:
143163
type: object
164+
required: [pubkey, scheme]
144165
properties:
145166
pubkey:
146167
description: a validator BLS public key for which to generate a proxy key
168+
allOf:
169+
- $ref: '#/components/schemas/BlsPubkey'
170+
scheme:
171+
description: signature scheme to generate proxy keypair for
147172
type: string
148-
format: hex
149-
pattern: "^0x[a-fA-F0-9]{96}$"
150-
example: "0xac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118"
173+
enum: [bls, ecdsa]
174+
examples:
175+
Bls:
176+
value:
177+
pubkey: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a"
178+
scheme: "bls"
179+
Ecdsa:
180+
value:
181+
pubkey: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a"
182+
scheme: "ecdsa"
151183
responses:
152184
"200":
153185
description: Successs
@@ -161,22 +193,30 @@ paths:
161193
properties:
162194
delegator:
163195
description: the validator BLS public key for which the proxy key was generated (the same one as requested)
164-
type: string
165-
format: hex
166-
pattern: "^0x[a-fA-F0-9]{96}$"
167-
example: "0xac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118"
196+
allOf:
197+
- $ref: '#/components/schemas/BlsPubkey'
168198
proxy:
169199
description: the generated proxy public key
170-
type: string
171-
format: hex
172-
pattern: "^0x[a-fA-F0-9]{96}$"
173-
example: "0x8a481a7a51c430a9bafa64366bc4934f5880f5f1d97646f91680936a53f2a268fdde5369430a2b4bb700c5f82cfbab3f"
200+
oneOf:
201+
- $ref: '#/components/schemas/BlsPubkey'
202+
- $ref: '#/components/schemas/EcdsaPubkey'
174203
signature:
175204
description: The signature of the proxy delegation
176-
type: string
177-
format: hex
178-
pattern: "^0x[a-fA-F0-9]{192}$"
179-
example: "0xabfacf1cd17d80abfc6fa6b8e534ab25cdb1f95a855706ef604672c8695401a84c7834008e57925d4259c551b7c03d1a16f05b082294fadcba802a61a5cccfb5e96dd1dce4c9dac3f6d15254495019146346670be1f374a67cb0cda2aaf72d00"
205+
allOf:
206+
- $ref: '#/components/schemas/BlsSignature'
207+
examples:
208+
Bls:
209+
value:
210+
message:
211+
delegator: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a"
212+
proxy: "0xb646318d81b7cff3f8aae5040eab11927b4a99542c02970a1ab8069a83e5b76b302705d0b5e0054831ce2af72088bf30"
213+
signature: "0x88274f2d78d30ae429cc16f5c64657b491ccf26291c821cf953da34f16d60947d4f245decdce4a492e8d8f949482051b184aaa890d5dd97788387689335a1fee37cbe55c0227f81b073ce6e93b45f96169f497ed322d3d384d79ccaa7846d5ab"
214+
Ecdsa:
215+
value:
216+
message:
217+
delegator: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a"
218+
proxy: "0x023b2806b1b1dfa34dd90b01546906cef3e4c8e0fc0cba60480e9eb4d0a0828311"
219+
signature: "0xb5b5b71d1701cc45086af3d3d86bf9d3c509442835e5b9f7734923edc9a6c538e743d70613cdef90b7e5b171fbbe6a29075b3f155e4bd66d81ff9dbc3b6d7fa677d169b2ceab727ffa079a31fe1fc0e478752e9da9566a9408e4db24ac6104db"
180220
"404":
181221
description: Unknown value (pubkey, etc.)
182222
content:
@@ -216,3 +256,24 @@ components:
216256
type: http
217257
scheme: bearer
218258
bearerFormat: JWT
259+
schemas:
260+
BlsPubkey:
261+
type: string
262+
format: hex
263+
pattern: "^0x[a-fA-F0-9]{96}$"
264+
example: "0xa9e9cff900de07e295a044789fd4bdb6785eb0651ad282f9e76d12afd87e75180bdd64caf2e315b815d7322bd31ab48a"
265+
EcdsaPubkey:
266+
type: string
267+
format: hex
268+
pattern: "^0x[a-fA-F0-9]{64}$"
269+
example: "0x023b2806b1b1dfa34dd90b01546906cef3e4c8e0fc0cba60480e9eb4d0a0828311"
270+
BlsSignature:
271+
type: string
272+
format: hex
273+
pattern: "^0x[a-fA-F0-9]{192}$"
274+
example: "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989"
275+
EcdsaSignature:
276+
type: string
277+
format: hex
278+
pattern: "^0x[a-fA-F0-9]{128}$"
279+
example: "0xe6a0c0c41a6d4af9794882c18c5280376cbfb7921453612dea02ed8f47b1208455f07931dc12c4b70c4e8ae216db0136000ec2cf17244189f012de356ac46cec"

bin/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
pub mod prelude {
22
pub use cb_common::{
33
commit,
4-
commit::request::{SignRequest, SignedProxyDelegation},
4+
commit::request::{
5+
SignConsensusRequest, SignProxyRequest, SignedProxyDelegation,
6+
SignedProxyDelegationBls, SignedProxyDelegationEcdsa,
7+
},
58
config::{
69
load_builder_module_config, load_commit_module_config, load_pbs_config,
710
load_pbs_custom_config, StartCommitModuleConfig,
811
},
912
pbs::{BuilderEvent, BuilderEventClient, OnBuilderApiEvent},
13+
signer::{BlsPublicKey, BlsSignature, EcdsaPublicKey, EcdsaSignature},
1014
utils::{
1115
initialize_pbs_tracing_log, initialize_tracing_log, utcnow_ms, utcnow_ns, utcnow_sec,
1216
utcnow_us,

config.example.toml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# The main configuration file for the Commit-Boost sidecar.
1+
# The main configuration file for the Commit-Boost sidecar.
22
# Some fields are optional and can be omitted, in which case the default value, if present, will be used.
33

44
# Chain spec id. Supported values: Mainnet, Holesky, Helder
@@ -18,7 +18,7 @@ port = 18550
1818
# Whether to forward `status` calls to relays or skip and return 200
1919
# OPTIONAL, DEFAULT: true
2020
relay_check = true
21-
# Timeout in milliseconds for the `get_header` call to relays. Note that the CL has also a timeout (e.g. 1 second) so
21+
# Timeout in milliseconds for the `get_header` call to relays. Note that the CL has also a timeout (e.g. 1 second) so
2222
# this should be lower than that, leaving some margin for overhead
2323
# OPTIONAL, DEFAULT: 950
2424
timeout_get_header_ms = 950
@@ -34,10 +34,11 @@ skip_sigverify = false
3434
# Minimum bid in ETH that will be accepted from `get_header`
3535
# OPTIONAL, DEFAULT: 0.0
3636
min_bid_eth = 0.0
37+
# How late in milliseconds in the slot is "late". This impacts the `get_header` requests, by shortening timeouts for `get_header` calls to
3738
# List of URLs of relay monitors to send registrations to
3839
# OPTIONAL
3940
relay_monitors = []
40-
# How late in milliseconds in the slot is "late". This impacts the `get_header` requests, by shortening timeouts for `get_header` calls to
41+
# How late in milliseconds in the slot is "late". This impacts the `get_header` requests, by shortening timeouts for `get_header` calls to
4142
# relays and make sure a header is returned within this deadline. If the request from the CL comes later in the slot, then fetching headers is skipped
4243
# to force local building and miniminzing the risk of missed slots. See also the timing games section below
4344
# OPTIONAL, DEFAULT: 2000
@@ -55,12 +56,12 @@ url = "http://0xa1cec75a3f0661e99299274182938151e8433c61a19222347ea1313d839229cb
5556
headers = { X-MyCustomHeader = "MyCustomValue" }
5657
# Whether to enable timing games, as tuned by `target_first_request_ms` and `frequency_get_header_ms`.
5758
# These values should be carefully chosen for each relay, as each relay has different latency and timing games setups.
58-
# They should only be used by advanced users, and if mis-configured can result in unforeseen effects, e.g. fetching a lower header value,
59+
# They should only be used by advanced users, and if mis-configured can result in unforeseen effects, e.g. fetching a lower header value,
5960
# or getting a temporary IP ban.
60-
#
61+
#
6162
# EXAMPLES
6263
# Assuming: timeout_get_header_ms = 950, frequency_get_header_ms = 300, target_first_request_ms = 200, late_in_slot_time_ms = 2000
63-
#
64+
#
6465
# 1) CL request comes at 100ms in the slot (max timeout 1050ms in the slot), then:
6566
# - sleep for 100ms
6667
# - send request at 200ms with 850ms timeout
@@ -112,13 +113,13 @@ id = "DA_COMMIT"
112113
type = "commit"
113114
# Docker image of the module
114115
docker_image = "test_da_commit"
115-
# Additional config needed by the business logic of the module should also be set here.
116+
# Additional config needed by the business logic of the module should also be set here.
116117
# See also `examples/da_commit/src/main.rs` for more information
117118
sleep_secs = 5
118119

119120
# Configuration for how metrics should be collected and scraped
120121
[metrics]
121-
# Path to a `prometheus.yml` file to use in Prometheus. If using a custom config file, be sure to add a
122+
# Path to a `prometheus.yml` file to use in Prometheus. If using a custom config file, be sure to add a
122123
# file discovery section as follows:
123124
# ```yml
124125
# file_sd_configs:

crates/common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ blst.workspace = true
3535
tree_hash.workspace = true
3636
tree_hash_derive.workspace = true
3737
eth2_keystore.workspace = true
38+
k256.workspace = true
3839

3940
# misc
4041
thiserror.workspace = true

0 commit comments

Comments
 (0)