forest/message_pool/msgpool/
reorg.rs1use crate::blocks::Tipset;
7use crate::message::{MessageRead as _, SignedMessage};
8use crate::message_pool::msgpool::utils;
9use crate::message_pool::{
10 Error,
11 msg_pool::{StrictnessPolicy, TrustPolicy},
12 msgpool::{msg_pool::MessagePool, recovered_bls_messages},
13 provider::Provider,
14};
15use crate::shim::address::Address;
16use crate::utils::ShallowClone as _;
17use ahash::{HashMap, HashMapExt};
18
19impl<T> MessagePool<T>
20where
21 T: Provider + Send + Sync + 'static,
22{
23 pub(in crate::message_pool) async fn apply_head_change(
34 &self,
35 revert: Vec<Tipset>,
36 apply: Vec<Tipset>,
37 ) -> Result<(), Error> {
38 let mut repub = false;
39 let mut rmsgs: HashMap<Address, HashMap<u64, SignedMessage>> = HashMap::new();
40 for ts in revert {
41 let Ok(pts) = self.api.load_tipset(ts.parents()) else {
42 tracing::error!("error loading reverted tipset parent");
43 continue;
44 };
45 *self.cur_tipset.write() = pts;
46
47 let mut msgs: Vec<SignedMessage> = Vec::new();
48 for block in ts.block_headers() {
49 let Ok((umsg, smsgs)) = self.api.messages_for_block(block) else {
50 tracing::error!("error retrieving messages for reverted block");
51 continue;
52 };
53 msgs.extend(smsgs);
54 msgs.extend(recovered_bls_messages(&self.caches.bls_sig, umsg));
55 }
56
57 for msg in msgs {
58 utils::add_to_selected_msgs(msg, &mut rmsgs);
59 }
60 }
61
62 for ts in apply {
63 for b in ts.block_headers() {
64 let Ok((msgs, smsgs)) = self.api.messages_for_block(b) else {
65 tracing::error!("error retrieving messages for block");
66 continue;
67 };
68
69 for msg in smsgs {
70 self.remove_applied_from_pool(&msg.from(), msg.sequence(), &mut rmsgs, &ts)
71 .await?;
72 if !repub && self.republish.was_republished(&msg.cid()) {
73 repub = true;
74 }
75 }
76 for msg in msgs {
77 self.remove_applied_from_pool(&msg.from, msg.sequence, &mut rmsgs, &ts)
78 .await?;
79 if !repub && self.republish.was_republished(&msg.cid()) {
80 repub = true;
81 }
82 }
83 }
84 *self.cur_tipset.write() = ts;
87 }
88 if repub {
89 self.republish.trigger()?;
90 }
91
92 let cur_ts = self.cur_tipset.read().shallow_clone();
93 for (_, hm) in rmsgs {
94 for (_, msg) in hm {
95 if let Err(e) = self
96 .add_to_pool_unchecked(
97 &cur_ts,
98 msg,
99 TrustPolicy::Trusted,
100 StrictnessPolicy::Relaxed,
101 )
102 .await
103 {
104 tracing::error!("Failed to read message from reorg to mpool: {}", e);
105 }
106 }
107 }
108 self.pending.shrink_to_fit();
109 Ok(())
110 }
111
112 async fn remove_applied_from_pool(
117 &self,
118 from: &Address,
119 sequence: u64,
120 rmsgs: &mut HashMap<Address, HashMap<u64, SignedMessage>>,
121 ts: &Tipset,
122 ) -> Result<(), Error> {
123 if rmsgs
124 .get_mut(from)
125 .and_then(|temp| temp.remove(&sequence))
126 .is_none()
127 && let Ok(resolved) = self
128 .resolve_to_key(from, ts)
129 .await
130 .inspect_err(|e| tracing::debug!(%from, "remove: failed to resolve address: {e:#}"))
131 {
132 let _ = self.pending.remove(&resolved, sequence, true);
133 }
134 Ok(())
135 }
136}