casper_storage/system/handle_payment/
handle_payment_native.rs1use crate::{
2 global_state::{error::Error as GlobalStateError, state::StateReader},
3 system::{
4 handle_payment::{
5 mint_provider::MintProvider, runtime_provider::RuntimeProvider,
6 storage_provider::StorageProvider, HandlePayment,
7 },
8 mint::Mint,
9 runtime_native::RuntimeNative,
10 },
11 tracking_copy::TrackingCopyEntityExt,
12};
13use casper_types::{
14 account::AccountHash,
15 addressable_entity::{NamedKeyAddr, NamedKeyValue},
16 system::handle_payment::Error,
17 AccessRights, CLValue, FeeHandling, GrantedAccess, Key, Phase, RefundHandling, StoredValue,
18 TransferredTo, URef, U512,
19};
20use std::collections::BTreeSet;
21use tracing::error;
22
23impl<S> MintProvider for RuntimeNative<S>
24where
25 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
26{
27 fn transfer_purse_to_account(
28 &mut self,
29 source: URef,
30 target: AccountHash,
31 amount: U512,
32 ) -> Result<TransferredTo, Error> {
33 let target_key = Key::Account(target);
34 let target_uref = match self.tracking_copy().borrow_mut().read(&target_key) {
35 Ok(Some(StoredValue::CLValue(cl_value))) => {
36 let entity_key = CLValue::into_t::<Key>(cl_value)
37 .map_err(|_| Error::FailedTransferToAccountPurse)?;
38 let target_uref = {
40 if let Ok(Some(StoredValue::AddressableEntity(entity))) =
41 self.tracking_copy().borrow_mut().read(&entity_key)
42 {
43 entity.main_purse_add_only()
44 } else {
45 return Err(Error::Transfer);
46 }
47 };
48 target_uref
49 } Ok(Some(StoredValue::Account(account))) => {
51 if self.config().enable_addressable_entity() {
52 self.tracking_copy()
53 .borrow_mut()
54 .migrate_account(target, self.protocol_version())
55 .map_err(|_| Error::Transfer)?;
56 }
57
58 account.main_purse_add_only()
59 }
60 Ok(_) | Err(_) => return Err(Error::Transfer),
61 };
62
63 if source.with_access_rights(AccessRights::ADD) == target_uref {
65 return Ok(TransferredTo::ExistingAccount);
66 }
67
68 let granted_access = self.access_rights_mut().grant_access(target_uref);
70
71 let transfered = self
72 .transfer_purse_to_purse(source, target_uref, amount)
73 .is_ok();
74
75 if let GrantedAccess::Granted {
77 uref_addr,
78 newly_granted_access_rights,
79 } = granted_access
80 {
81 self.access_rights_mut()
82 .remove_access(uref_addr, newly_granted_access_rights)
83 }
84
85 if transfered {
86 Ok(TransferredTo::ExistingAccount)
87 } else {
88 Err(Error::Transfer)
89 }
90 }
91
92 fn transfer_purse_to_purse(
93 &mut self,
94 source: URef,
95 target: URef,
96 amount: U512,
97 ) -> Result<(), Error> {
98 match self.transfer(None, source, target, amount, None) {
100 Ok(ret) => Ok(ret),
101 Err(err) => {
102 error!("{}", err);
103 Err(Error::Transfer)
104 }
105 }
106 }
107
108 fn available_balance(&mut self, purse: URef) -> Result<Option<U512>, Error> {
109 match <Self as Mint>::balance(self, purse) {
110 Ok(ret) => Ok(ret),
111 Err(err) => {
112 error!("{}", err);
113 Err(Error::GetBalance)
114 }
115 }
116 }
117
118 fn reduce_total_supply(&mut self, amount: U512) -> Result<(), Error> {
119 match <Self as Mint>::reduce_total_supply(self, amount) {
120 Ok(ret) => Ok(ret),
121 Err(err) => {
122 error!("{}", err);
123 Err(Error::ReduceTotalSupply)
124 }
125 }
126 }
127}
128
129impl<S> RuntimeProvider for RuntimeNative<S>
130where
131 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
132{
133 fn get_key(&mut self, name: &str) -> Option<Key> {
134 self.named_keys().get(name).cloned()
135 }
136
137 fn put_key(&mut self, name: &str, key: Key) -> Result<(), Error> {
138 let name = name.to_string();
139 match self.context_key() {
140 Key::Account(_) | Key::Hash(_) => {
141 let name: String = name.clone();
142 let value = CLValue::from_t((name.clone(), key)).map_err(|_| Error::PutKey)?;
143 let named_key_value = StoredValue::CLValue(value);
144 self.tracking_copy()
145 .borrow_mut()
146 .add(*self.context_key(), named_key_value)
147 .map_err(|_| Error::PutKey)?;
148 self.named_keys_mut().insert(name, key);
149 Ok(())
150 }
151 Key::AddressableEntity(entity_addr) => {
152 let named_key_value = StoredValue::NamedKey(
153 NamedKeyValue::from_concrete_values(key, name.clone())
154 .map_err(|_| Error::PutKey)?,
155 );
156 let named_key_addr = NamedKeyAddr::new_from_string(*entity_addr, name.clone())
157 .map_err(|_| Error::PutKey)?;
158 let named_key = Key::NamedKey(named_key_addr);
159 self.tracking_copy()
161 .borrow_mut()
162 .write(named_key, named_key_value);
163 self.named_keys_mut().insert(name, key);
164 Ok(())
165 }
166 _ => Err(Error::UnexpectedKeyVariant),
167 }
168 }
169
170 fn remove_key(&mut self, name: &str) -> Result<(), Error> {
171 self.named_keys_mut().remove(name);
172 match self.context_key() {
173 Key::AddressableEntity(entity_addr) => {
174 let named_key_addr = NamedKeyAddr::new_from_string(*entity_addr, name.to_string())
175 .map_err(|_| Error::RemoveKey)?;
176 let key = Key::NamedKey(named_key_addr);
177 let value = self
178 .tracking_copy()
179 .borrow_mut()
180 .read(&key)
181 .map_err(|_| Error::RemoveKey)?;
182 if let Some(StoredValue::NamedKey(_)) = value {
183 self.tracking_copy().borrow_mut().prune(key);
184 }
185 }
186 Key::Hash(_) => {
187 let mut contract = self
188 .tracking_copy()
189 .borrow_mut()
190 .read(self.context_key())
191 .map_err(|_| Error::RemoveKey)?
192 .ok_or(Error::RemoveKey)?
193 .as_contract()
194 .ok_or(Error::RemoveKey)?
195 .clone();
196
197 if contract.remove_named_key(name).is_none() {
198 return Ok(());
199 }
200
201 self.tracking_copy()
202 .borrow_mut()
203 .write(*self.context_key(), StoredValue::Contract(contract))
204 }
205 Key::Account(_) => {
206 let account = {
207 let mut account = match self
208 .tracking_copy()
209 .borrow_mut()
210 .read(self.context_key())
211 .map_err(|_| Error::RemoveKey)?
212 {
213 Some(StoredValue::Account(account)) => account,
214 Some(_) | None => return Err(Error::UnexpectedKeyVariant),
215 };
216 account.named_keys_mut().remove(name);
217 account
218 };
219 self.tracking_copy()
220 .borrow_mut()
221 .write(*self.context_key(), StoredValue::Account(account));
222 }
223 _ => return Err(Error::UnexpectedKeyVariant),
224 }
225
226 Ok(())
227 }
228
229 fn get_phase(&self) -> Phase {
230 self.phase()
231 }
232
233 fn get_caller(&self) -> AccountHash {
234 self.address()
235 }
236
237 fn refund_handling(&self) -> RefundHandling {
238 *self.config().refund_handling()
239 }
240
241 fn fee_handling(&self) -> FeeHandling {
242 *self.config().fee_handling()
243 }
244
245 fn administrative_accounts(&self) -> BTreeSet<AccountHash> {
246 self.transfer_config().administrative_accounts()
247 }
248}
249
250impl<S> StorageProvider for RuntimeNative<S>
251where
252 S: StateReader<Key, StoredValue, Error = GlobalStateError>,
253{
254 fn write_balance(&mut self, purse_uref: URef, amount: U512) -> Result<(), Error> {
255 let cl_value = CLValue::from_t(amount).map_err(|_| Error::Storage)?;
256 self.tracking_copy().borrow_mut().write(
257 Key::Balance(purse_uref.addr()),
258 StoredValue::CLValue(cl_value),
259 );
260 Ok(())
261 }
262}
263
264impl<S> HandlePayment for RuntimeNative<S> where
265 S: StateReader<Key, StoredValue, Error = GlobalStateError>
266{
267}