forest/message_pool/msgpool/
provider.rs1use crate::blocks::{CachingBlockHeader, Tipset, TipsetKey};
5use crate::chain::{AtFinalityResolution, ChainStore, HeadChanges};
6use crate::message::{ChainMessage, SignedMessage};
7use crate::message_pool::errors::Error;
8use crate::message_pool::msg_pool::{
9 MAX_ACTOR_PENDING_MESSAGES, MAX_UNTRUSTED_ACTOR_PENDING_MESSAGES,
10};
11use crate::networks::Height;
12use crate::prelude::*;
13use crate::shim::{
14 address::Address,
15 econ::TokenAmount,
16 message::Message,
17 state_tree::{ActorState, StateTree},
18};
19use crate::utils::db::CborStoreExt;
20use auto_impl::auto_impl;
21
22#[auto_impl(Arc)]
26pub trait Provider {
27 fn subscribe_head_changes(&self) -> flume::Receiver<HeadChanges>;
29 fn get_heaviest_tipset(&self) -> Tipset;
31 fn put_message(&self, msg: &ChainMessage) -> Result<Cid, Error>;
34 fn get_actor_after(&self, addr: &Address, ts: &Tipset) -> Result<ActorState, Error>;
38 fn messages_for_block(
40 &self,
41 h: &CachingBlockHeader,
42 ) -> Result<(Vec<Message>, Vec<SignedMessage>), Error>;
43 fn load_tipset(&self, tsk: &TipsetKey) -> Result<Tipset, Error>;
45 fn chain_compute_base_fee(&self, ts: &Tipset) -> Result<TokenAmount, Error>;
47 fn resolve_to_deterministic_address_at_finality(
50 &self,
51 addr: &Address,
52 ts: &Tipset,
53 ) -> Result<Address, Error>;
54 fn messages_for_tipset(&self, ts: &Tipset) -> Result<Arc<Vec<ChainMessage>>, Error>;
56 fn max_actor_pending_messages(&self) -> u64 {
58 MAX_ACTOR_PENDING_MESSAGES
59 }
60 fn max_untrusted_actor_pending_messages(&self) -> u64 {
62 MAX_UNTRUSTED_ACTOR_PENDING_MESSAGES
63 }
64}
65
66impl Provider for ChainStore {
67 fn subscribe_head_changes(&self) -> flume::Receiver<HeadChanges> {
68 self.subscribe_head_changes()
69 }
70
71 fn get_heaviest_tipset(&self) -> Tipset {
72 self.heaviest_tipset()
73 }
74
75 fn put_message(&self, msg: &ChainMessage) -> Result<Cid, Error> {
76 let cid = self
77 .db()
78 .put_cbor_default(msg)
79 .map_err(|err| Error::Other(err.to_string()))?;
80 Ok(cid)
81 }
82
83 fn get_actor_after(&self, addr: &Address, ts: &Tipset) -> Result<ActorState, Error> {
84 let state = StateTree::new_from_root(self.db(), ts.parent_state())
85 .map_err(|e| Error::Other(e.to_string()))?;
86 Ok(state.get_required_actor(addr)?)
87 }
88
89 fn messages_for_block(
90 &self,
91 h: &CachingBlockHeader,
92 ) -> Result<(Vec<Message>, Vec<SignedMessage>), Error> {
93 crate::chain::block_messages(self.db(), h).map_err(|err| err.into())
94 }
95
96 fn load_tipset(&self, tsk: &TipsetKey) -> Result<Tipset, Error> {
97 Ok(self.chain_index().load_required_tipset(tsk)?)
98 }
99
100 fn chain_compute_base_fee(&self, ts: &Tipset) -> Result<TokenAmount, Error> {
101 let smoke_height = self.chain_config().epoch(Height::Smoke);
102 let firehorse_height = self.chain_config().epoch(Height::FireHorse);
103 crate::chain::compute_base_fee(self.db(), ts, smoke_height, firehorse_height)
104 .map_err(|err| err.into())
105 }
106
107 fn resolve_to_deterministic_address_at_finality(
108 &self,
109 addr: &Address,
110 ts: &Tipset,
111 ) -> Result<Address, Error> {
112 ChainStore::resolve_to_deterministic_address_at_finality(self, addr, ts)
113 .map(AtFinalityResolution::into_address)
114 .map_err(|e| Error::Other(e.to_string()))
115 }
116
117 fn messages_for_tipset(&self, ts: &Tipset) -> Result<Arc<Vec<ChainMessage>>, Error> {
118 ChainStore::messages_for_tipset(self, ts).map_err(Into::into)
119 }
120}
121
122pub trait ProviderExt {
123 async fn resolve_to_deterministic_address_at_finality_async(
125 &self,
126 addr: Address,
127 ts: Tipset,
128 ) -> Result<Address, Error>;
129}
130
131impl<T> ProviderExt for T
132where
133 T: Provider + ShallowClone + Send + Sync + 'static,
134{
135 async fn resolve_to_deterministic_address_at_finality_async(
136 &self,
137 addr: Address,
138 ts: Tipset,
139 ) -> Result<Address, Error> {
140 let this = self.shallow_clone();
141 tokio::task::spawn_blocking(move || {
142 this.resolve_to_deterministic_address_at_finality(&addr, &ts)
143 })
144 .await
145 .context("tokio join error")?
146 }
147}