pchain_world_state/network/
pool.rs1use std::{
9 ops::Deref,
10 convert::{TryInto, TryFrom}
11};
12use pchain_types::{ serialization::{Serializable, Deserializable}, cryptography::PublicAddress};
13
14use super::{
15 stake::{Stake, StakeValue},
16 network_account::{NetworkAccountStorage, KeySpaced},
17 index_map::{IndexMap, IndexMapOperationError},
18 index_heap::IndexHeap
19};
20
21#[derive(Debug, Clone, PartialEq, Eq, borsh::BorshSerialize, borsh::BorshDeserialize)]
23pub struct Pool {
24 pub operator: PublicAddress,
26 pub commission_rate: u8,
29 pub power: u64,
31 pub operator_stake: Option<Stake>
33}
34
35impl Serializable for Pool {}
36impl Deserializable for Pool {}
37
38pub struct PoolDict<'a, S, const M: u16>
40 where S: NetworkAccountStorage
41{
42 pub(in crate::network) prefix_key: Vec<u8>,
43 pub(in crate::network) world_state: &'a mut S
44}
45
46impl<'a, S, const M: u16> PoolDict<'a, S, M>
47 where S: NetworkAccountStorage
48{
49 pub fn exists(&self) -> bool {
50 let key = [self.prefix_key.as_slice(), &pool_data::OPERATOR].concat();
51 self.world_state.contains(&key)
52 }
53
54 pub fn operator(&self) -> Option<PublicAddress> {
55 let bytes = self.world_state.get(&[self.prefix_key.as_slice(), &pool_data::OPERATOR].concat())?;
56 match bytes.try_into() {
57 Ok(address) => Some(address),
58 Err(_) => None
59 }
60 }
61
62 pub fn set_operator(&mut self, operator: PublicAddress) {
63 self.world_state.set(&[self.prefix_key.as_slice(), &pool_data::OPERATOR].concat(), operator.to_vec());
64 }
65
66 pub fn power(&self) -> Option<u64> {
67 let bytes = self.world_state.get(&[self.prefix_key.as_slice(), &pool_data::POWER].concat())?;
68 match bytes.try_into() {
69 Ok(value) => Some(u64::from_le_bytes(value)),
70 Err(_) => None
71 }
72 }
73
74 pub fn set_power(&mut self, power: u64) {
75 self.world_state.set(&[self.prefix_key.as_slice(), &pool_data::POWER].concat(), power.to_le_bytes().to_vec());
76 }
77
78 pub fn commission_rate(&self) -> Option<u8> {
79 let bytes = self.world_state.get(&[self.prefix_key.as_slice(), &pool_data::COMMISSION_RATE].concat())?;
80 match bytes.try_into() {
81 Ok(value) => Some(u8::from_le_bytes(value)),
82 Err(_) => None
83 }
84 }
85
86 pub fn set_commission_rate(&mut self, commission_rate: u8) {
87 self.world_state.set(&[self.prefix_key.as_slice(), &pool_data::COMMISSION_RATE].concat(), commission_rate.to_le_bytes().to_vec());
88 }
89
90 pub fn operator_stake(&self) -> Option<Option<Stake>> {
91 self.world_state.get(&[self.prefix_key.as_slice(), &pool_data::OPERATOR_STAKE].concat()).map(|bytes|{
92 Option::<Stake>::deserialize(&bytes).unwrap()
93 })
94 }
95
96 pub fn set_operator_stake(&mut self, stake: Option<Stake>) {
97 self.world_state.set(&[self.prefix_key.as_slice(), &pool_data::OPERATOR_STAKE].concat(), Option::<Stake>::serialize(&stake));
98 }
99
100 pub fn delegated_stakes(&mut self) -> IndexHeap<S, StakeValue> {
101 IndexHeap::<S, StakeValue>::new(
102 [self.prefix_key.as_slice(), &pool_data::DELEGATED_STAKES].concat(),
103 self.world_state,
104 M as u32,
105 )
106 }
107
108 pub fn delete(&'a mut self) {
109 for k in vec![
110 [self.prefix_key.as_slice(), &pool_data::OPERATOR].concat(),
111 [self.prefix_key.as_slice(), &pool_data::POWER].concat(),
112 [self.prefix_key.as_slice(), &pool_data::COMMISSION_RATE].concat(),
113 [self.prefix_key.as_slice(), &pool_data::OPERATOR_STAKE].concat(),
114 ] {
115 self.world_state.delete(k.as_slice());
116 }
117
118 self.delegated_stakes().clear();
119 }
120}
121
122impl<'a, S, const M: u16> TryFrom<PoolDict<'a, S, M>> for Pool
123 where S: NetworkAccountStorage
124{
125 type Error = ();
126 fn try_from(pool: PoolDict<'a, S, M>) -> Result<Self, Self::Error> {
127 Ok(Pool {
128 operator: pool.operator().ok_or(())?,
129 commission_rate: pool.commission_rate().ok_or(())?,
130 power: pool.power().ok_or(())?,
131 operator_stake: pool.operator_stake().ok_or(())?
132 })
133 }
134}
135
136
137pub struct ValidatorPool<'a, S, const N: u16, const M: u16> where S: NetworkAccountStorage
141{
142 inner: IndexMap<'a, S, PoolAddress>
143}
144
145
146impl<'a, S, const N: u16, const M: u16> ValidatorPool<'a, S, N, M> where S: NetworkAccountStorage
147{
148 pub(in crate::network) const PREFIX_NESTED_MAP: [u8; 1] = [3u8];
152
153 pub(in crate::network) fn new(world_state: &'a mut S, prefix_key: Vec<u8>) -> Self {
154 Self {
155 inner: IndexMap::<S, PoolAddress>::new(
156 prefix_key,
157 world_state,
158 N as u32,
159 )
160 }
161 }
162
163 pub fn length(&self) -> u32 {
164 self.inner.length()
165 }
166
167 pub fn pool(&mut self, operator: PublicAddress) -> Option<PoolDict<S, M>> {
168 self.inner.get_by(PoolAddress(operator).key())?;
169
170 Some(PoolDict {
171 prefix_key: [self.inner.domain.as_slice(), &Self::PREFIX_NESTED_MAP, operator.as_slice()].concat(),
172 world_state: self.inner.store
173 })
174 }
175
176 pub fn pool_at(&mut self, index: u32) -> Option<PoolDict<S, M>> {
177 let pool_address = self.inner.get(index)?;
178 self.pool(pool_address.into())
179 }
180
181 pub fn push(&'a mut self, pool: Pool, delegated_stakes: Vec<StakeValue>) -> Result<(), IndexMapOperationError> {
183 self.inner.push(PoolAddress(pool.operator))?;
185
186 let mut pool_dict = self.pool(pool.operator).unwrap();
188 pool_dict.set_operator(pool.operator);
189 pool_dict.set_power(pool.power);
190 pool_dict.set_commission_rate(pool.commission_rate);
191 pool_dict.set_operator_stake(pool.operator_stake);
192
193 let _ = pool_dict.delegated_stakes().reset(delegated_stakes);
195 Ok(())
196 }
197
198 pub fn clear(&'a mut self) {
200 let pool_length = self.length();
201 for i in 0..pool_length {
202 let mut pool = self.pool_at(i).unwrap();
203 pool.delegated_stakes().clear();
204 pool.delete();
205 }
206 self.inner.set_length(0);
207 }
208
209 pub fn get(&self, index: u32) -> Option<PoolAddress> {
210 self.inner.get(index)
211 }
212
213}
214
215mod pool_data {
216 pub const OPERATOR: [u8; 1] = [0x0];
217 pub const POWER: [u8; 1] = [0x1];
218 pub const COMMISSION_RATE: [u8; 1] = [0x2];
219 pub const OPERATOR_STAKE: [u8; 1] = [0x3];
220 pub const DELEGATED_STAKES: [u8; 1] = [0x4];
221}
222
223#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
226pub struct PoolAddress(pub PublicAddress);
227
228impl KeySpaced for PoolAddress {
229 fn key(&self) -> &[u8] {
230 &self.0
231 }
232}
233
234impl From<PoolAddress> for Vec<u8>{
235 fn from(value: PoolAddress) -> Vec<u8> {
236 value.0.to_vec()
237 }
238}
239
240impl From<Vec<u8>> for PoolAddress {
241 fn from(value: Vec<u8>) -> Self {
242 Self(value.try_into().unwrap())
243 }
244}
245
246impl From<PoolAddress> for PublicAddress {
247 fn from(value: PoolAddress) -> Self {
248 value.0
249 }
250}
251
252impl Deref for PoolAddress {
253 type Target = PublicAddress;
254 fn deref(&self) -> &Self::Target {
255 &self.0
256 }
257}
258
259#[derive(Clone)]
260pub struct PoolKey {
262 pub operator: PublicAddress,
263 pub power: u64
264}
265
266impl PoolKey {
267 pub fn new(operator: PublicAddress, power: u64) -> Self {
268 Self { operator, power }
269 }
270}
271
272impl KeySpaced for PoolKey {
273 fn key(&self) -> &[u8] {
274 self.operator.as_slice()
275 }
276}
277
278impl Eq for PoolKey {}
279
280impl PartialEq for PoolKey {
281 fn eq(&self, other: &Self) -> bool {
282 match self.power.eq(&other.power) {
283 true => self.operator.eq(&other.operator),
284 false => false,
285 }
286 }
287}
288
289impl PartialOrd for PoolKey {
290 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
291 match self.power.partial_cmp(&other.power) {
292 Some(std::cmp::Ordering::Equal) => self.operator.partial_cmp(&other.operator),
293 Some(compare) => Some(compare),
294 None => None
295 }
296 }
297}
298
299impl Ord for PoolKey {
300 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
301 match self.power.cmp(&other.power) {
302 std::cmp::Ordering::Equal => self.operator.cmp(&other.operator),
303 compare => compare
304 }
305 }
306}
307
308impl From<PoolKey> for Vec<u8> {
309 fn from(pool_key: PoolKey) -> Self {
310 <(Vec<u8>, u64)>::serialize(&(pool_key.operator.to_vec(), pool_key.power))
311 }
312}
313
314impl From<Vec<u8>> for PoolKey {
315 fn from(bytes: Vec<u8>) -> Self {
316 let (operator, power) = <(Vec<u8>, u64)>::deserialize(&bytes).unwrap();
317 Self { operator: operator.try_into().unwrap(), power }
318 }
319}