1use {
2 prost::{
3 DecodeError,
4 bytes::Buf,
5 encoding::{self, DecodeContext, WireType, check_wire_type, decode_key, decode_varint},
6 },
7 prost_types::Timestamp,
8 solana_clock::{Epoch, Slot},
9 solana_pubkey::{PUBKEY_BYTES, Pubkey},
10 solana_signature::SIGNATURE_BYTES,
11 std::{borrow::Cow, collections::HashSet, mem::MaybeUninit, ops::Range},
12};
13
14#[allow(deprecated)]
15fn create_decode_error(description: impl Into<Cow<'static, str>>) -> DecodeError {
16 DecodeError::new(description)
17}
18
19fn decode_error(
20 description: impl Into<Cow<'static, str>>,
21 stack: &[(&'static str, &'static str)],
22) -> DecodeError {
23 let mut error = create_decode_error(description);
24 for (message, field) in stack {
25 error.push(message, field);
26 }
27 error
28}
29
30fn decode_pubkey(
31 buf: &mut impl Buf,
32 wire_type: WireType,
33 struct_name: &'static str,
34 field: &'static str,
35) -> Result<Pubkey, DecodeError> {
36 check_wire_type(WireType::LengthDelimited, wire_type)?;
37 let len = decode_varint(buf)? as usize;
38 if len > buf.remaining() {
39 return Err(decode_error("buffer underflow", &[(struct_name, field)]));
40 }
41 if len != PUBKEY_BYTES {
42 return Err(decode_error(
43 "invalid pubkey length",
44 &[(struct_name, field)],
45 ));
46 }
47 let mut pubkey = MaybeUninit::<[u8; PUBKEY_BYTES]>::uninit();
48 buf.copy_to_slice(unsafe { &mut *pubkey.as_mut_ptr() });
49 Ok(unsafe { pubkey.assume_init() }.into())
50}
51
52pub trait LimitedDecode: Default {
53 fn decode(mut buf: impl Buf) -> Result<Self, DecodeError> {
54 let buf_len = buf.remaining();
55 let mut message = Self::default();
56 while buf.has_remaining() {
57 let (tag, wire_type) = decode_key(&mut buf)?;
58 message.merge_field(tag, wire_type, &mut buf, buf_len)?;
59 }
60 Ok(message)
61 }
62
63 fn merge_field(
64 &mut self,
65 tag: u32,
66 wire_type: WireType,
67 buf: &mut impl Buf,
68 buf_len: usize,
69 ) -> Result<(), DecodeError>;
70}
71
72#[derive(Debug, Default)]
73pub struct SubscribeUpdateLimitedDecode {
74 pub update_oneof: Option<UpdateOneofLimitedDecode>,
75 pub created_at: Option<Timestamp>,
76}
77
78impl LimitedDecode for SubscribeUpdateLimitedDecode {
79 fn merge_field(
80 &mut self,
81 tag: u32,
82 wire_type: WireType,
83 buf: &mut impl Buf,
84 buf_len: usize,
85 ) -> Result<(), DecodeError> {
86 const STRUCT_NAME: &str = "SubscribeUpdateLimitedDecode";
87 check_wire_type(WireType::LengthDelimited, wire_type)?;
88 match tag {
89 1u32 => {
90 let len = decode_varint(buf)? as usize;
91 if len > buf.remaining() {
92 return Err(decode_error(
93 "buffer underflow",
94 &[(STRUCT_NAME, "filters")],
95 ));
96 }
97 buf.advance(len);
98 Ok(())
99 }
100 #[allow(clippy::manual_range_patterns)]
101 2u32 | 3u32 | 4u32 | 10u32 | 5u32 | 6u32 | 9u32 | 7u32 | 8u32 => {
102 let value = &mut self.update_oneof;
103 UpdateOneofLimitedDecode::merge(value, tag, buf, buf_len).map_err(|mut error| {
104 error.push(STRUCT_NAME, "update_oneof");
105 error
106 })
107 }
108 11u32 => {
109 let value = &mut self.created_at;
110 encoding::message::merge(
111 WireType::LengthDelimited,
112 value.get_or_insert_with(Default::default),
113 buf,
114 DecodeContext::default(),
115 )
116 .map_err(|mut error| {
117 error.push(STRUCT_NAME, "created_at");
118 error
119 })
120 }
121 _ => encoding::skip_field(
122 WireType::LengthDelimited,
123 tag,
124 buf,
125 DecodeContext::default(),
126 ),
127 }
128 }
129}
130
131#[derive(Debug)]
132pub enum UpdateOneofLimitedDecode {
133 Account(Range<usize>),
134 Slot(Range<usize>),
135 Transaction(Range<usize>),
136 TransactionStatus(Range<usize>),
137 Block(Range<usize>),
138 Ping(Range<usize>),
139 Pong(Range<usize>),
140 BlockMeta(Range<usize>),
141 Entry(Range<usize>),
142}
143
144impl UpdateOneofLimitedDecode {
145 pub fn merge(
146 field: &mut Option<Self>,
147 tag: u32,
148 buf: &mut impl Buf,
149 buf_len: usize,
150 ) -> Result<(), DecodeError> {
151 let len = decode_varint(buf)? as usize;
152 if len > buf.remaining() {
153 return Err(create_decode_error("buffer underflow"));
154 }
155
156 let start = buf_len - buf.remaining();
157 buf.advance(len);
158 let end = buf_len - buf.remaining();
159 let range = Range { start, end };
160
161 match tag {
162 2u32 => match field {
163 Some(Self::Account(_)) => Err(create_decode_error("merge is not supported")),
164 _ => {
165 *field = Some(Self::Account(range));
166 Ok(())
167 }
168 },
169 3u32 => match field {
170 Some(Self::Slot(_)) => Err(create_decode_error("merge is not supported")),
171 _ => {
172 *field = Some(Self::Slot(range));
173 Ok(())
174 }
175 },
176 4u32 => match field {
177 Some(Self::Transaction(_)) => Err(create_decode_error("merge is not supported")),
178 _ => {
179 *field = Some(Self::Transaction(range));
180 Ok(())
181 }
182 },
183 10u32 => match field {
184 Some(Self::TransactionStatus(_)) => {
185 Err(create_decode_error("merge is not supported"))
186 }
187 _ => {
188 *field = Some(Self::TransactionStatus(range));
189 Ok(())
190 }
191 },
192 5u32 => match field {
193 Some(Self::Block(_)) => Err(create_decode_error("merge is not supported")),
194 _ => {
195 *field = Some(Self::Block(range));
196 Ok(())
197 }
198 },
199 6u32 => match field {
200 Some(Self::Ping(_)) => Err(create_decode_error("merge is not supported")),
201 _ => {
202 *field = Some(Self::Ping(range));
203 Ok(())
204 }
205 },
206 9u32 => match field {
207 Some(Self::Pong(_)) => Err(create_decode_error("merge is not supported")),
208 _ => {
209 *field = Some(Self::Pong(range));
210 Ok(())
211 }
212 },
213 7u32 => match field {
214 Some(Self::BlockMeta(_)) => Err(create_decode_error("merge is not supported")),
215 _ => {
216 *field = Some(Self::BlockMeta(range));
217 Ok(())
218 }
219 },
220 8u32 => match field {
221 Some(Self::Entry(_)) => Err(create_decode_error("merge is not supported")),
222 _ => {
223 *field = Some(Self::Entry(range));
224 Ok(())
225 }
226 },
227 _ => unreachable!(),
228 }
229 }
230}
231
232#[derive(Debug)]
233pub struct UpdateOneofLimitedDecodeAccount {
234 pub account: usize,
235 pub pubkey: Pubkey,
236 pub owner: Pubkey,
237 pub lamports: u64,
238 pub executable: bool,
239 pub rent_epoch: Epoch,
240 pub data: Range<usize>,
241 pub txn_signature_offset: Option<usize>,
242 pub write_version: usize,
243 pub slot: Slot,
244 pub is_startup: bool,
245}
246
247impl Default for UpdateOneofLimitedDecodeAccount {
248 fn default() -> Self {
249 Self {
250 account: usize::MAX,
251 pubkey: Pubkey::default(),
252 owner: Pubkey::default(),
253 lamports: u64::default(),
254 executable: bool::default(),
255 rent_epoch: Epoch::default(),
256 data: Range::default(),
257 txn_signature_offset: Option::default(),
258 write_version: usize::default(),
259 slot: Slot::default(),
260 is_startup: bool::default(),
261 }
262 }
263}
264
265impl LimitedDecode for UpdateOneofLimitedDecodeAccount {
266 fn merge_field(
267 &mut self,
268 tag: u32,
269 wire_type: WireType,
270 buf: &mut impl Buf,
271 buf_len: usize,
272 ) -> Result<(), DecodeError> {
273 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeAccount";
274 let ctx = DecodeContext::default();
275 match tag {
276 1u32 => {
277 check_wire_type(WireType::LengthDelimited, wire_type)?;
278 self.account = buf_len - buf.remaining();
279 self.account_merge(buf, buf_len).map_err(|mut error| {
280 error.push(STRUCT_NAME, "account");
281 error
282 })
283 }
284 2u32 => {
285 let value = &mut self.slot;
286 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
287 error.push(STRUCT_NAME, "slot");
288 error
289 })
290 }
291 3u32 => {
292 let value = &mut self.is_startup;
293 encoding::bool::merge(wire_type, value, buf, ctx).map_err(|mut error| {
294 error.push(STRUCT_NAME, "is_startup");
295 error
296 })
297 }
298 _ => encoding::skip_field(wire_type, tag, buf, ctx),
299 }
300 }
301}
302
303impl UpdateOneofLimitedDecodeAccount {
304 fn account_merge(&mut self, buf: &mut impl Buf, buf_len: usize) -> Result<(), DecodeError> {
305 let len = decode_varint(buf)?;
306 let remaining = buf.remaining();
307 if len > remaining as u64 {
308 return Err(create_decode_error("buffer underflow"));
309 }
310
311 let limit = remaining - len as usize;
312 while buf.remaining() > limit {
313 let (tag, wire_type) = decode_key(buf)?;
314 self.account_merge_field(tag, wire_type, buf, buf_len)?;
315 }
316
317 if buf.remaining() != limit {
318 return Err(create_decode_error("delimited length exceeded"));
319 }
320 Ok(())
321 }
322
323 fn account_merge_field(
324 &mut self,
325 tag: u32,
326 wire_type: WireType,
327 buf: &mut impl Buf,
328 buf_len: usize,
329 ) -> Result<(), DecodeError> {
330 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeAccount";
331 let ctx = DecodeContext::default();
332 match tag {
333 1u32 => {
334 self.pubkey = decode_pubkey(buf, wire_type, STRUCT_NAME, "pubkey")?;
335 Ok(())
336 }
337 2u32 => {
338 let value = &mut self.lamports;
339 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
340 error.push(STRUCT_NAME, "lamports");
341 error
342 })
343 }
344 3u32 => {
345 self.owner = decode_pubkey(buf, wire_type, STRUCT_NAME, "owner")?;
346 Ok(())
347 }
348 4u32 => {
349 let value = &mut self.executable;
350 encoding::bool::merge(wire_type, value, buf, ctx).map_err(|mut error| {
351 error.push(STRUCT_NAME, "executable");
352 error
353 })
354 }
355 5u32 => {
356 let value = &mut self.rent_epoch;
357 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
358 error.push(STRUCT_NAME, "rent_epoch");
359 error
360 })
361 }
362 6u32 => {
363 check_wire_type(WireType::LengthDelimited, wire_type)?;
364 let len = decode_varint(buf)? as usize;
365 if len > buf.remaining() {
366 return Err(decode_error("buffer underflow", &[(STRUCT_NAME, "data")]));
367 }
368
369 let start = buf_len - buf.remaining();
370 buf.advance(len);
371 let end = buf_len - buf.remaining();
372 self.data = Range { start, end };
373 Ok(())
374 }
375 7u32 => {
376 self.write_version = buf_len - buf.remaining();
377 let mut value = 0;
378 encoding::uint64::merge(wire_type, &mut value, buf, ctx).map_err(|mut error| {
379 error.push(STRUCT_NAME, "write_version");
380 error
381 })
382 }
383 8u32 => {
384 check_wire_type(WireType::LengthDelimited, wire_type)?;
385 let len = decode_varint(buf)? as usize;
386 if len > buf.remaining() {
387 return Err(decode_error(
388 "buffer underflow",
389 &[(STRUCT_NAME, "txn_signature")],
390 ));
391 }
392 if len != SIGNATURE_BYTES {
393 return Err(decode_error(
394 "invalid signature length",
395 &[(STRUCT_NAME, "txn_signature")],
396 ));
397 }
398 self.txn_signature_offset = Some(buf_len - buf.remaining());
399 buf.advance(len);
400 Ok(())
401 }
402 _ => encoding::skip_field(wire_type, tag, buf, ctx),
403 }
404 }
405}
406
407#[derive(Debug, Default)]
408pub struct UpdateOneofLimitedDecodeSlot {
409 pub slot: Slot,
410 pub parent: Option<Slot>,
411 pub status: i32,
412 pub dead_error: Option<Range<usize>>,
413}
414
415impl LimitedDecode for UpdateOneofLimitedDecodeSlot {
416 fn merge_field(
417 &mut self,
418 tag: u32,
419 wire_type: WireType,
420 buf: &mut impl Buf,
421 buf_len: usize,
422 ) -> Result<(), DecodeError> {
423 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeSlot";
424 let ctx = DecodeContext::default();
425 match tag {
426 1u32 => {
427 let value = &mut self.slot;
428 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
429 error.push(STRUCT_NAME, "slot");
430 error
431 })
432 }
433 2u32 => {
434 let value = &mut self.parent;
435 encoding::uint64::merge(
436 wire_type,
437 value.get_or_insert_with(Default::default),
438 buf,
439 ctx,
440 )
441 .map_err(|mut error| {
442 error.push(STRUCT_NAME, "parent");
443 error
444 })
445 }
446 3u32 => {
447 let value = &mut self.status;
448 encoding::int32::merge(wire_type, value, buf, ctx).map_err(|mut error| {
449 error.push(STRUCT_NAME, "status");
450 error
451 })
452 }
453 4u32 => {
454 check_wire_type(WireType::LengthDelimited, wire_type)?;
455 let len = decode_varint(buf)? as usize;
456 if len > buf.remaining() {
457 return Err(decode_error(
458 "buffer underflow",
459 &[(STRUCT_NAME, "dead_error")],
460 ));
461 }
462
463 let start = buf_len - buf.remaining();
464 buf.advance(len);
465 let end = buf_len - buf.remaining();
466 self.dead_error = Some(Range { start, end });
467 Ok(())
468 }
469 _ => encoding::skip_field(wire_type, tag, buf, ctx),
470 }
471 }
472}
473
474#[derive(Debug, Default)]
475pub struct UpdateOneofLimitedDecodeTransaction {
476 pub transaction: Option<Range<usize>>,
477 pub slot: Slot,
478}
479
480impl LimitedDecode for UpdateOneofLimitedDecodeTransaction {
481 fn merge_field(
482 &mut self,
483 tag: u32,
484 wire_type: WireType,
485 buf: &mut impl Buf,
486 buf_len: usize,
487 ) -> Result<(), DecodeError> {
488 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeTransaction";
489 let ctx = DecodeContext::default();
490 match tag {
491 1u32 => {
492 check_wire_type(WireType::LengthDelimited, wire_type)?;
493 let len = decode_varint(buf)? as usize;
494 if len > buf.remaining() {
495 return Err(decode_error(
496 "buffer underflow",
497 &[(STRUCT_NAME, "transaction")],
498 ));
499 }
500
501 let start = buf_len - buf.remaining();
502 buf.advance(len);
503 let end = buf_len - buf.remaining();
504 self.transaction = Some(Range { start, end });
505 Ok(())
506 }
507 2u32 => {
508 let value = &mut self.slot;
509 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
510 error.push(STRUCT_NAME, "slot");
511 error
512 })
513 }
514 _ => encoding::skip_field(wire_type, tag, buf, ctx),
515 }
516 }
517}
518
519#[derive(Debug, Default)]
520pub struct UpdateOneofLimitedDecodeTransactionInfo {
521 pub signature_offset: Option<usize>,
522 pub is_vote: bool,
523 pub index: u64,
524 pub account_keys: HashSet<Pubkey>,
525 pub err: Option<Range<usize>>,
526}
527
528impl LimitedDecode for UpdateOneofLimitedDecodeTransactionInfo {
529 fn merge_field(
530 &mut self,
531 tag: u32,
532 wire_type: WireType,
533 buf: &mut impl Buf,
534 buf_len: usize,
535 ) -> Result<(), DecodeError> {
536 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeTransactionInfo";
537 let ctx = DecodeContext::default();
538 match tag {
539 1u32 => {
540 check_wire_type(WireType::LengthDelimited, wire_type)?;
542 let len = decode_varint(buf)? as usize;
543 if len > buf.remaining() {
544 return Err(decode_error(
545 "buffer underflow",
546 &[(STRUCT_NAME, "signature")],
547 ));
548 }
549 if len != SIGNATURE_BYTES {
550 return Err(decode_error(
551 "invalid signature length",
552 &[(STRUCT_NAME, "signature")],
553 ));
554 }
555 self.signature_offset = Some(buf_len - buf.remaining());
556 buf.advance(len);
557 Ok(())
558 }
559 2u32 => {
560 let value = &mut self.is_vote;
562 encoding::bool::merge(wire_type, value, buf, ctx).map_err(|mut error| {
563 error.push(STRUCT_NAME, "is_vote");
564 error
565 })
566 }
567 3u32 => {
568 check_wire_type(WireType::LengthDelimited, wire_type)?;
570 self.merge_transaction(buf, buf_len).map_err(|mut error| {
571 error.push(STRUCT_NAME, "transaction");
572 error
573 })
574 }
575 4u32 => {
576 check_wire_type(WireType::LengthDelimited, wire_type)?;
578 self.merge_meta(buf, buf_len).map_err(|mut error| {
579 error.push(STRUCT_NAME, "meta");
580 error
581 })
582 }
583 5u32 => {
584 let value = &mut self.index;
586 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
587 error.push(STRUCT_NAME, "index");
588 error
589 })
590 }
591 _ => encoding::skip_field(wire_type, tag, buf, ctx),
592 }
593 }
594}
595
596impl UpdateOneofLimitedDecodeTransactionInfo {
597 fn merge_transaction(&mut self, buf: &mut impl Buf, buf_len: usize) -> Result<(), DecodeError> {
598 let len = decode_varint(buf)?;
599 let remaining = buf.remaining();
600 if len > remaining as u64 {
601 return Err(create_decode_error("buffer underflow"));
602 }
603
604 let limit = remaining - len as usize;
605 while buf.remaining() > limit {
606 let (tag, wire_type) = decode_key(buf)?;
607 if tag == 2 {
609 check_wire_type(WireType::LengthDelimited, wire_type)?;
610 self.merge_transaction_message(buf, buf_len)?;
611 } else {
612 encoding::skip_field(wire_type, tag, buf, DecodeContext::default())?;
613 }
614 }
615 Ok(())
616 }
617
618 fn merge_transaction_message(
619 &mut self,
620 buf: &mut impl Buf,
621 _buf_len: usize,
622 ) -> Result<(), DecodeError> {
623 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeTransactionInfo";
624 let len = decode_varint(buf)?;
625 let remaining = buf.remaining();
626 if len > remaining as u64 {
627 return Err(create_decode_error("buffer underflow"));
628 }
629
630 let limit = remaining - len as usize;
631 while buf.remaining() > limit {
632 let (tag, wire_type) = decode_key(buf)?;
633 if tag == 2 {
635 self.account_keys.insert(decode_pubkey(
636 buf,
637 wire_type,
638 STRUCT_NAME,
639 "account_keys",
640 )?);
641 } else {
642 encoding::skip_field(wire_type, tag, buf, DecodeContext::default())?;
643 }
644 }
645 Ok(())
646 }
647
648 fn merge_meta(&mut self, buf: &mut impl Buf, buf_len: usize) -> Result<(), DecodeError> {
649 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeTransactionInfo";
650 let len = decode_varint(buf)?;
651 let remaining = buf.remaining();
652 if len > remaining as u64 {
653 return Err(create_decode_error("buffer underflow"));
654 }
655
656 let limit = remaining - len as usize;
657 while buf.remaining() > limit {
658 let (tag, wire_type) = decode_key(buf)?;
659 match tag {
660 1u32 => {
661 check_wire_type(WireType::LengthDelimited, wire_type)?;
663 let len = decode_varint(buf)? as usize;
664 if len > buf.remaining() {
665 return Err(create_decode_error("buffer underflow"));
666 }
667 let start = buf_len - buf.remaining();
668 buf.advance(len);
669 let end = buf_len - buf.remaining();
670 self.err = Some(Range { start, end });
671 }
672 12u32 => {
673 self.account_keys.insert(decode_pubkey(
675 buf,
676 wire_type,
677 STRUCT_NAME,
678 "loaded_writable_addresses",
679 )?);
680 }
681 13u32 => {
682 self.account_keys.insert(decode_pubkey(
684 buf,
685 wire_type,
686 STRUCT_NAME,
687 "loaded_readonly_addresses",
688 )?);
689 }
690 _ => {
691 encoding::skip_field(wire_type, tag, buf, DecodeContext::default())?;
692 }
693 }
694 }
695 Ok(())
696 }
697}
698
699#[derive(Debug, Default)]
700pub struct UpdateOneofLimitedDecodeEntry {
701 pub slot: Slot,
702 pub index: u64,
703 pub executed_transaction_count: u64,
704}
705
706impl LimitedDecode for UpdateOneofLimitedDecodeEntry {
707 fn merge_field(
708 &mut self,
709 tag: u32,
710 wire_type: WireType,
711 buf: &mut impl Buf,
712 _buf_len: usize,
713 ) -> Result<(), DecodeError> {
714 const STRUCT_NAME: &str = "UpdateOneofLimitedDecodeEntry";
715 let ctx = DecodeContext::default();
716 match tag {
717 1u32 => {
718 let value = &mut self.slot;
719 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
720 error.push(STRUCT_NAME, "slot");
721 error
722 })
723 }
724 2u32 => {
725 let value = &mut self.index;
726 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
727 error.push(STRUCT_NAME, "index");
728 error
729 })
730 }
731 3u32 => encoding::uint64::merge(wire_type, &mut 0, buf, ctx).map_err(|mut error| {
732 error.push(STRUCT_NAME, "num_hashes");
733 error
734 }),
735 4u32 => {
736 check_wire_type(WireType::LengthDelimited, wire_type)?;
737 let len = decode_varint(buf)? as usize;
738 if len > buf.remaining() {
739 Err(create_decode_error("buffer underflow"))
740 } else {
741 buf.advance(len);
742 Ok(())
743 }
744 }
745 .map_err(|mut error| {
746 error.push(STRUCT_NAME, "hash");
747 error
748 }),
749 5u32 => {
750 let value = &mut self.executed_transaction_count;
751 encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
752 error.push(STRUCT_NAME, "executed_transaction_count");
753 error
754 })
755 }
756 6u32 => encoding::uint64::merge(wire_type, &mut 0, buf, ctx).map_err(|mut error| {
757 error.push(STRUCT_NAME, "starting_transaction_index");
758 error
759 }),
760 _ => encoding::skip_field(wire_type, tag, buf, ctx),
761 }
762 }
763}