avail_rust_client/subscription/
block.rs1use crate::{
4 AvailHeader, Client, LegacyBlock, RpcError, Sub,
5 block::{Block, events::BlockEventsQuery},
6};
7use avail_rust_core::{H256, rpc::BlockPhaseEvent};
8use std::time::Duration;
9
10#[derive(Clone)]
12pub struct LegacyBlockSub {
13 sub: Sub,
14}
15
16impl LegacyBlockSub {
17 pub fn new(client: Client) -> Self {
28 Self { sub: Sub::new(client) }
29 }
30
31 pub async fn next(&mut self) -> Result<Option<LegacyBlock>, RpcError> {
42 let info = self.sub.next().await?;
43 let block = match self
44 .sub
45 .client_ref()
46 .chain()
47 .retry_on(Some(self.sub.should_retry_on_error()), Some(true))
48 .legacy_block(Some(info.hash))
49 .await
50 {
51 Ok(x) => x,
52 Err(err) => {
53 self.sub.set_block_height(info.height);
55 return Err(err);
56 },
57 };
58 Ok(block)
59 }
60
61 pub async fn prev(&mut self) -> Result<Option<LegacyBlock>, RpcError> {
73 let info = self.sub.prev().await?;
74 let block = match self
75 .sub
76 .client_ref()
77 .chain()
78 .retry_on(Some(self.sub.should_retry_on_error()), Some(true))
79 .legacy_block(Some(info.hash))
80 .await
81 {
82 Ok(x) => x,
83 Err(err) => {
84 self.sub.set_block_height(info.height);
86 return Err(err);
87 },
88 };
89 Ok(block)
90 }
91
92 pub fn should_retry_on_error(&self) -> bool {
97 self.sub.should_retry_on_error()
98 }
99
100 pub fn use_best_block(&mut self, value: bool) {
105 self.sub.use_best_block(value);
106 }
107
108 pub fn set_block_height(&mut self, block_height: u32) {
113 self.sub.set_block_height(block_height);
114 }
115
116 pub fn set_pool_rate(&mut self, value: Duration) {
121 self.sub.set_pool_rate(value);
122 }
123
124 pub fn set_retry_on_error(&mut self, value: Option<bool>) {
130 self.sub.set_retry_on_error(value);
131 }
132}
133
134#[derive(Clone)]
135pub struct BlockSubValue {
136 pub value: Block,
137 pub block_height: u32,
138 pub block_hash: H256,
139}
140
141#[derive(Clone)]
143pub struct BlockSub {
144 sub: Sub,
145}
146
147impl BlockSub {
148 pub fn new(client: Client) -> Self {
157 Self { sub: Sub::new(client) }
158 }
159
160 pub async fn next(&mut self) -> Result<BlockSubValue, RpcError> {
169 let info = self.sub.next().await?;
170 let value = Block::new(self.sub.client_ref().clone(), info.hash);
171 Ok(BlockSubValue { value, block_hash: info.hash, block_height: info.height })
172 }
173
174 pub async fn prev(&mut self) -> Result<BlockSubValue, RpcError> {
184 let info = self.sub.prev().await?;
185 let value = Block::new(self.sub.client_ref().clone(), info.hash);
186 Ok(BlockSubValue { value, block_hash: info.hash, block_height: info.height })
187 }
188
189 pub fn should_retry_on_error(&self) -> bool {
191 self.sub.should_retry_on_error()
192 }
193
194 pub fn use_best_block(&mut self, value: bool) {
199 self.sub.use_best_block(value);
200 }
201
202 pub fn set_block_height(&mut self, block_height: u32) {
207 self.sub.set_block_height(block_height);
208 }
209
210 pub fn set_pool_rate(&mut self, value: Duration) {
215 self.sub.set_pool_rate(value);
216 }
217
218 pub fn set_retry_on_error(&mut self, value: Option<bool>) {
224 self.sub.set_retry_on_error(value);
225 }
226}
227
228#[derive(Debug, Clone)]
229pub struct BlockEventsSubValue {
230 pub list: Vec<BlockPhaseEvent>,
231 pub block_height: u32,
232 pub block_hash: H256,
233}
234
235#[derive(Clone)]
237pub struct BlockEventsSub {
238 sub: Sub,
239 opts: avail_rust_core::rpc::EventOpts,
240}
241
242impl BlockEventsSub {
243 pub fn new(client: Client, opts: avail_rust_core::rpc::EventOpts) -> Self {
246 Self { sub: Sub::new(client), opts }
247 }
248
249 pub async fn next(&mut self) -> Result<BlockEventsSubValue, crate::Error> {
268 loop {
269 let events = self.next_step().await?;
270 if events.list.is_empty() {
271 continue;
272 }
273 return Ok(events);
274 }
275 }
276
277 pub async fn next_step(&mut self) -> Result<BlockEventsSubValue, crate::Error> {
290 let info = self.sub.next().await?;
291 let block = BlockEventsQuery::new(self.sub.client_ref().clone(), info.hash);
292 let events = match block.raw(self.opts.clone()).await {
293 Ok(x) => x,
294 Err(err) => {
295 self.sub.set_block_height(info.height);
297 return Err(err);
298 },
299 };
300
301 return Ok(BlockEventsSubValue {
302 list: events,
303 block_height: info.height,
304 block_hash: info.hash,
305 });
306 }
307
308 pub fn set_options(&mut self, value: avail_rust_core::rpc::EventOpts) {
313 self.opts = value;
314 }
315
316 pub fn should_retry_on_error(&self) -> bool {
318 self.sub.should_retry_on_error()
319 }
320
321 pub fn use_best_block(&mut self, value: bool) {
323 self.sub.use_best_block(value);
324 }
325
326 pub fn set_block_height(&mut self, block_height: u32) {
328 self.sub.set_block_height(block_height);
329 }
330
331 pub fn set_pool_rate(&mut self, value: Duration) {
333 self.sub.set_pool_rate(value);
334 }
335
336 pub fn set_retry_on_error(&mut self, value: Option<bool>) {
338 self.sub.set_retry_on_error(value);
339 }
340}
341
342#[derive(Clone)]
344pub struct BlockHeaderSub {
345 sub: Sub,
346}
347
348impl BlockHeaderSub {
349 pub fn new(client: Client) -> Self {
361 Self { sub: Sub::new(client) }
362 }
363
364 pub async fn next(&mut self) -> Result<Option<AvailHeader>, crate::Error> {
368 let info = self.sub.next().await?;
369 let header = match self
370 .sub
371 .client_ref()
372 .chain()
373 .retry_on(Some(self.sub.should_retry_on_error()), Some(true))
374 .block_header(Some(info.hash))
375 .await
376 {
377 Ok(x) => x,
378 Err(err) => {
379 self.sub.set_block_height(info.height);
381 return Err(err);
382 },
383 };
384
385 Ok(header)
386 }
387
388 pub async fn prev(&mut self) -> Result<Option<AvailHeader>, crate::Error> {
392 let info = self.sub.prev().await?;
393 let header = match self
394 .sub
395 .client_ref()
396 .chain()
397 .retry_on(Some(self.sub.should_retry_on_error()), Some(true))
398 .block_header(Some(info.hash))
399 .await
400 {
401 Ok(x) => x,
402 Err(err) => {
403 self.sub.set_block_height(info.height);
405 return Err(err);
406 },
407 };
408
409 Ok(header)
410 }
411
412 pub fn should_retry_on_error(&self) -> bool {
414 self.sub.should_retry_on_error()
415 }
416
417 pub fn use_best_block(&mut self, value: bool) {
419 self.sub.use_best_block(value);
420 }
421
422 pub fn set_block_height(&mut self, block_height: u32) {
424 self.sub.set_block_height(block_height);
425 }
426
427 pub fn set_pool_rate(&mut self, value: Duration) {
429 self.sub.set_pool_rate(value);
430 }
431
432 pub fn set_retry_on_error(&mut self, value: Option<bool>) {
434 self.sub.set_retry_on_error(value);
435 }
436}
437
438#[cfg(test)]
439mod tests {
440 use super::*;
441 use crate::{clients::mock_client::MockClient, error::Error, prelude::*, subxt_rpcs::RpcClient};
442
443 #[tokio::test]
445 async fn block_sub_test() -> Result<(), Error> {
446 let client = Client::new(TURING_ENDPOINT).await?;
447
448 let mut sub = BlockSub::new(client.clone());
452
453 let block_height = client.finalized().block_height().await?;
454 let value = sub.next().await?;
455 assert_eq!(value.block_height, block_height);
456
457 let mut sub = BlockSub::new(client.clone());
461
462 let block_height = client.finalized().block_height().await?;
463 let value = sub.prev().await?;
464 assert_eq!(value.block_height, block_height - 1);
465
466 let block_height = 1900000u32;
470 let mut sub = BlockSub::new(client.clone());
471 sub.set_block_height(block_height);
472 for i in 0..3 {
473 let value = sub.next().await?;
474 assert_eq!(value.block_height, block_height + i);
475 }
476
477 let block_height = 1900000u32;
481 let mut sub = BlockSub::new(client.clone());
482 sub.set_block_height(block_height);
483 for i in 0..3 {
484 let value = sub.prev().await?;
485 assert_eq!(value.block_height, block_height - i - 1);
486 }
487
488 let block_height = 1900000u32;
492 let mut sub = BlockSub::new(client.clone());
493 sub.set_block_height(block_height);
494
495 let value = sub.next().await?;
496 assert_eq!(value.block_height, block_height);
497
498 let value = sub.prev().await?;
499 assert_eq!(value.block_height, block_height - 1);
500
501 let block_height = 1900000u32;
505 let mut sub = BlockSub::new(client.clone());
506 sub.set_block_height(block_height);
507
508 let value = sub.prev().await?;
509 assert_eq!(value.block_height, block_height - 1);
510
511 let value = sub.next().await?;
512 assert_eq!(value.block_height, block_height);
513
514 Ok(())
515 }
516
517 #[tokio::test]
519 async fn header_sub_test() -> Result<(), Error> {
520 let (rpc_client, mut commander) = MockClient::new(TURING_ENDPOINT);
521 let client = Client::from_rpc_client(RpcClient::new(rpc_client)).await?;
522
523 let mut sub = BlockHeaderSub::new(client.clone());
527
528 let block_height = client.finalized().block_height().await?;
529 let value = sub.next().await?.expect("Should be there");
530 assert_eq!(value.number, block_height);
531
532 let mut sub = BlockHeaderSub::new(client.clone());
536
537 let block_height = client.finalized().block_height().await?;
538 let value = sub.prev().await?.expect("Should be there");
539 assert_eq!(value.number, block_height - 1);
540
541 let block_height = 1900000u32;
545 let mut sub = BlockHeaderSub::new(client.clone());
546 sub.set_block_height(block_height);
547 for i in 0..3 {
548 let value = sub.next().await?.expect("Should be there");
549 assert_eq!(value.number, block_height + i);
550 }
551
552 let block_height = 1900000u32;
556 let mut sub = BlockHeaderSub::new(client.clone());
557 sub.set_block_height(block_height);
558 for i in 0..3 {
559 let value = sub.prev().await?.expect("Should be there");
560 assert_eq!(value.number, block_height - i - 1);
561 }
562
563 let block_height = 1900000u32;
567 let mut sub = BlockHeaderSub::new(client.clone());
568 sub.set_block_height(block_height);
569
570 let value = sub.next().await?.expect("Should be there");
571 assert_eq!(value.number, block_height);
572
573 let value = sub.prev().await?.expect("Should be there");
574 assert_eq!(value.number, block_height - 1);
575
576 let block_height = 1900000u32;
580 let mut sub = BlockHeaderSub::new(client.clone());
581 sub.set_block_height(block_height);
582
583 let value = sub.prev().await?.expect("Should be there");
584 assert_eq!(value.number, block_height - 1);
585
586 let value = sub.next().await?.expect("Should be there");
587 assert_eq!(value.number, block_height);
588
589 let block_height = 1900000u32;
593 let mut sub = BlockHeaderSub::new(client.clone());
594 sub.set_retry_on_error(Some(false));
595 sub.set_block_height(block_height);
596
597 let value = sub.next().await?.expect("Should be there");
598 assert_eq!(value.number, block_height);
599 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
600
601 commander.block_header_err(None);
602 let _ = sub.next().await.expect_err("Should fail");
603 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
604
605 let value = sub.next().await?.expect("Should be there");
606 assert_eq!(value.number, block_height + 1);
607 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 2);
608
609 Ok(())
610 }
611
612 #[tokio::test]
614 async fn legacy_block_sub_test() -> Result<(), Error> {
615 let (rpc_client, mut commander) = MockClient::new(TURING_ENDPOINT);
616 let client = Client::from_rpc_client(RpcClient::new(rpc_client)).await?;
617
618 let mut sub = LegacyBlockSub::new(client.clone());
622
623 let block_height = client.finalized().block_height().await?;
624 let value = sub.next().await?.expect("Should be there");
625 assert_eq!(value.block.header.number, block_height);
626
627 let mut sub = LegacyBlockSub::new(client.clone());
631
632 let block_height = client.finalized().block_height().await?;
633 let value = sub.prev().await?.expect("Should be there");
634 assert_eq!(value.block.header.number, block_height - 1);
635
636 let block_height = 1900000u32;
640 let mut sub = LegacyBlockSub::new(client.clone());
641 sub.set_block_height(block_height);
642 for i in 0..3 {
643 let value = sub.next().await?.expect("Should be there");
644 assert_eq!(value.block.header.number, block_height + i);
645 }
646
647 let block_height = 1900000u32;
651 let mut sub = LegacyBlockSub::new(client.clone());
652 sub.set_block_height(block_height);
653 for i in 0..3 {
654 let value = sub.prev().await?.expect("Should be there");
655 assert_eq!(value.block.header.number, block_height - i - 1);
656 }
657
658 let block_height = 1900000u32;
662 let mut sub = LegacyBlockSub::new(client.clone());
663 sub.set_block_height(block_height);
664
665 let value = sub.next().await?.expect("Should be there");
666 assert_eq!(value.block.header.number, block_height);
667
668 let value = sub.prev().await?.expect("Should be there");
669 assert_eq!(value.block.header.number, block_height - 1);
670
671 let block_height = 1900000u32;
675 let mut sub = LegacyBlockSub::new(client.clone());
676 sub.set_block_height(block_height);
677
678 let value = sub.prev().await?.expect("Should be there");
679 assert_eq!(value.block.header.number, block_height - 1);
680
681 let value = sub.next().await?.expect("Should be there");
682 assert_eq!(value.block.header.number, block_height);
683
684 let block_height = 1900000u32;
688 let mut sub = LegacyBlockSub::new(client.clone());
689 sub.set_retry_on_error(Some(false));
690 sub.set_block_height(block_height);
691
692 let value = sub.next().await?.expect("Should be there");
693 assert_eq!(value.block.header.number, block_height);
694 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
695
696 commander.legacy_block_err(None);
697 let _ = sub.next().await.expect_err("Should fail");
698 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
699
700 let value = sub.next().await?.expect("Should be there");
701 assert_eq!(value.block.header.number, block_height + 1);
702 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 2);
703
704 Ok(())
705 }
706}