1use crate::{
2 global_state::{error::Error as GlobalStateError, state::StateReader},
3 system::{
4 auction::{
5 providers::{AccountProvider, MintProvider, RuntimeProvider, StorageProvider},
6 Auction,
7 },
8 mint::Mint,
9 runtime_native::RuntimeNative,
10 },
11 tracking_copy::{TrackingCopyEntityExt, TrackingCopyError},
12};
13use casper_types::{
14 account::AccountHash,
15 bytesrepr::{FromBytes, ToBytes},
16 system::{
17 auction::{BidAddr, BidKind, EraInfo, Error, Unbond, UnbondEra, UnbondKind},
18 mint,
19 },
20 AccessRights, CLTyped, CLValue, Key, KeyTag, PublicKey, StoredValue, URef, U512,
21};
22use std::collections::BTreeSet;
23use tracing::{debug, error};
24
25impl<S> RuntimeProvider for RuntimeNative<S>
26where
27 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
28{
29 fn get_caller(&self) -> AccountHash {
30 self.address()
31 }
32
33 fn is_allowed_session_caller(&self, account_hash: &AccountHash) -> bool {
34 if self.get_caller() == PublicKey::System.to_account_hash() {
35 return true;
36 }
37
38 account_hash == &self.address()
39 }
40
41 fn is_valid_uref(&self, uref: URef) -> bool {
42 self.access_rights().has_access_rights_to_uref(&uref)
43 }
44
45 fn named_keys_get(&self, name: &str) -> Option<Key> {
46 self.named_keys().get(name).cloned()
47 }
48
49 fn get_keys(&mut self, key_tag: &KeyTag) -> Result<BTreeSet<Key>, Error> {
50 self.tracking_copy()
51 .borrow_mut()
52 .get_keys(key_tag)
53 .map_err(|error| {
54 error!(%key_tag, "RuntimeProvider::get_keys: {:?}", error);
55 Error::Storage
56 })
57 }
58
59 fn get_keys_by_prefix(&mut self, prefix: &[u8]) -> Result<Vec<Key>, Error> {
60 self.tracking_copy()
61 .borrow_mut()
62 .reader()
63 .keys_with_prefix(prefix)
64 .map_err(|error| {
65 error!("RuntimeProvider::get_keys_by_prefix: {:?}", error);
66 Error::Storage
67 })
68 }
69
70 fn delegator_count(&mut self, bid_addr: &BidAddr) -> Result<usize, Error> {
71 let delegated_accounts = {
72 let prefix = bid_addr.delegated_account_prefix()?;
73 let keys = self.get_keys_by_prefix(&prefix).map_err(|err| {
74 error!("RuntimeProvider::delegator_count {:?}", err);
75 Error::Storage
76 })?;
77 keys.len()
78 };
79 let delegated_purses = {
80 let prefix = bid_addr.delegated_purse_prefix()?;
81 let keys = self.get_keys_by_prefix(&prefix).map_err(|err| {
82 error!("RuntimeProvider::delegator_count {:?}", err);
83 Error::Storage
84 })?;
85 keys.len()
86 };
87 Ok(delegated_accounts.saturating_add(delegated_purses))
88 }
89
90 fn reservation_count(&mut self, bid_addr: &BidAddr) -> Result<usize, Error> {
91 let reserved_accounts = {
92 let reservation_prefix = bid_addr.reserved_account_prefix()?;
93 let reservation_keys = self
94 .get_keys_by_prefix(&reservation_prefix)
95 .map_err(|err| {
96 error!("RuntimeProvider::reservation_count {:?}", err);
97 Error::Storage
98 })?;
99 reservation_keys.len()
100 };
101 let reserved_purses = {
102 let reservation_prefix = bid_addr.reserved_purse_prefix()?;
103 let reservation_keys = self
104 .get_keys_by_prefix(&reservation_prefix)
105 .map_err(|err| {
106 error!("RuntimeProvider::reservation_count {:?}", err);
107 Error::Storage
108 })?;
109 reservation_keys.len()
110 };
111 Ok(reserved_accounts.saturating_add(reserved_purses))
112 }
113
114 fn used_reservation_count(&mut self, bid_addr: &BidAddr) -> Result<usize, Error> {
115 let reservation_account_prefix = bid_addr.reserved_account_prefix()?;
116 let reservation_purse_prefix = bid_addr.reserved_purse_prefix()?;
117
118 let mut reservation_keys = self
119 .get_keys_by_prefix(&reservation_account_prefix)
120 .map_err(|exec_error| {
121 error!("RuntimeProvider::reservation_count {:?}", exec_error);
122 <Option<Error>>::from(exec_error).unwrap_or(Error::Storage)
123 })?;
124
125 let more = self
126 .get_keys_by_prefix(&reservation_purse_prefix)
127 .map_err(|exec_error| {
128 error!("RuntimeProvider::reservation_count {:?}", exec_error);
129 <Option<Error>>::from(exec_error).unwrap_or(Error::Storage)
130 })?;
131
132 reservation_keys.extend(more);
133
134 let mut used = 0;
135 for reservation_key in reservation_keys {
136 if let Key::BidAddr(BidAddr::ReservedDelegationAccount {
137 validator,
138 delegator,
139 }) = reservation_key
140 {
141 let key_to_check = Key::BidAddr(BidAddr::DelegatedAccount {
142 validator,
143 delegator,
144 });
145 if let Ok(Some(_)) = self.read_bid(&key_to_check) {
146 used += 1;
147 }
148 }
149 if let Key::BidAddr(BidAddr::ReservedDelegationPurse {
150 validator,
151 delegator,
152 }) = reservation_key
153 {
154 let key_to_check = Key::BidAddr(BidAddr::DelegatedPurse {
155 validator,
156 delegator,
157 });
158 if let Ok(Some(_)) = self.read_bid(&key_to_check) {
159 used += 1;
160 }
161 }
162 }
163 Ok(used)
164 }
165
166 fn vesting_schedule_period_millis(&self) -> u64 {
167 self.vesting_schedule_period_millis()
168 }
169
170 fn allow_auction_bids(&self) -> bool {
171 self.allow_auction_bids()
172 }
173
174 fn should_compute_rewards(&self) -> bool {
175 self.compute_rewards()
176 }
177}
178
179impl<S> StorageProvider for RuntimeNative<S>
180where
181 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
182{
183 fn read<T: FromBytes + CLTyped>(&mut self, uref: URef) -> Result<Option<T>, Error> {
184 if !self.access_rights().has_access_rights_to_uref(&uref) {
186 return Err(Error::ForgedReference);
187 }
188 let key = &Key::URef(uref);
189 let stored_value = match self.tracking_copy().borrow_mut().read(key) {
190 Ok(Some(stored_value)) => stored_value,
191 Ok(None) => return Ok(None),
192 Err(_) => return Err(Error::Storage),
193 };
194 if let StoredValue::CLValue(value) = stored_value {
196 let value = CLValue::into_t(value).map_err(|_| Error::CLValue)?;
198 Ok(Some(value))
199 } else {
200 Err(Error::CLValue)
201 }
202 }
203
204 fn write<T: ToBytes + CLTyped>(&mut self, uref: URef, value: T) -> Result<(), Error> {
205 let cl_value = CLValue::from_t(value).map_err(|_| Error::CLValue)?;
206 if !uref.is_writeable() {
208 error!("uref not writeable {}", uref);
209 return Err(Error::Storage);
210 }
211 if !self.access_rights().has_access_rights_to_uref(&uref) {
213 return Err(Error::ForgedReference);
214 }
215 self.tracking_copy()
216 .borrow_mut()
217 .write(Key::URef(uref), StoredValue::CLValue(cl_value));
218 Ok(())
219 }
220
221 fn read_bid(&mut self, key: &Key) -> Result<Option<BidKind>, Error> {
222 match self.tracking_copy().borrow_mut().read(key) {
223 Ok(Some(StoredValue::BidKind(bid_kind))) => Ok(Some(bid_kind)),
224 Ok(Some(_)) => {
225 error!("StorageProvider::read_bid: unexpected StoredValue variant");
226 Err(Error::Storage)
227 }
228 Ok(None) => Ok(None),
229 Err(TrackingCopyError::BytesRepr(_)) => Err(Error::Serialization),
230 Err(err) => {
231 error!("StorageProvider::read_bid: {:?}", err);
232 Err(Error::Storage)
233 }
234 }
235 }
236
237 fn write_bid(&mut self, key: Key, bid_kind: BidKind) -> Result<(), Error> {
238 let stored_value = StoredValue::BidKind(bid_kind);
239
240 self.tracking_copy().borrow_mut().write(key, stored_value);
245 Ok(())
246 }
247
248 fn read_unbond(&mut self, bid_addr: BidAddr) -> Result<Option<Unbond>, Error> {
249 match self
250 .tracking_copy()
251 .borrow_mut()
252 .read(&Key::BidAddr(bid_addr))
253 {
254 Ok(Some(StoredValue::BidKind(BidKind::Unbond(unbond)))) => Ok(Some(*unbond)),
255 Ok(Some(_)) => {
256 error!("StorageProvider::read_unbonds: unexpected StoredValue variant");
257 Err(Error::Storage)
258 }
259 Ok(None) => Ok(None),
260 Err(TrackingCopyError::BytesRepr(_)) => Err(Error::Serialization),
261 Err(err) => {
262 error!("StorageProvider::read_unbonds: {:?}", err);
263 Err(Error::Storage)
264 }
265 }
266 }
267
268 fn write_unbond(&mut self, bid_addr: BidAddr, unbond: Option<Unbond>) -> Result<(), Error> {
269 let unbond_key = Key::BidAddr(bid_addr);
270 match unbond {
271 Some(unbond) => {
272 self.tracking_copy().borrow_mut().write(
273 unbond_key,
274 StoredValue::BidKind(BidKind::Unbond(Box::new(unbond))),
275 );
276 }
277 None => {
278 self.tracking_copy().borrow_mut().prune(unbond_key);
279 }
280 }
281 Ok(())
282 }
283
284 fn record_era_info(&mut self, era_info: EraInfo) -> Result<(), Error> {
285 if self.get_caller() != PublicKey::System.to_account_hash() {
286 return Err(Error::InvalidContext);
287 }
288 self.tracking_copy()
289 .borrow_mut()
290 .write(Key::EraSummary, StoredValue::EraInfo(era_info));
291 Ok(())
292 }
293
294 fn prune_bid(&mut self, bid_addr: BidAddr) {
295 self.tracking_copy().borrow_mut().prune(bid_addr.into());
296 }
297}
298
299impl<S> MintProvider for RuntimeNative<S>
300where
301 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
302{
303 fn unbond(&mut self, unbond_kind: &UnbondKind, unbond_era: &UnbondEra) -> Result<(), Error> {
304 let (purse, maybe_account_hash) = match unbond_kind {
305 UnbondKind::Validator(pk) | UnbondKind::DelegatedPublicKey(pk) => {
306 let account_hash = pk.to_account_hash();
307 self.tracking_copy()
310 .borrow_mut()
311 .migrate_account(account_hash, self.protocol_version())
312 .map_err(|error| {
313 error!(
314 "MintProvider::unbond: couldn't migrate account: {:?}",
315 error
316 );
317 Error::Storage
318 })?;
319
320 let maybe_value = self
321 .tracking_copy()
322 .borrow_mut()
323 .read(&Key::Account(account_hash))
324 .map_err(|error| {
325 error!("MintProvider::unbond: {:?}", error);
326 Error::Storage
327 })?;
328
329 match maybe_value {
330 Some(StoredValue::Account(account)) => {
331 (account.main_purse(), Some(account_hash))
332 }
333 Some(StoredValue::CLValue(cl_value)) => {
334 let entity_key: Key = cl_value.into_t().map_err(|_| Error::CLValue)?;
335 let maybe_value = self
336 .tracking_copy()
337 .borrow_mut()
338 .read(&entity_key)
339 .map_err(|error| {
340 error!("MintProvider::unbond: {:?}", error);
341 Error::Storage
342 })?;
343 match maybe_value {
344 Some(StoredValue::AddressableEntity(entity)) => {
345 (entity.main_purse(), Some(account_hash))
346 }
347 Some(_cl_value) => return Err(Error::CLValue),
348 None => return Err(Error::InvalidPublicKey),
349 }
350 }
351 Some(_cl_value) => return Err(Error::CLValue),
352 None => return Err(Error::InvalidPublicKey),
353 }
354 }
355 UnbondKind::DelegatedPurse(addr) => {
356 let purse = URef::new(*addr, AccessRights::READ_ADD_WRITE);
357 match self.balance(purse) {
358 Ok(Some(_)) => (purse, None),
359 Ok(None) => return Err(Error::MissingPurse),
360 Err(err) => {
361 error!("MintProvider::unbond: {:?}", err);
362 return Err(Error::Unbonding);
363 }
364 }
365 }
366 };
367
368 self.mint_transfer_direct(
369 maybe_account_hash,
370 *unbond_era.bonding_purse(),
371 purse,
372 *unbond_era.amount(),
373 None,
374 )
375 .map_err(|_| Error::Transfer)?
376 .map_err(|_| Error::Transfer)?;
377 Ok(())
378 }
379
380 fn mint_transfer_direct(
381 &mut self,
382 to: Option<AccountHash>,
383 source: URef,
384 target: URef,
385 amount: U512,
386 id: Option<u64>,
387 ) -> Result<Result<(), mint::Error>, Error> {
388 let addr = if let Some(uref) = self.runtime_footprint().main_purse() {
389 uref.addr()
390 } else {
391 return Err(Error::InvalidContext);
392 };
393 if !(addr == source.addr() || self.get_caller() == PublicKey::System.to_account_hash()) {
394 return Err(Error::InvalidCaller);
395 }
396
397 self.extend_access_rights(&[source, target.into_add()]);
399
400 match self.transfer(to, source, target, amount, id) {
401 Ok(ret) => {
402 Ok(Ok(ret))
404 }
405 Err(err) => {
406 error!("{}", err);
407 Err(Error::Transfer)
408 }
409 }
410 }
411
412 fn mint_into_existing_purse(
413 &mut self,
414 amount: U512,
415 existing_purse: URef,
416 ) -> Result<(), Error> {
417 if self.get_caller() != PublicKey::System.to_account_hash() {
418 return Err(Error::InvalidCaller);
419 }
420
421 match <Self as Mint>::mint_into_existing_purse(self, existing_purse, amount) {
422 Ok(ret) => Ok(ret),
423 Err(err) => {
424 error!("{}", err);
425 Err(Error::MintError)
426 }
427 }
428 }
429
430 fn create_purse(&mut self) -> Result<URef, Error> {
431 let initial_balance = U512::zero();
432 match <Self as Mint>::mint(self, initial_balance) {
433 Ok(ret) => Ok(ret),
434 Err(err) => {
435 error!("{}", err);
436 Err(Error::CreatePurseFailed)
437 }
438 }
439 }
440
441 fn available_balance(&mut self, purse: URef) -> Result<Option<U512>, Error> {
442 match <Self as Mint>::balance(self, purse) {
443 Ok(ret) => Ok(ret),
444 Err(err) => {
445 error!("{}", err);
446 Err(Error::GetBalance)
447 }
448 }
449 }
450
451 fn read_base_round_reward(&mut self) -> Result<U512, Error> {
452 match <Self as Mint>::read_base_round_reward(self) {
453 Ok(ret) => Ok(ret),
454 Err(err) => {
455 error!("{}", err);
456 Err(Error::MissingValue)
457 }
458 }
459 }
460
461 fn mint(&mut self, amount: U512) -> Result<URef, Error> {
462 match <Self as Mint>::mint(self, amount) {
463 Ok(ret) => Ok(ret),
464 Err(err) => {
465 error!("{}", err);
466 Err(Error::MintReward)
467 }
468 }
469 }
470
471 fn reduce_total_supply(&mut self, amount: U512) -> Result<(), Error> {
472 match <Self as Mint>::reduce_total_supply(self, amount) {
473 Ok(ret) => Ok(ret),
474 Err(err) => {
475 error!("{}", err);
476 Err(Error::MintReduceTotalSupply)
477 }
478 }
479 }
480}
481
482impl<S> AccountProvider for RuntimeNative<S>
483where
484 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
485{
486 fn get_main_purse(&self) -> Result<URef, Error> {
487 match self.runtime_footprint().main_purse() {
490 None => {
491 debug!("runtime_native attempt to access non-existent main purse");
492 Err(Error::InvalidContext)
493 }
494 Some(purse) => Ok(purse),
495 }
496 }
497
498 fn set_main_purse(&mut self, purse: URef) {
500 self.runtime_footprint_mut().set_main_purse(purse);
501 }
502}
503
504impl<S> Auction for RuntimeNative<S> where S: StateReader<Key, StoredValue, Error = GlobalStateError>
505{}