55from pydantic import Field
66
77from consensus_testing .test_fixtures .base import BaseConsensusFixture , BaseTestSpec
8+ from consensus_testing .test_fixtures .hex_codec import from_hex , to_hex
89from lean_spec .base import StrictBaseModel
910from lean_spec .node .networking .enr .enr import ENR
1011from lean_spec .node .networking .gossipsub .message import GossipsubMessage
3233from lean_spec .spec .forks import SubnetId
3334
3435
35- def _to_hex (data : bytes ) -> str :
36- """Format raw bytes as a 0x-prefixed hex string."""
37- return "0x" + data .hex ()
38-
39-
40- def _from_hex (hex_str : str ) -> bytes :
41- """Parse a 0x-prefixed hex string into raw bytes."""
42- return bytes .fromhex (hex_str .removeprefix ("0x" ))
43-
44-
4536class EncodedOutput (StrictBaseModel ):
4637 """Reference encoding for a roundtrip vector."""
4738
@@ -79,7 +70,7 @@ def run(self) -> VarintOutput:
7970 )
8071 assert byte_length == len (encoded ), f"Length: { byte_length } != { len (encoded )} "
8172
82- return VarintOutput (encoded = _to_hex (encoded ), byte_length = byte_length )
73+ return VarintOutput (encoded = to_hex (encoded ), byte_length = byte_length )
8374
8475
8576class GossipTopicOutput (StrictBaseModel ):
@@ -166,9 +157,9 @@ class GossipMessageIdentifier(StrictBaseModel):
166157 def run (self ) -> GossipMessageIdentifierOutput :
167158 """Compute the identifier: SHA256(domain + uint64_le(len(topic)) + topic + data)[:20]."""
168159 message_id = GossipsubMessage .compute_id (
169- _from_hex (self .topic ), _from_hex (self .data ), domain = _from_hex (self .domain )
160+ from_hex (self .topic ), from_hex (self .data ), domain = from_hex (self .domain )
170161 )
171- return GossipMessageIdentifierOutput (message_id = _to_hex (message_id ))
162+ return GossipMessageIdentifierOutput (message_id = to_hex (message_id ))
172163
173164
174165class RpcSubscriptionSpec (StrictBaseModel ):
@@ -205,12 +196,12 @@ class RpcMessageSpec(StrictBaseModel):
205196 def build (self ) -> Message :
206197 """Convert to the wire-format message."""
207198 return Message (
208- from_peer = _from_hex (self .from_peer ) if self .from_peer else b"" ,
209- data = _from_hex (self .data ) if self .data else b"" ,
210- seqno = _from_hex (self .seqno ) if self .seqno else b"" ,
199+ from_peer = from_hex (self .from_peer ) if self .from_peer else b"" ,
200+ data = from_hex (self .data ) if self .data else b"" ,
201+ seqno = from_hex (self .seqno ) if self .seqno else b"" ,
211202 topic = TopicId (self .topic ),
212- signature = _from_hex (self .signature ) if self .signature else b"" ,
213- key = _from_hex (self .key ) if self .key else b"" ,
203+ signature = from_hex (self .signature ) if self .signature else b"" ,
204+ key = from_hex (self .key ) if self .key else b"" ,
214205 )
215206
216207
@@ -279,14 +270,12 @@ def build(self) -> ControlMessage:
279270 ihave = [
280271 ControlIHave (
281272 topic_id = TopicId (ihave .topic_id ),
282- message_ids = [_from_hex (message_id ) for message_id in ihave .message_ids ],
273+ message_ids = [from_hex (message_id ) for message_id in ihave .message_ids ],
283274 )
284275 for ihave in self .ihave
285276 ],
286277 iwant = [
287- ControlIWant (
288- message_ids = [_from_hex (message_id ) for message_id in iwant .message_ids ]
289- )
278+ ControlIWant (message_ids = [from_hex (message_id ) for message_id in iwant .message_ids ])
290279 for iwant in self .iwant
291280 ],
292281 graft = [ControlGraft (topic_id = TopicId (graft .topic_id )) for graft in self .graft ],
@@ -296,7 +285,7 @@ def build(self) -> ControlMessage:
296285 ],
297286 idontwant = [
298287 ControlIDontWant (
299- message_ids = [_from_hex (message_id ) for message_id in idontwant .message_ids ]
288+ message_ids = [from_hex (message_id ) for message_id in idontwant .message_ids ]
300289 )
301290 for idontwant in self .idontwant
302291 ],
@@ -334,7 +323,7 @@ def run(self) -> EncodedOutput:
334323 re_encoded = RPC .decode (encoded ).encode ()
335324 assert encoded == re_encoded , "RPC roundtrip produced different bytes"
336325
337- return EncodedOutput (encoded = _to_hex (encoded ))
326+ return EncodedOutput (encoded = to_hex (encoded ))
338327
339328
340329class ReqRespRequestRoundtrip (StrictBaseModel ):
@@ -348,14 +337,14 @@ class ReqRespRequestRoundtrip(StrictBaseModel):
348337
349338 def run (self ) -> EncodedOutput :
350339 """Encode the request, decode it back, and emit the reference bytes."""
351- ssz_data = _from_hex (self .ssz_data )
340+ ssz_data = from_hex (self .ssz_data )
352341 encoded = encode_request (ssz_data )
353342
354343 # Decode must recover the original SSZ bytes.
355344 decoded = decode_request (encoded )
356345 assert decoded == ssz_data , "Request roundtrip produced different bytes"
357346
358- return EncodedOutput (encoded = _to_hex (encoded ))
347+ return EncodedOutput (encoded = to_hex (encoded ))
359348
360349
361350class ReqRespResponseRoundtrip (StrictBaseModel ):
@@ -373,15 +362,15 @@ class ReqRespResponseRoundtrip(StrictBaseModel):
373362 def run (self ) -> EncodedOutput :
374363 """Encode the response, decode it back, and emit the reference bytes."""
375364 code = ResponseCode (self .response_code )
376- ssz_data = _from_hex (self .ssz_data )
365+ ssz_data = from_hex (self .ssz_data )
377366 encoded = code .encode (ssz_data )
378367
379368 # Decode must recover both the response code and SSZ bytes.
380369 decoded_code , decoded_data = ResponseCode .decode (encoded )
381370 assert decoded_code == code , f"Code mismatch: { decoded_code } != { code } "
382371 assert decoded_data == ssz_data , "Response roundtrip produced different bytes"
383372
384- return EncodedOutput (encoded = _to_hex (encoded ))
373+ return EncodedOutput (encoded = to_hex (encoded ))
385374
386375
387376class ResponseChunkSpec (StrictBaseModel ):
@@ -424,9 +413,9 @@ def run(self) -> ResponseStreamOutput:
424413 """Encode every chunk back-to-back and emit the reference stream."""
425414 buffer = bytearray ()
426415 for chunk in self .chunks :
427- buffer .extend (ResponseCode (chunk .response_code ).encode (_from_hex (chunk .ssz_data )))
416+ buffer .extend (ResponseCode (chunk .response_code ).encode (from_hex (chunk .ssz_data )))
428417 return ResponseStreamOutput (
429- encoded = _to_hex (bytes (buffer )),
418+ encoded = to_hex (bytes (buffer )),
430419 chunk_count = len (self .chunks ),
431420 )
432421
@@ -516,19 +505,19 @@ def run(self) -> EnrOutput:
516505 eth2_data = enr .eth2_data
517506 attestation_subnets = enr .attestation_subnets
518507 return EnrOutput (
519- rlp = _to_hex (rlp_bytes ),
508+ rlp = to_hex (rlp_bytes ),
520509 seq = int (enr .seq ),
521510 identity_scheme = enr .identity_scheme ,
522- node_id = _to_hex (enr .node_id ) if enr .node_id else None ,
523- public_key = _to_hex (enr .public_key ) if enr .public_key else None ,
511+ node_id = to_hex (enr .node_id ) if enr .node_id else None ,
512+ public_key = to_hex (enr .public_key ) if enr .public_key else None ,
524513 ip4 = enr .ip4 if enr .ip4 else None ,
525514 udp_port = int (enr .udp_port ) if enr .udp_port is not None else None ,
526515 quic_port = int (enr .quic_port ) if enr .quic_port is not None else None ,
527516 multiaddr = str (enr .multiaddr ()) if enr .multiaddr () is not None else None ,
528517 eth2_data = (
529518 EnrEth2DataOutput (
530- fork_digest = _to_hex (eth2_data .fork_digest ),
531- next_fork_version = _to_hex (eth2_data .next_fork_version ),
519+ fork_digest = to_hex (eth2_data .fork_digest ),
520+ next_fork_version = to_hex (eth2_data .next_fork_version ),
532521 next_fork_epoch = int (eth2_data .next_fork_epoch ),
533522 )
534523 if eth2_data is not None
@@ -576,7 +565,7 @@ def run(self) -> PeerIdentifierOutput:
576565 "rsa" : KeyType .RSA ,
577566 }
578567 protobuf = PublicKeyProtobuf (
579- key_type = key_type_map [self .key_type ], key_data = _from_hex (self .public_key )
568+ key_type = key_type_map [self .key_type ], key_data = from_hex (self .public_key )
580569 )
581570 peer_id = PeerId .from_public_key (protobuf )
582571 peer_id_string = str (peer_id )
@@ -586,7 +575,7 @@ def run(self) -> PeerIdentifierOutput:
586575 assert roundtrip == peer_id , "PeerId Base58 roundtrip failed"
587576
588577 return PeerIdentifierOutput (
589- protobuf_encoded = _to_hex (protobuf .encode ()),
578+ protobuf_encoded = to_hex (protobuf .encode ()),
590579 peer_id = peer_id_string ,
591580 )
592581
@@ -615,14 +604,14 @@ class SnappyBlockRoundtrip(StrictBaseModel):
615604
616605 def run (self ) -> SnappyBlockOutput :
617606 """Compress, decompress back, and emit the reference bytes."""
618- uncompressed_bytes = _from_hex (self .data )
607+ uncompressed_bytes = from_hex (self .data )
619608 compressed = compress (uncompressed_bytes )
620609
621610 decompressed = decompress (compressed )
622611 assert decompressed == uncompressed_bytes , "Snappy block roundtrip produced different bytes"
623612
624613 return SnappyBlockOutput (
625- compressed = _to_hex (compressed ),
614+ compressed = to_hex (compressed ),
626615 compressed_length = len (compressed ),
627616 uncompressed_length = len (uncompressed_bytes ),
628617 )
@@ -652,14 +641,14 @@ class SnappyFrameRoundtrip(StrictBaseModel):
652641
653642 def run (self ) -> SnappyFrameOutput :
654643 """Compress with framing, decompress back, and emit the reference bytes."""
655- uncompressed_bytes = _from_hex (self .data )
644+ uncompressed_bytes = from_hex (self .data )
656645 framed = frame_compress (uncompressed_bytes )
657646
658647 decompressed = frame_decompress (framed )
659648 assert decompressed == uncompressed_bytes , "Snappy frame roundtrip produced different bytes"
660649
661650 return SnappyFrameOutput (
662- framed = _to_hex (framed ),
651+ framed = to_hex (framed ),
663652 framed_length = len (framed ),
664653 uncompressed_length = len (uncompressed_bytes ),
665654 )
@@ -704,7 +693,7 @@ def attempt_decode(self) -> Exception | None:
704693 "enr" : ENR .from_rlp ,
705694 }
706695 try :
707- decoders [self .decoder ](_from_hex (self .raw_bytes ))
696+ decoders [self .decoder ](from_hex (self .raw_bytes ))
708697 except Exception as exception :
709698 return exception
710699 return None
0 commit comments