@@ -106,8 +106,8 @@ pub const Shred = extern struct {
106106 };
107107
108108 /// NOTE: Legacy Code and Data shreds are defined like this, which isn't compatible with the
109- /// layout of our packed struct. To get around this .isSupported () **must** return true
110- /// before using any of the other methods.
109+ /// layout of our packed struct. To get around this .hasSupportedVariant () **must** return
110+ /// true casting to a `Shred` and using any of the other methods.
111111 ///
112112 /// pub enum ShredType {
113113 /// Data = 0b1010_0101,
@@ -116,28 +116,16 @@ pub const Shred = extern struct {
116116 ///
117117 pub const Variant = packed struct (u8 ) {
118118 merkle_count : u4 ,
119- kind : enum (u4 ) {
120- // all supported kinds
119+ kind : Kind ,
120+
121+ const Kind = enum (u4 ) {
121122 merkle_code_chained = 0x6 ,
122123 merkle_code_chained_resigned = 0x7 ,
123124 merkle_data_chained = 0x9 ,
124125 merkle_data_chained_resigned = 0xB ,
125- _ ,
126- },
127-
128- // [firedancer] https://github.com/firedancer-io/firedancer/blob/9f7770af997a1443e7903113fc03ca1ce3b0ad73/src/ballet/shred/fd_shred.c#L16
129- // Legacy (non-merkle), and non-chained shreds are deprecated
130- // https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0313-drop-unchained-merkle-shreds.md
131- fn isSupported (self : Variant ) bool {
132- return switch (self .kind ) {
133- _ = > false ,
134- else = > true ,
135- };
136- }
126+ };
137127
138128 fn headerSize (self : Variant ) u8 {
139- std .debug .assert (self .isSupported ());
140-
141129 return @as (u8 , @offsetOf (Shred , "code_or_data" )) + if (self .isData ())
142130 @as (u8 , @sizeOf (DataHeader ))
143131 else
@@ -148,15 +136,13 @@ pub const Shred = extern struct {
148136 return switch (self .kind ) {
149137 .merkle_data_chained_resigned , .merkle_code_chained_resigned = > true ,
150138 .merkle_data_chained , .merkle_code_chained = > false ,
151- _ = > unreachable , // unsupported variant
152139 };
153140 }
154141
155142 pub fn isData (self : Variant ) bool {
156143 return switch (self .kind ) {
157144 .merkle_data_chained , .merkle_data_chained_resigned = > true ,
158145 .merkle_code_chained , .merkle_code_chained_resigned = > false ,
159- _ = > unreachable , // unsupported variant
160146 };
161147 }
162148
@@ -165,8 +151,6 @@ pub const Shred = extern struct {
165151 }
166152
167153 fn merkleSize (self : Variant ) u16 {
168- std .debug .assert (self .isSupported ());
169-
170154 return @as (u16 , self .merkle_count ) * merkle_node_size ;
171155 }
172156
@@ -183,7 +167,6 @@ pub const Shred = extern struct {
183167 .merkle_code_chained_resigned = > .merkle_data_chained_resigned ,
184168 .merkle_data_chained = > .merkle_code_chained ,
185169 .merkle_data_chained_resigned = > .merkle_code_chained_resigned ,
186- _ = > unreachable , // unsupported variant
187170 },
188171 };
189172 }
@@ -204,9 +187,9 @@ pub const Shred = extern struct {
204187 /// Makes sure that the *layout* of the Shred is valid.
205188 pub fn fromPacketChecked (packet : * const Packet ) ! * const Shred {
206189 if (packet .len < min_header_size ) return error .PacketUnderMinHeaderSize ;
190+ if (! Shred .hasSupportedVariant (& packet .data )) return error .UnsupportedVariant ;
207191
208192 const shred : * const Shred = @ptrCast (packet );
209- if (! shred .variant .isSupported ()) return error .UnsupportedVariant ;
210193
211194 const header_size : u16 = shred .variant .headerSize ();
212195 if (packet .len < header_size ) return error .PacketUnderHeaderSize ;
@@ -274,7 +257,17 @@ pub const Shred = extern struct {
274257 return shred ;
275258 }
276259
260+ // [firedancer] https://github.com/firedancer-io/firedancer/blob/9f7770af997a1443e7903113fc03ca1ce3b0ad73/src/ballet/shred/fd_shred.c#L16
261+ // Legacy (non-merkle), and non-chained shreds are deprecated
262+ // https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0313-drop-unchained-merkle-shreds.md
263+ pub fn hasSupportedVariant (buffer : * const Packet.Buffer ) bool {
264+ const BareVariant = packed struct (u8 ) { merkle_count : u4 , kind : u4 };
265+ const bare_variant : BareVariant = @bitCast (buffer [@offsetOf (Shred , "variant" ).. ][0 ]);
266+ return std .enums .fromInt (Variant .Kind , bare_variant .kind ) != null ;
267+ }
268+
277269 pub fn fromBufferUnchecked (buffer : * const Packet.Buffer ) * const Shred {
270+ std .debug .assert (Shred .hasSupportedVariant (buffer ));
278271 return @ptrCast (buffer );
279272 }
280273
0 commit comments