ckb_store/
data_loader_wrapper.rs

1//! TODO(doc): @quake
2use crate::ChainStore;
3use ckb_traits::{
4    CellDataProvider, EpochProvider, ExtensionProvider, HeaderFields, HeaderFieldsProvider,
5    HeaderProvider,
6};
7use ckb_types::{
8    bytes::Bytes,
9    core::{BlockExt, BlockNumber, EpochExt, HeaderView},
10    packed::{self, Byte32, OutPoint},
11};
12use std::sync::Arc;
13
14/// DataLoaderWrapper wrap`ChainStore`
15/// impl `HeaderProvider` `CellDataProvider` `EpochProvider`
16pub struct DataLoaderWrapper<T>(Arc<T>);
17
18// auto derive don't work
19impl<T> Clone for DataLoaderWrapper<T> {
20    fn clone(&self) -> Self {
21        DataLoaderWrapper(Arc::clone(&self.0))
22    }
23}
24
25/// Auto transform Arc wrapped `ChainStore` to `DataLoaderWrapper`
26pub trait AsDataLoader<T> {
27    /// Return arc cloned DataLoaderWrapper
28    fn as_data_loader(&self) -> DataLoaderWrapper<T>;
29}
30
31impl<T> AsDataLoader<T> for Arc<T>
32where
33    T: ChainStore,
34{
35    fn as_data_loader(&self) -> DataLoaderWrapper<T> {
36        DataLoaderWrapper(Arc::clone(self))
37    }
38}
39
40impl<T> CellDataProvider for DataLoaderWrapper<T>
41where
42    T: ChainStore,
43{
44    fn get_cell_data(&self, out_point: &OutPoint) -> Option<Bytes> {
45        ChainStore::get_cell_data(self.0.as_ref(), out_point).map(|(data, _)| data)
46    }
47
48    fn get_cell_data_hash(&self, out_point: &OutPoint) -> Option<Byte32> {
49        ChainStore::get_cell_data_hash(self.0.as_ref(), out_point)
50    }
51}
52
53impl<T> HeaderProvider for DataLoaderWrapper<T>
54where
55    T: ChainStore,
56{
57    fn get_header(&self, block_hash: &Byte32) -> Option<HeaderView> {
58        ChainStore::get_block_header(self.0.as_ref(), block_hash)
59    }
60}
61
62impl<T> HeaderFieldsProvider for DataLoaderWrapper<T>
63where
64    T: ChainStore,
65{
66    fn get_header_fields(&self, hash: &Byte32) -> Option<HeaderFields> {
67        self.0.get_block_header(hash).map(|header| HeaderFields {
68            number: header.number(),
69            epoch: header.epoch(),
70            parent_hash: header.data().raw().parent_hash(),
71            timestamp: header.timestamp(),
72            hash: header.hash(),
73        })
74    }
75}
76
77impl<T> EpochProvider for DataLoaderWrapper<T>
78where
79    T: ChainStore,
80{
81    fn get_epoch_ext(&self, header: &HeaderView) -> Option<EpochExt> {
82        ChainStore::get_block_epoch_index(self.0.as_ref(), &header.hash())
83            .and_then(|index| ChainStore::get_epoch_ext(self.0.as_ref(), &index))
84    }
85
86    fn get_block_hash(&self, number: BlockNumber) -> Option<Byte32> {
87        ChainStore::get_block_hash(self.0.as_ref(), number)
88    }
89
90    fn get_block_ext(&self, block_hash: &Byte32) -> Option<BlockExt> {
91        ChainStore::get_block_ext(self.0.as_ref(), block_hash)
92    }
93
94    fn get_block_header(&self, hash: &Byte32) -> Option<HeaderView> {
95        ChainStore::get_block_header(self.0.as_ref(), hash)
96    }
97}
98
99impl<T> ExtensionProvider for DataLoaderWrapper<T>
100where
101    T: ChainStore,
102{
103    fn get_block_extension(&self, hash: &Byte32) -> Option<packed::Bytes> {
104        ChainStore::get_block_extension(self.0.as_ref(), hash)
105    }
106}
107
108/// Borrowed DataLoaderWrapper with lifetime
109pub struct BorrowedDataLoaderWrapper<'a, T>(&'a T);
110impl<'a, T: ChainStore> BorrowedDataLoaderWrapper<'a, T> {
111    /// Construct new BorrowedDataLoaderWrapper
112    pub fn new(source: &'a T) -> Self {
113        BorrowedDataLoaderWrapper(source)
114    }
115}
116
117impl<'a, T: ChainStore> CellDataProvider for BorrowedDataLoaderWrapper<'a, T> {
118    fn get_cell_data(&self, out_point: &OutPoint) -> Option<Bytes> {
119        self.0.get_cell_data(out_point).map(|(data, _)| data)
120    }
121
122    fn get_cell_data_hash(&self, out_point: &OutPoint) -> Option<Byte32> {
123        self.0.get_cell_data_hash(out_point)
124    }
125}
126
127impl<'a, T: ChainStore> HeaderProvider for BorrowedDataLoaderWrapper<'a, T> {
128    fn get_header(&self, block_hash: &Byte32) -> Option<HeaderView> {
129        self.0.get_block_header(block_hash)
130    }
131}
132
133impl<'a, T: ChainStore> EpochProvider for BorrowedDataLoaderWrapper<'a, T> {
134    fn get_epoch_ext(&self, header: &HeaderView) -> Option<EpochExt> {
135        ChainStore::get_block_epoch_index(self.0, &header.hash())
136            .and_then(|index| ChainStore::get_epoch_ext(self.0, &index))
137    }
138
139    fn get_block_hash(&self, number: BlockNumber) -> Option<Byte32> {
140        ChainStore::get_block_hash(self.0, number)
141    }
142
143    fn get_block_ext(&self, block_hash: &Byte32) -> Option<BlockExt> {
144        ChainStore::get_block_ext(self.0, block_hash)
145    }
146
147    fn get_block_header(&self, hash: &Byte32) -> Option<HeaderView> {
148        ChainStore::get_block_header(self.0, hash)
149    }
150}
151
152impl<'a, T: ChainStore> ExtensionProvider for BorrowedDataLoaderWrapper<'a, T> {
153    fn get_block_extension(&self, hash: &Byte32) -> Option<packed::Bytes> {
154        ChainStore::get_block_extension(self.0, hash)
155    }
156}