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> {
258 loop {
259 let info = self.sub.next().await?;
260 let block = BlockEventsQuery::new(self.sub.client_ref().clone(), info.hash);
261 let events = match block.raw(self.opts.clone()).await {
262 Ok(x) => x,
263 Err(err) => {
264 self.sub.set_block_height(info.height);
266 return Err(err);
267 },
268 };
269
270 if events.is_empty() {
271 continue;
272 }
273
274 return Ok(BlockEventsSubValue {
275 list: events,
276 block_height: info.height,
277 block_hash: info.hash,
278 });
279 }
280 }
281
282 pub fn set_options(&mut self, value: avail_rust_core::rpc::EventOpts) {
287 self.opts = value;
288 }
289
290 pub fn should_retry_on_error(&self) -> bool {
292 self.sub.should_retry_on_error()
293 }
294
295 pub fn use_best_block(&mut self, value: bool) {
297 self.sub.use_best_block(value);
298 }
299
300 pub fn set_block_height(&mut self, block_height: u32) {
302 self.sub.set_block_height(block_height);
303 }
304
305 pub fn set_pool_rate(&mut self, value: Duration) {
307 self.sub.set_pool_rate(value);
308 }
309
310 pub fn set_retry_on_error(&mut self, value: Option<bool>) {
312 self.sub.set_retry_on_error(value);
313 }
314}
315
316#[derive(Clone)]
318pub struct BlockHeaderSub {
319 sub: Sub,
320}
321
322impl BlockHeaderSub {
323 pub fn new(client: Client) -> Self {
335 Self { sub: Sub::new(client) }
336 }
337
338 pub async fn next(&mut self) -> Result<Option<AvailHeader>, crate::Error> {
342 let info = self.sub.next().await?;
343 let header = match self
344 .sub
345 .client_ref()
346 .chain()
347 .retry_on(Some(self.sub.should_retry_on_error()), Some(true))
348 .block_header(Some(info.hash))
349 .await
350 {
351 Ok(x) => x,
352 Err(err) => {
353 self.sub.set_block_height(info.height);
355 return Err(err);
356 },
357 };
358
359 Ok(header)
360 }
361
362 pub async fn prev(&mut self) -> Result<Option<AvailHeader>, crate::Error> {
366 let info = self.sub.prev().await?;
367 let header = match self
368 .sub
369 .client_ref()
370 .chain()
371 .retry_on(Some(self.sub.should_retry_on_error()), Some(true))
372 .block_header(Some(info.hash))
373 .await
374 {
375 Ok(x) => x,
376 Err(err) => {
377 self.sub.set_block_height(info.height);
379 return Err(err);
380 },
381 };
382
383 Ok(header)
384 }
385
386 pub fn should_retry_on_error(&self) -> bool {
388 self.sub.should_retry_on_error()
389 }
390
391 pub fn use_best_block(&mut self, value: bool) {
393 self.sub.use_best_block(value);
394 }
395
396 pub fn set_block_height(&mut self, block_height: u32) {
398 self.sub.set_block_height(block_height);
399 }
400
401 pub fn set_pool_rate(&mut self, value: Duration) {
403 self.sub.set_pool_rate(value);
404 }
405
406 pub fn set_retry_on_error(&mut self, value: Option<bool>) {
408 self.sub.set_retry_on_error(value);
409 }
410}
411
412#[cfg(test)]
413mod tests {
414 use super::*;
415 use crate::{clients::mock_client::MockClient, error::Error, prelude::*, subxt_rpcs::RpcClient};
416
417 #[tokio::test]
419 async fn block_sub_test() -> Result<(), Error> {
420 let client = Client::new(TURING_ENDPOINT).await?;
421
422 let mut sub = BlockSub::new(client.clone());
426
427 let block_height = client.finalized().block_height().await?;
428 let value = sub.next().await?;
429 assert_eq!(value.block_height, block_height);
430
431 let mut sub = BlockSub::new(client.clone());
435
436 let block_height = client.finalized().block_height().await?;
437 let value = sub.prev().await?;
438 assert_eq!(value.block_height, block_height - 1);
439
440 let block_height = 1900000u32;
444 let mut sub = BlockSub::new(client.clone());
445 sub.set_block_height(block_height);
446 for i in 0..3 {
447 let value = sub.next().await?;
448 assert_eq!(value.block_height, block_height + i);
449 }
450
451 let block_height = 1900000u32;
455 let mut sub = BlockSub::new(client.clone());
456 sub.set_block_height(block_height);
457 for i in 0..3 {
458 let value = sub.prev().await?;
459 assert_eq!(value.block_height, block_height - i - 1);
460 }
461
462 let block_height = 1900000u32;
466 let mut sub = BlockSub::new(client.clone());
467 sub.set_block_height(block_height);
468
469 let value = sub.next().await?;
470 assert_eq!(value.block_height, block_height);
471
472 let value = sub.prev().await?;
473 assert_eq!(value.block_height, block_height - 1);
474
475 let block_height = 1900000u32;
479 let mut sub = BlockSub::new(client.clone());
480 sub.set_block_height(block_height);
481
482 let value = sub.prev().await?;
483 assert_eq!(value.block_height, block_height - 1);
484
485 let value = sub.next().await?;
486 assert_eq!(value.block_height, block_height);
487
488 Ok(())
489 }
490
491 #[tokio::test]
493 async fn header_sub_test() -> Result<(), Error> {
494 let (rpc_client, mut commander) = MockClient::new(TURING_ENDPOINT);
495 let client = Client::from_rpc_client(RpcClient::new(rpc_client)).await?;
496
497 let mut sub = BlockHeaderSub::new(client.clone());
501
502 let block_height = client.finalized().block_height().await?;
503 let value = sub.next().await?.expect("Should be there");
504 assert_eq!(value.number, block_height);
505
506 let mut sub = BlockHeaderSub::new(client.clone());
510
511 let block_height = client.finalized().block_height().await?;
512 let value = sub.prev().await?.expect("Should be there");
513 assert_eq!(value.number, block_height - 1);
514
515 let block_height = 1900000u32;
519 let mut sub = BlockHeaderSub::new(client.clone());
520 sub.set_block_height(block_height);
521 for i in 0..3 {
522 let value = sub.next().await?.expect("Should be there");
523 assert_eq!(value.number, block_height + i);
524 }
525
526 let block_height = 1900000u32;
530 let mut sub = BlockHeaderSub::new(client.clone());
531 sub.set_block_height(block_height);
532 for i in 0..3 {
533 let value = sub.prev().await?.expect("Should be there");
534 assert_eq!(value.number, block_height - i - 1);
535 }
536
537 let block_height = 1900000u32;
541 let mut sub = BlockHeaderSub::new(client.clone());
542 sub.set_block_height(block_height);
543
544 let value = sub.next().await?.expect("Should be there");
545 assert_eq!(value.number, block_height);
546
547 let value = sub.prev().await?.expect("Should be there");
548 assert_eq!(value.number, block_height - 1);
549
550 let block_height = 1900000u32;
554 let mut sub = BlockHeaderSub::new(client.clone());
555 sub.set_block_height(block_height);
556
557 let value = sub.prev().await?.expect("Should be there");
558 assert_eq!(value.number, block_height - 1);
559
560 let value = sub.next().await?.expect("Should be there");
561 assert_eq!(value.number, block_height);
562
563 let block_height = 1900000u32;
567 let mut sub = BlockHeaderSub::new(client.clone());
568 sub.set_retry_on_error(Some(false));
569 sub.set_block_height(block_height);
570
571 let value = sub.next().await?.expect("Should be there");
572 assert_eq!(value.number, block_height);
573 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
574
575 commander.block_header_err(None);
576 let _ = sub.next().await.expect_err("Should fail");
577 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
578
579 let value = sub.next().await?.expect("Should be there");
580 assert_eq!(value.number, block_height + 1);
581 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 2);
582
583 Ok(())
584 }
585
586 #[tokio::test]
588 async fn legacy_block_sub_test() -> Result<(), Error> {
589 let (rpc_client, mut commander) = MockClient::new(TURING_ENDPOINT);
590 let client = Client::from_rpc_client(RpcClient::new(rpc_client)).await?;
591
592 let mut sub = LegacyBlockSub::new(client.clone());
596
597 let block_height = client.finalized().block_height().await?;
598 let value = sub.next().await?.expect("Should be there");
599 assert_eq!(value.block.header.number, block_height);
600
601 let mut sub = LegacyBlockSub::new(client.clone());
605
606 let block_height = client.finalized().block_height().await?;
607 let value = sub.prev().await?.expect("Should be there");
608 assert_eq!(value.block.header.number, block_height - 1);
609
610 let block_height = 1900000u32;
614 let mut sub = LegacyBlockSub::new(client.clone());
615 sub.set_block_height(block_height);
616 for i in 0..3 {
617 let value = sub.next().await?.expect("Should be there");
618 assert_eq!(value.block.header.number, block_height + i);
619 }
620
621 let block_height = 1900000u32;
625 let mut sub = LegacyBlockSub::new(client.clone());
626 sub.set_block_height(block_height);
627 for i in 0..3 {
628 let value = sub.prev().await?.expect("Should be there");
629 assert_eq!(value.block.header.number, block_height - i - 1);
630 }
631
632 let block_height = 1900000u32;
636 let mut sub = LegacyBlockSub::new(client.clone());
637 sub.set_block_height(block_height);
638
639 let value = sub.next().await?.expect("Should be there");
640 assert_eq!(value.block.header.number, block_height);
641
642 let value = sub.prev().await?.expect("Should be there");
643 assert_eq!(value.block.header.number, block_height - 1);
644
645 let block_height = 1900000u32;
649 let mut sub = LegacyBlockSub::new(client.clone());
650 sub.set_block_height(block_height);
651
652 let value = sub.prev().await?.expect("Should be there");
653 assert_eq!(value.block.header.number, block_height - 1);
654
655 let value = sub.next().await?.expect("Should be there");
656 assert_eq!(value.block.header.number, block_height);
657
658 let block_height = 1900000u32;
662 let mut sub = LegacyBlockSub::new(client.clone());
663 sub.set_retry_on_error(Some(false));
664 sub.set_block_height(block_height);
665
666 let value = sub.next().await?.expect("Should be there");
667 assert_eq!(value.block.header.number, block_height);
668 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
669
670 commander.legacy_block_err(None);
671 let _ = sub.next().await.expect_err("Should fail");
672 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 1);
673
674 let value = sub.next().await?.expect("Should be there");
675 assert_eq!(value.block.header.number, block_height + 1);
676 assert_eq!(sub.sub.as_finalized().next_block_height, block_height + 2);
677
678 Ok(())
679 }
680}