saturn_mempool_oracle/
ops.rs1use borsh::{BorshDeserialize, BorshSerialize};
2use serde::{Deserialize, Serialize};
3
4use crate::{mempool_entry::MempoolEntry, txid::Txid};
5
6#[derive(Debug, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Clone)]
7pub enum UpdateMempoolEntriesInstruction {
8 InitializeProgram,
9 ResizeAccounts,
10 ModifyEntries(Vec<UpdateMempoolEntriesOp>),
11 GetEntries(Vec<[u8; 32]>),
12}
13
14#[derive(Debug, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Clone)]
15pub struct UpdateMempoolEntries(Vec<UpdateMempoolEntriesOp>);
16
17impl UpdateMempoolEntries {
18 pub fn new() -> Self {
19 Self(Vec::new())
20 }
21
22 pub fn get_entry(&self, index: usize) -> Option<&UpdateMempoolEntriesOp> {
23 self.0.get(index)
24 }
25
26 pub fn is_empty(&self) -> bool {
27 self.0.is_empty()
28 }
29
30 pub fn len(&self) -> usize {
31 self.0.len()
32 }
33
34 pub fn push(&mut self, op: UpdateMempoolEntriesOp) {
35 self.0.push(op);
36 }
37
38 pub fn iter(&self) -> impl Iterator<Item = &UpdateMempoolEntriesOp> {
39 self.0.iter()
40 }
41
42 pub fn into_iter(self) -> impl Iterator<Item = UpdateMempoolEntriesOp> {
43 self.0.into_iter()
44 }
45
46 pub fn split_by_size(
47 &self,
48 max_size: usize,
49 ) -> Result<Vec<UpdateMempoolEntries>, std::io::Error> {
50 let mut result = Vec::new();
51 let mut current = UpdateMempoolEntries::new();
52
53 for op in &self.0 {
54 current.push(op.clone());
56
57 let serialized = borsh::to_vec(¤t.0)?;
58
59 if serialized.len() > max_size {
61 current.0.pop();
63
64 if !current.0.is_empty() {
66 result.push(current);
67 current = UpdateMempoolEntries::new();
68
69 current.push(op.clone());
71 }
72 }
73 }
74
75 if !current.0.is_empty() {
77 result.push(current);
78 }
79
80 Ok(result)
81 }
82}
83
84impl Into<UpdateMempoolEntriesInstruction> for UpdateMempoolEntries {
85 fn into(self) -> UpdateMempoolEntriesInstruction {
86 UpdateMempoolEntriesInstruction::ModifyEntries(self.0)
87 }
88}
89
90impl Into<UpdateMempoolEntriesInstruction> for &UpdateMempoolEntries {
91 fn into(self) -> UpdateMempoolEntriesInstruction {
92 UpdateMempoolEntriesInstruction::ModifyEntries(self.0.clone())
93 }
94}
95
96impl FromIterator<UpdateMempoolEntriesOp> for UpdateMempoolEntries {
97 fn from_iter<I: IntoIterator<Item = UpdateMempoolEntriesOp>>(iter: I) -> Self {
98 Self(iter.into_iter().collect())
99 }
100}
101
102impl IntoIterator for UpdateMempoolEntries {
103 type Item = UpdateMempoolEntriesOp;
104 type IntoIter = std::vec::IntoIter<Self::Item>;
105
106 fn into_iter(self) -> Self::IntoIter {
107 self.0.into_iter()
108 }
109}
110
111impl<'a> IntoIterator for &'a UpdateMempoolEntries {
112 type Item = &'a UpdateMempoolEntriesOp;
113 type IntoIter = std::slice::Iter<'a, UpdateMempoolEntriesOp>;
114
115 fn into_iter(self) -> Self::IntoIter {
116 self.0.iter()
117 }
118}
119
120#[derive(
121 Debug, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Clone, PartialEq, Eq, Hash,
122)]
123#[serde(tag = "operation", content = "data")]
124pub enum UpdateMempoolEntriesOp {
125 #[serde(rename = "add_entry")]
126 #[serde(serialize_with = "serialize_entry")]
127 AddEntry(MempoolEntry),
128 #[serde(rename = "delete_entry")]
129 #[serde(serialize_with = "serialize_txid")]
130 DeleteEntry(Txid),
131 #[serde(rename = "update_entry")]
132 #[serde(serialize_with = "serialize_entry")]
133 UpdateEntry(MempoolEntry),
134}
135
136fn serialize_entry<S>(entry: &MempoolEntry, serializer: S) -> Result<S::Ok, S::Error>
137where
138 S: serde::Serializer,
139{
140 use serde::ser::SerializeStruct;
141
142 let mut state = serializer.serialize_struct("EntryWithTxid", 2)?;
143 state.serialize_field("txid", &entry.txid)?;
144 state.serialize_field("entry", entry)?;
145 state.end()
146}
147
148fn serialize_txid<S>(txid: &Txid, serializer: S) -> Result<S::Ok, S::Error>
149where
150 S: serde::Serializer,
151{
152 use serde::ser::SerializeStruct;
153
154 let mut state = serializer.serialize_struct("TxidOnly", 1)?;
155 state.serialize_field("txid", &txid)?;
156 state.end()
157}
158
159impl UpdateMempoolEntriesOp {
160 pub fn txid(&self) -> &Txid {
161 match self {
162 UpdateMempoolEntriesOp::AddEntry(entry) => &entry.txid,
163 UpdateMempoolEntriesOp::DeleteEntry(txid) => txid,
164 UpdateMempoolEntriesOp::UpdateEntry(entry) => &entry.txid,
165 }
166 }
167}