/home/runner/work/creditcoin/creditcoin/pallets/creditcoin/src/migrations/v6.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use super::v5; |
2 | | use crate::Config; |
3 | | use crate::EvmCurrencyType; |
4 | | use crate::EvmInfo; |
5 | | use crate::EvmSupportedTransferKinds; |
6 | | use crate::EvmTransferKind; |
7 | | use crate::Id; |
8 | | use core::convert::TryFrom; |
9 | | use frame_support::generate_storage_alias; |
10 | | use frame_support::pallet_prelude::*; |
11 | | use sp_std::collections::btree_map::BTreeMap; |
12 | | use sp_std::collections::btree_set::BTreeSet; |
13 | | use sp_std::prelude::*; |
14 | | |
15 | | pub use v5::*; |
16 | | |
17 | | pub use v5::Address as OldAddress; |
18 | | pub use v5::AskOrder as OldAskOrder; |
19 | | pub use v5::AskTerms as OldAskTerms; |
20 | | pub use v5::BidOrder as OldBidOrder; |
21 | | pub use v5::BidTerms as OldBidTerms; |
22 | | pub use v5::Blockchain as OldBlockchain; |
23 | | pub use v5::DealOrder as OldDealOrder; |
24 | | pub use v5::LoanTerms as OldLoanTerms; |
25 | | pub use v5::OrderId as OldOrderId; |
26 | | pub use v5::Task as OldTask; |
27 | | pub use v5::Transfer as OldTransfer; |
28 | | pub use v5::TransferKind as OldTransferKind; |
29 | | pub use v5::UnverifiedCollectedCoinsStruct as OldUnverifiedCollectedCoins; |
30 | | pub use v5::UnverifiedTransfer as OldUnverifiedTransfer; |
31 | | |
32 | | use crate::Address; |
33 | | use crate::AddressId; |
34 | | use crate::AskOrder; |
35 | | use crate::AskOrderId; |
36 | | use crate::AskTerms; |
37 | | use crate::BidOrder; |
38 | | use crate::BidOrderId; |
39 | | use crate::BidTerms; |
40 | | use crate::Blockchain; |
41 | | use crate::Currency; |
42 | | use crate::CurrencyId; |
43 | | use crate::DealOrder; |
44 | | use crate::LegacyTransferKind; |
45 | | use crate::LoanTerms; |
46 | | use crate::Task; |
47 | | use crate::TaskId; |
48 | | use crate::Transfer; |
49 | | use crate::TransferId; |
50 | | use crate::TransferKind; |
51 | | use crate::UnverifiedCollectedCoins; |
52 | | use crate::UnverifiedTransfer; |
53 | | |
54 | 16 | fn translate_blockchain(old: OldBlockchain) -> Option<Blockchain> { |
55 | 16 | match old { |
56 | 12 | OldBlockchain::Ethereum => Some(Blockchain::ETHEREUM), |
57 | 4 | OldBlockchain::Rinkeby => Some(Blockchain::RINKEBY), |
58 | | // this assumes that Luniverse == mainnet luniverse, we may want to make the chain ID of the |
59 | | // old "Luniverse" variant on-chain-storage to make testnet work |
60 | 0 | OldBlockchain::Luniverse => Some(Blockchain::LUNIVERSE), |
61 | 0 | other => { |
62 | 0 | log::warn!( |
63 | 0 | "unexpected blockchain found on storage item: {:?}", |
64 | 0 | core::str::from_utf8(other.as_bytes()).ok() |
65 | | ); |
66 | 0 | None |
67 | | }, |
68 | | } |
69 | 16 | } |
70 | | |
71 | 8 | fn translate_loan_terms<T: Config>( |
72 | 8 | old: OldLoanTerms, |
73 | 8 | currency: CurrencyId<T::Hash>, |
74 | 8 | ) -> LoanTerms<T::Hash> { |
75 | 8 | LoanTerms { |
76 | 8 | amount: old.amount, |
77 | 8 | interest_rate: old.interest_rate, |
78 | 8 | term_length: old.term_length, |
79 | 8 | currency, |
80 | 8 | } |
81 | 8 | } |
82 | | |
83 | 3 | fn translate_transfer_kind(old: OldTransferKind) -> Option<TransferKind> { |
84 | 3 | Some(match old { |
85 | 3 | OldTransferKind::Ethless(_) => TransferKind::Evm(EvmTransferKind::Ethless), |
86 | 0 | OldTransferKind::Erc20(_) => TransferKind::Evm(EvmTransferKind::Erc20), |
87 | 0 | other => { |
88 | 0 | log::warn!("unexpected transfer kind found on storage item: {:?}", other); |
89 | 0 | return None; |
90 | | }, |
91 | | }) |
92 | 3 | } |
93 | | |
94 | 2 | fn reconstruct_currency(blockchain: &OldBlockchain, kind: &OldTransferKind) -> Option<Currency> { |
95 | 2 | let info = match blockchain { |
96 | 0 | OldBlockchain::Ethereum => EvmInfo::ETHEREUM, |
97 | 2 | OldBlockchain::Rinkeby => EvmInfo::RINKEBY, |
98 | 0 | OldBlockchain::Luniverse => EvmInfo::LUNIVERSE, |
99 | 0 | other => { |
100 | 0 | log::warn!( |
101 | 0 | "unexpected blockchain found on storage item: {:?}", |
102 | 0 | core::str::from_utf8(other.as_bytes()).ok() |
103 | | ); |
104 | 0 | return None; |
105 | | }, |
106 | | }; |
107 | 2 | let currency_type = match kind { |
108 | 0 | OldTransferKind::Erc20(addr) => EvmCurrencyType::SmartContract( |
109 | 0 | addr.clone(), |
110 | 0 | EvmSupportedTransferKinds::try_from(vec![EvmTransferKind::Erc20]) |
111 | 0 | .expect("1 is less than the bound (2); qed"), |
112 | 0 | ), |
113 | 2 | OldTransferKind::Ethless(addr) => EvmCurrencyType::SmartContract( |
114 | 2 | addr.clone(), |
115 | 2 | EvmSupportedTransferKinds::try_from(vec![EvmTransferKind::Ethless]) |
116 | 2 | .expect("1 is less than the bound (2); qed"), |
117 | 2 | ), |
118 | 0 | other => { |
119 | 0 | log::warn!("unexpected transfer kind found in storage: {:?}", other); |
120 | 0 | return None; |
121 | | }, |
122 | | }; |
123 | 2 | Some(Currency::Evm(currency_type, info)) |
124 | 2 | } |
125 | | |
126 | 4 | fn reconstruct_currency_from_deal<T: Config>( |
127 | 4 | deal_order: &OldDealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, |
128 | 4 | ) -> Option<Currency> { |
129 | 4 | let transfer_id2 = deal_order.funding_transfer_id.as_ref()?2 ; |
130 | 2 | let transfer = OldTransfers::<T>::get(transfer_id)?0 ; |
131 | 2 | let currency = reconstruct_currency(&deal_order.blockchain, &transfer.kind)?0 ; |
132 | 2 | Some(currency) |
133 | 4 | } |
134 | | |
135 | 3 | fn translate_transfer<T: Config>( |
136 | 3 | transfer: OldTransfer<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, |
137 | 3 | ) -> Option<Transfer<T::AccountId, T::BlockNumber, T::Hash, T::Moment>> { |
138 | 3 | Some(Transfer { |
139 | 3 | amount: transfer.amount, |
140 | 3 | from: transfer.from, |
141 | 3 | to: transfer.to, |
142 | 3 | tx_id: transfer.tx_id, |
143 | 3 | block: transfer.block, |
144 | 3 | is_processed: transfer.is_processed, |
145 | 3 | account_id: transfer.account_id, |
146 | 3 | timestamp: transfer.timestamp, |
147 | 3 | deal_order_id: match transfer.order_id { |
148 | 3 | OldOrderId::Deal(id) => id, |
149 | 0 | OldOrderId::Repayment(id) => { |
150 | 0 | log::warn!("Found unexpected repayment ID attached to a transfer: {:?}", id); |
151 | 0 | return None; |
152 | | }, |
153 | | }, |
154 | 3 | blockchain: translate_blockchain(transfer.blockchain)?0 , |
155 | 3 | kind: translate_transfer_kind(transfer.kind)?0 , |
156 | | }) |
157 | 3 | } |
158 | | |
159 | 0 | fn to_legacy_transfer_kind(transfer_kind: OldTransferKind) -> LegacyTransferKind { |
160 | 0 | match transfer_kind { |
161 | 0 | OldTransferKind::Erc20(addr) => LegacyTransferKind::Erc20(addr), |
162 | 0 | OldTransferKind::Ethless(addr) => LegacyTransferKind::Ethless(addr), |
163 | 0 | OldTransferKind::Native => LegacyTransferKind::Native, |
164 | 0 | OldTransferKind::Other(other) => LegacyTransferKind::Other(other), |
165 | | } |
166 | 0 | } |
167 | | |
168 | | generate_storage_alias!( |
169 | | Creditcoin, |
170 | | Transfers<T: Config> => Map<(Identity, TransferId<T::Hash>), Transfer<T::AccountId, T::BlockNumber, T::Hash, T::Moment>> |
171 | | ); |
172 | | |
173 | | struct OldTransfersInstance; |
174 | | impl frame_support::traits::StorageInstance for OldTransfersInstance { |
175 | 5 | fn pallet_prefix() -> &'static str { |
176 | 5 | "Creditcoin" |
177 | 5 | } |
178 | | const STORAGE_PREFIX: &'static str = "Transfers"; |
179 | | } |
180 | | #[allow(type_alias_bounds)] |
181 | | type OldTransfers<T: Config> = frame_support::storage::types::StorageMap< |
182 | | OldTransfersInstance, |
183 | | Identity, |
184 | | TransferId<T::Hash>, |
185 | | OldTransfer<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, |
186 | | >; |
187 | | |
188 | | generate_storage_alias!( |
189 | | Creditcoin, |
190 | | Addresses<T: Config> => Map<(Blake2_128Concat, AddressId<T::Hash>), Address<T::AccountId>> |
191 | | ); |
192 | | |
193 | | generate_storage_alias!( |
194 | | Creditcoin, |
195 | | AskOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), AskOrder<T::AccountId, T::BlockNumber, T::Hash>> |
196 | | ); |
197 | | |
198 | | generate_storage_alias!( |
199 | | Creditcoin, |
200 | | BidOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), BidOrder<T::AccountId, T::BlockNumber, T::Hash>> |
201 | | ); |
202 | | |
203 | | generate_storage_alias!( |
204 | | Creditcoin, |
205 | | DealOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), DealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>> |
206 | | ); |
207 | | |
208 | | generate_storage_alias!( |
209 | | Creditcoin, |
210 | | PendingTasks<T: Config> => DoubleMap<(Identity, T::BlockNumber), (Identity, TaskId<T::Hash>), Task<T::AccountId, T::BlockNumber, T::Hash, T::Moment>> |
211 | | ); |
212 | | |
213 | 7 | pub(crate) fn migrate<T: Config>() -> Weight { |
214 | 7 | let mut weight: Weight = 0; |
215 | 7 | let weight_each = T::DbWeight::get().reads_writes(1, 1); |
216 | 7 | let write = T::DbWeight::get().writes(1); |
217 | 7 | let read = T::DbWeight::get().reads(1); |
218 | 7 | |
219 | 7 | let mut reconstructed_currency_ask = BTreeMap::new(); |
220 | 7 | let mut reconstructed_currency_bid = BTreeMap::new(); |
221 | 7 | let mut currencies = BTreeSet::new(); |
222 | 7 | |
223 | 7 | DealOrders::<T>::translate::<OldDealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, _>( |
224 | 7 | |_exp, _hash, deal_order| { |
225 | 4 | weight = weight.saturating_add(weight_each); |
226 | 4 | |
227 | 4 | let currency = reconstruct_currency_from_deal::<T>(&deal_order); |
228 | 4 | let currency_id = if let Some(currency2 ) = currency.as_ref() { |
229 | 2 | currency.to_id::<T>() |
230 | | } else { |
231 | 2 | CurrencyId::placeholder() |
232 | | }; |
233 | | |
234 | 4 | weight = weight.saturating_add(read); |
235 | 4 | let offer = if let Some(offer) = crate::Offers::<T>::get( |
236 | 4 | deal_order.offer_id.expiration(), |
237 | 4 | deal_order.offer_id.hash(), |
238 | 4 | ) { |
239 | 4 | offer |
240 | | } else { |
241 | 0 | log::warn!("deal order has a non-existent offer: {:?}", deal_order.offer_id); |
242 | 0 | return None; |
243 | | }; |
244 | | |
245 | 4 | if let Some(currency2 ) = currency { |
246 | 2 | reconstructed_currency_ask.insert(offer.ask_id, currency_id.clone()); |
247 | 2 | reconstructed_currency_bid.insert(offer.bid_id, currency_id.clone()); |
248 | 2 | currencies.insert((currency_id.clone(), currency)); |
249 | 2 | } |
250 | | |
251 | 4 | Some(DealOrder { |
252 | 4 | offer_id: deal_order.offer_id, |
253 | 4 | lender_address_id: deal_order.lender_address_id, |
254 | 4 | borrower_address_id: deal_order.borrower_address_id, |
255 | 4 | terms: translate_loan_terms::<T>(deal_order.terms, currency_id), |
256 | 4 | expiration_block: deal_order.expiration_block, |
257 | 4 | timestamp: deal_order.timestamp, |
258 | 4 | block: deal_order.block, |
259 | 4 | funding_transfer_id: deal_order.funding_transfer_id, |
260 | 4 | repayment_transfer_id: deal_order.repayment_transfer_id, |
261 | 4 | lock: deal_order.lock, |
262 | 4 | borrower: deal_order.borrower, |
263 | 4 | }) |
264 | 7 | }, |
265 | 7 | ); |
266 | 7 | |
267 | 7 | AskOrders::<T>::translate::<OldAskOrder<T::AccountId, T::BlockNumber, T::Hash>, _>( |
268 | 7 | |exp, hash, ask_order| { |
269 | 2 | weight = weight.saturating_add(weight_each); |
270 | 2 | let ask_id = AskOrderId::with_expiration_hash::<T>(exp, hash); |
271 | 2 | let currency = reconstructed_currency_ask |
272 | 2 | .remove(&ask_id) |
273 | 2 | .unwrap_or_else(CurrencyId::placeholder); |
274 | 2 | Some(AskOrder { |
275 | 2 | lender_address_id: ask_order.lender_address_id, |
276 | 2 | terms: AskTerms::try_from(translate_loan_terms::<T>( |
277 | 2 | ask_order.terms.0, |
278 | 2 | currency, |
279 | 2 | )).expect("terms are checked for validity on creation so they must be valid on an existing ask order; qed"), |
280 | 2 | expiration_block: ask_order.expiration_block, |
281 | 2 | block: ask_order.block, |
282 | 2 | lender: ask_order.lender, |
283 | 2 | }) |
284 | 7 | }, |
285 | 7 | ); |
286 | 7 | |
287 | 7 | BidOrders::<T>::translate::<OldBidOrder<T::AccountId, T::BlockNumber, T::Hash>, _>( |
288 | 7 | |exp, hash, bid_order| { |
289 | 2 | weight = weight.saturating_add(weight_each); |
290 | 2 | let bid_id = BidOrderId::with_expiration_hash::<T>(exp, hash); |
291 | 2 | let currency = reconstructed_currency_bid |
292 | 2 | .remove(&bid_id) |
293 | 2 | .unwrap_or_else(CurrencyId::placeholder); |
294 | 2 | Some(BidOrder { |
295 | 2 | borrower_address_id: bid_order.borrower_address_id, |
296 | 2 | terms: BidTerms::try_from(translate_loan_terms::<T>(bid_order.terms.0, currency)).expect("terms are checked on creation so they must be valid on existing bid order; qed"), |
297 | 2 | expiration_block: bid_order.expiration_block, |
298 | 2 | block: bid_order.block, |
299 | 2 | borrower: bid_order.borrower, |
300 | 2 | }) |
301 | 7 | }, |
302 | 7 | ); |
303 | 7 | |
304 | 7 | Transfers::<T>::translate::<OldTransfer<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, _>( |
305 | 7 | |_id, transfer| { |
306 | 3 | weight = weight.saturating_add(weight_each); |
307 | 3 | translate_transfer::<T>(transfer) |
308 | 7 | }, |
309 | 7 | ); |
310 | 7 | |
311 | 7 | PendingTasks::<T>::translate::<OldTask<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, _>( |
312 | 7 | |_exp, _id, task| { |
313 | 1 | weight = weight.saturating_add(weight_each); |
314 | 1 | Some(match task { |
315 | 0 | OldTask::VerifyTransfer(unverified_transfer) => { |
316 | 0 | let kind = unverified_transfer.transfer.kind.clone(); |
317 | 0 | Task::VerifyTransfer(UnverifiedTransfer { |
318 | 0 | transfer: translate_transfer::<T>(unverified_transfer.transfer)?, |
319 | 0 | from_external: unverified_transfer.from_external, |
320 | 0 | to_external: unverified_transfer.to_external, |
321 | 0 | deadline: unverified_transfer.deadline, |
322 | 0 | currency_to_check: crate::CurrencyOrLegacyTransferKind::TransferKind( |
323 | 0 | to_legacy_transfer_kind(kind), |
324 | 0 | ), |
325 | | }) |
326 | | }, |
327 | 1 | OldTask::CollectCoins(collect_coins) => { |
328 | 1 | Task::CollectCoins(UnverifiedCollectedCoins { |
329 | 1 | to: collect_coins.to, |
330 | 1 | tx_id: collect_coins.tx_id, |
331 | 1 | contract: Default::default(), |
332 | 1 | }) |
333 | | }, |
334 | | }) |
335 | 7 | }, |
336 | 7 | ); |
337 | 7 | |
338 | 13 | Addresses::<T>::translate::<OldAddress<T::AccountId>, _>(|_id, address| { |
339 | 13 | weight = weight.saturating_add(weight_each); |
340 | 13 | Some(Address { |
341 | 13 | blockchain: translate_blockchain(address.blockchain)?0 , |
342 | 13 | value: address.value, |
343 | 13 | owner: address.owner, |
344 | | }) |
345 | 7 | }); |
346 | | |
347 | 9 | for (currency_id, currency2 ) in currencies { |
348 | 2 | weight = weight.saturating_add(write); |
349 | 2 | crate::Currencies::<T>::insert(currency_id, currency); |
350 | 2 | } |
351 | | |
352 | 7 | weight |
353 | 7 | } |
354 | | |
355 | | #[cfg(test)] |
356 | | mod tests { |
357 | | use super::*; |
358 | | use crate::{ |
359 | | concatenate, |
360 | | helpers::HexToAddress, |
361 | | mock::{ExtBuilder, Test}, |
362 | | tests::{IntoBounded, TestInfo}, |
363 | | Duration, InterestRate, |
364 | | }; |
365 | | use frame_support::Blake2_128Concat; |
366 | | use sp_runtime::traits::Hash as _; |
367 | | |
368 | | generate_storage_alias!( |
369 | | Creditcoin, |
370 | | Addresses<T: Config> => Map<(Blake2_128Concat, AddressId<T::Hash>), super::OldAddress<T::AccountId>> |
371 | | ); |
372 | | |
373 | | type OldAddresses = Addresses<Test>; |
374 | | |
375 | | generate_storage_alias!( |
376 | | Creditcoin, |
377 | | DealOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), super::OldDealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>> |
378 | | ); |
379 | | |
380 | | type OldDealOrders = DealOrders<Test>; |
381 | | |
382 | | generate_storage_alias!( |
383 | | Creditcoin, |
384 | | AskOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), super::OldAskOrder<T::AccountId, T::BlockNumber, T::Hash>> |
385 | | ); |
386 | | |
387 | | type OldAskOrders = AskOrders<Test>; |
388 | | |
389 | | generate_storage_alias!( |
390 | | Creditcoin, |
391 | | BidOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), super::OldBidOrder<T::AccountId, T::BlockNumber, T::Hash>> |
392 | | ); |
393 | | |
394 | | type OldBidOrders = BidOrders<Test>; |
395 | | |
396 | | generate_storage_alias!( |
397 | | Creditcoin, |
398 | | PendingTasks<T: Config> => DoubleMap<(Identity, T::BlockNumber), (Identity, TaskId<T::Hash>), super::OldTask<T::AccountId, T::BlockNumber, T::Hash, T::Moment>> |
399 | | ); |
400 | | |
401 | | type OldPendingTasks = PendingTasks<Test>; |
402 | | |
403 | | type OldTransfers = super::OldTransfers<Test>; |
404 | | |
405 | 10 | fn hash(val: &[u8]) -> <Test as frame_system::Config>::Hash { |
406 | 10 | <Test as frame_system::Config>::Hashing::hash(val) |
407 | 10 | } |
408 | | |
409 | | type AccountId = <Test as frame_system::Config>::AccountId; |
410 | | type BlockNumber = <Test as frame_system::Config>::BlockNumber; |
411 | | type Hash = <Test as frame_system::Config>::Hash; |
412 | | type Moment = <Test as pallet_timestamp::Config>::Moment; |
413 | | |
414 | | type DealOrderId = crate::DealOrderId<BlockNumber, Hash>; |
415 | | type AskOrderId = crate::AskOrderId<BlockNumber, Hash>; |
416 | | type BidOrderId = crate::BidOrderId<BlockNumber, Hash>; |
417 | | type OfferId = crate::OfferId<BlockNumber, Hash>; |
418 | | |
419 | | type OldDealOrder = super::OldDealOrder<AccountId, BlockNumber, Hash, Moment>; |
420 | | type OldAskOrder = super::OldAskOrder<AccountId, BlockNumber, Hash>; |
421 | | type OldBidOrder = super::OldBidOrder<AccountId, BlockNumber, Hash>; |
422 | | type OldTransfer = super::OldTransfer<AccountId, BlockNumber, Hash, Moment>; |
423 | | type Offer = crate::Offer<AccountId, BlockNumber, Hash>; |
424 | | |
425 | 3 | fn old_transfer( |
426 | 3 | test_info: &TestInfo, |
427 | 3 | deal_id: DealOrderId, |
428 | 3 | kind: OldTransferKind, |
429 | 3 | ) -> (TransferId<Hash>, OldTransfer) { |
430 | 3 | let blockchain = OldBlockchain::Rinkeby; |
431 | 3 | let transfer = OldTransfer { |
432 | 3 | blockchain: blockchain.clone(), |
433 | 3 | kind, |
434 | 3 | from: test_info.lender.address_id.clone(), |
435 | 3 | to: test_info.borrower.address_id.clone(), |
436 | 3 | order_id: OldOrderId::Deal(deal_id), |
437 | 3 | amount: 1.into(), |
438 | 3 | tx_id: "0xdeadbeef".hex_to_address(), |
439 | 3 | block: 50, |
440 | 3 | is_processed: false, |
441 | 3 | account_id: test_info.lender.account_id.clone(), |
442 | 3 | timestamp: Some(10000), |
443 | 3 | }; |
444 | 3 | |
445 | 3 | let transfer_id = crate::TransferId::make({ |
446 | 3 | let key = concatenate!(blockchain.as_bytes(), &*transfer.tx_id); |
447 | 3 | hash(&key) |
448 | 3 | }); |
449 | 3 | |
450 | 3 | (transfer_id, transfer) |
451 | 3 | } |
452 | | |
453 | 2 | fn attach_transfer(transfer_id: TransferId<Hash>, deal: &mut OldDealOrder) { |
454 | 2 | deal.funding_transfer_id = Some(transfer_id); |
455 | 2 | } |
456 | | |
457 | 2 | fn old_ask_bid_offer( |
458 | 2 | test_info: &TestInfo, |
459 | 2 | ) -> ((AskOrderId, OldAskOrder), (BidOrderId, OldBidOrder), (OfferId, Offer)) { |
460 | 2 | let expiration = 10000; |
461 | 2 | let ask = OldAskOrder { |
462 | 2 | blockchain: OldBlockchain::Rinkeby, |
463 | 2 | lender_address_id: test_info.lender.address_id.clone(), |
464 | 2 | terms: OldAskTerms(old_loan_terms()), |
465 | 2 | expiration_block: expiration, |
466 | 2 | block: 10, |
467 | 2 | lender: test_info.lender.account_id.clone(), |
468 | 2 | }; |
469 | 2 | |
470 | 2 | let bid = OldBidOrder { |
471 | 2 | blockchain: OldBlockchain::Rinkeby, |
472 | 2 | borrower_address_id: test_info.borrower.address_id.clone(), |
473 | 2 | terms: OldBidTerms(old_loan_terms()), |
474 | 2 | expiration_block: expiration, |
475 | 2 | block: 11, |
476 | 2 | borrower: test_info.borrower.account_id.clone(), |
477 | 2 | }; |
478 | 2 | |
479 | 2 | let ask_id = AskOrderId::new::<Test>(expiration, &[1, 1, 1, 1]); |
480 | 2 | let bid_id = BidOrderId::new::<Test>(expiration, &[2, 2, 2, 2]); |
481 | 2 | |
482 | 2 | let offer = Offer { |
483 | 2 | ask_id: ask_id.clone(), |
484 | 2 | bid_id: bid_id.clone(), |
485 | 2 | expiration_block: expiration, |
486 | 2 | block: 12, |
487 | 2 | lender: test_info.lender.account_id.clone(), |
488 | 2 | }; |
489 | 2 | let offer_id = OfferId::new::<Test>(expiration, &ask_id, &bid_id); |
490 | 2 | |
491 | 2 | ((ask_id, ask), (bid_id, bid), (offer_id, offer)) |
492 | 2 | } |
493 | | |
494 | 9 | fn old_loan_terms() -> OldLoanTerms { |
495 | 9 | OldLoanTerms { |
496 | 9 | amount: 100u64.into(), |
497 | 9 | interest_rate: InterestRate { |
498 | 9 | rate_per_period: 100, |
499 | 9 | decimals: 4, |
500 | 9 | period: Duration::from_millis(2000), |
501 | 9 | interest_type: crate::InterestType::Simple, |
502 | 9 | }, |
503 | 9 | term_length: Duration::from_millis(10000), |
504 | 9 | } |
505 | 9 | } |
506 | | |
507 | 5 | fn old_deal_order( |
508 | 5 | test_info: &TestInfo, |
509 | 5 | offer: Option<(Offer, OfferId)>, |
510 | 5 | ) -> (DealOrderId, OldDealOrder) { |
511 | 5 | let (offer_id, _offer) = match offer { |
512 | 2 | Some((off, id)) => (id, off), |
513 | 3 | None => test_info.create_offer(), |
514 | | }; |
515 | 5 | let expiration_block = 10000; |
516 | 5 | |
517 | 5 | let deal_id = DealOrderId::with_expiration_hash::<Test>( |
518 | 5 | expiration_block, |
519 | 5 | hash(offer_id.hash().as_ref()), |
520 | 5 | ); |
521 | 5 | let blockchain = OldBlockchain::Rinkeby; |
522 | 5 | |
523 | 5 | ( |
524 | 5 | deal_id, |
525 | 5 | OldDealOrder { |
526 | 5 | blockchain, |
527 | 5 | offer_id, |
528 | 5 | lender_address_id: test_info.lender.address_id.clone(), |
529 | 5 | borrower_address_id: test_info.borrower.address_id.clone(), |
530 | 5 | terms: old_loan_terms(), |
531 | 5 | expiration_block, |
532 | 5 | timestamp: 100000, |
533 | 5 | block: Some(100), |
534 | 5 | funding_transfer_id: None, |
535 | 5 | repayment_transfer_id: None, |
536 | 5 | lock: None, |
537 | 5 | borrower: test_info.borrower.account_id.clone(), |
538 | 5 | }, |
539 | 5 | ) |
540 | 5 | } |
541 | | |
542 | 6 | fn old_to_new_terms(terms: OldLoanTerms, currency: Option<Currency>) -> super::LoanTerms<Hash> { |
543 | 6 | super::LoanTerms { |
544 | 6 | amount: terms.amount, |
545 | 6 | interest_rate: terms.interest_rate, |
546 | 6 | term_length: terms.term_length, |
547 | 6 | currency: currency.map_or_else(CurrencyId::placeholder, |c| c.to_id::<Test>()3 ), |
548 | 6 | } |
549 | 6 | } |
550 | | |
551 | 2 | fn old_to_new_deal( |
552 | 2 | deal: OldDealOrder, |
553 | 2 | currency: Option<Currency>, |
554 | 2 | ) -> super::DealOrder<AccountId, BlockNumber, Hash, Moment> { |
555 | 2 | super::DealOrder { |
556 | 2 | offer_id: deal.offer_id, |
557 | 2 | lender_address_id: deal.lender_address_id, |
558 | 2 | borrower_address_id: deal.borrower_address_id, |
559 | 2 | terms: old_to_new_terms(deal.terms, currency), |
560 | 2 | expiration_block: deal.expiration_block, |
561 | 2 | timestamp: deal.timestamp, |
562 | 2 | block: deal.block, |
563 | 2 | funding_transfer_id: deal.funding_transfer_id, |
564 | 2 | repayment_transfer_id: deal.repayment_transfer_id, |
565 | 2 | lock: deal.lock, |
566 | 2 | borrower: deal.borrower, |
567 | 2 | } |
568 | 2 | } |
569 | | |
570 | 2 | fn old_to_new_ask( |
571 | 2 | ask: OldAskOrder, |
572 | 2 | currency: Option<Currency>, |
573 | 2 | ) -> super::AskOrder<AccountId, BlockNumber, Hash> { |
574 | 2 | super::AskOrder { |
575 | 2 | lender_address_id: ask.lender_address_id, |
576 | 2 | terms: crate::AskTerms::try_from(old_to_new_terms(ask.terms.0, currency)).unwrap(), |
577 | 2 | expiration_block: ask.expiration_block, |
578 | 2 | block: ask.block, |
579 | 2 | lender: ask.lender, |
580 | 2 | } |
581 | 2 | } |
582 | | |
583 | 2 | fn old_to_new_bid( |
584 | 2 | bid: OldBidOrder, |
585 | 2 | currency: Option<Currency>, |
586 | 2 | ) -> super::BidOrder<AccountId, BlockNumber, Hash> { |
587 | 2 | super::BidOrder { |
588 | 2 | borrower_address_id: bid.borrower_address_id, |
589 | 2 | terms: crate::BidTerms::try_from(old_to_new_terms(bid.terms.0, currency)).unwrap(), |
590 | 2 | expiration_block: bid.expiration_block, |
591 | 2 | block: bid.block, |
592 | 2 | borrower: bid.borrower, |
593 | 2 | } |
594 | 2 | } |
595 | | |
596 | 2 | fn ethless_currency(contract: &str) -> Currency { |
597 | 2 | Currency::Evm( |
598 | 2 | EvmCurrencyType::SmartContract( |
599 | 2 | contract.hex_to_address(), |
600 | 2 | vec![EvmTransferKind::Ethless].into_bounded(), |
601 | 2 | ), |
602 | 2 | EvmInfo::RINKEBY, |
603 | 2 | ) |
604 | 2 | } |
605 | | |
606 | 4 | fn insert_deal(id: &DealOrderId, deal: &OldDealOrder) { |
607 | 4 | OldDealOrders::insert(id.expiration(), id.hash(), deal); |
608 | 4 | } |
609 | | |
610 | 3 | fn insert_transfer(id: &TransferId<Hash>, transfer: &OldTransfer) { |
611 | 3 | OldTransfers::insert(id, transfer); |
612 | 3 | } |
613 | | |
614 | | const CONTRACT: &str = "0xaaaa"; |
615 | | |
616 | 1 | #[test] |
617 | 1 | fn deal_order_with_transfer_migrates() { |
618 | 1 | ExtBuilder::default().build_and_execute(|| { |
619 | 1 | let test_info = TestInfo::new_defaults(); |
620 | 1 | |
621 | 1 | let (deal_id, mut deal) = old_deal_order(&test_info, None); |
622 | 1 | |
623 | 1 | let (transfer_id, transfer) = old_transfer( |
624 | 1 | &test_info, |
625 | 1 | deal_id.clone(), |
626 | 1 | OldTransferKind::Ethless(CONTRACT.hex_to_address()), |
627 | 1 | ); |
628 | 1 | insert_transfer(&transfer_id, &transfer); |
629 | 1 | |
630 | 1 | attach_transfer(transfer_id, &mut deal); |
631 | 1 | insert_deal(&deal_id, &deal); |
632 | 1 | |
633 | 1 | migrate::<Test>(); |
634 | 1 | |
635 | 1 | let migrated_deal = |
636 | 1 | super::DealOrders::<Test>::get(deal_id.expiration(), deal_id.hash()).unwrap(); |
637 | 1 | |
638 | 1 | assert_eq!(migrated_deal, old_to_new_deal(deal, Some(ethless_currency(CONTRACT)))); |
639 | 1 | }); |
640 | 1 | } |
641 | | |
642 | 1 | #[test] |
643 | 1 | fn deal_order_without_transfer_migrates() { |
644 | 1 | ExtBuilder::default().build_and_execute(|| { |
645 | 1 | let test_info = TestInfo::default(); |
646 | 1 | |
647 | 1 | let (deal_id, deal) = old_deal_order(&test_info, None); |
648 | 1 | insert_deal(&deal_id, &deal); |
649 | 1 | |
650 | 1 | migrate::<Test>(); |
651 | 1 | |
652 | 1 | let migrated_deal = |
653 | 1 | super::DealOrders::<Test>::get(deal_id.expiration(), deal_id.hash()).unwrap(); |
654 | 1 | |
655 | 1 | assert_eq!(migrated_deal, old_to_new_deal(deal, None)); |
656 | 1 | }); |
657 | 1 | } |
658 | | |
659 | 1 | #[test] |
660 | 1 | fn transfer_migrates() { |
661 | 1 | ExtBuilder::default().build_and_execute(|| { |
662 | 1 | let test_info = TestInfo::default(); |
663 | 1 | |
664 | 1 | let (deal_id, _) = old_deal_order(&test_info, None); |
665 | 1 | let (transfer_id, transfer) = old_transfer( |
666 | 1 | &test_info, |
667 | 1 | deal_id.clone(), |
668 | 1 | OldTransferKind::Ethless(CONTRACT.hex_to_address()), |
669 | 1 | ); |
670 | 1 | |
671 | 1 | insert_transfer(&transfer_id, &transfer); |
672 | 1 | |
673 | 1 | migrate::<Test>(); |
674 | 1 | |
675 | 1 | let migrated_transfer = super::Transfers::<Test>::get(&transfer_id).unwrap(); |
676 | 1 | |
677 | 1 | assert_eq!( |
678 | 1 | migrated_transfer, |
679 | 1 | super::Transfer { |
680 | 1 | blockchain: super::Blockchain::RINKEBY, |
681 | 1 | kind: super::TransferKind::Evm(EvmTransferKind::Ethless), |
682 | 1 | from: test_info.lender.address_id, |
683 | 1 | to: test_info.borrower.address_id, |
684 | 1 | deal_order_id: deal_id, |
685 | 1 | amount: transfer.amount, |
686 | 1 | tx_id: transfer.tx_id, |
687 | 1 | block: transfer.block, |
688 | 1 | is_processed: transfer.is_processed, |
689 | 1 | account_id: transfer.account_id, |
690 | 1 | timestamp: transfer.timestamp |
691 | 1 | } |
692 | 1 | ) |
693 | 1 | }) |
694 | 1 | } |
695 | | |
696 | 1 | #[test] |
697 | 1 | fn address_migrates() { |
698 | 1 | ExtBuilder::default().build_and_execute(|| { |
699 | 1 | let test_info = TestInfo::default(); |
700 | 1 | |
701 | 1 | let old_address = OldAddress { |
702 | 1 | blockchain: OldBlockchain::Rinkeby, |
703 | 1 | owner: test_info.lender.account_id, |
704 | 1 | value: "0xaaaabbbbccccdddd".hex_to_address(), |
705 | 1 | }; |
706 | 1 | let address_id = super::AddressId::make(hash(&concatenate!( |
707 | 1 | old_address.blockchain.as_bytes(), |
708 | 1 | &*old_address.value |
709 | 1 | ))); |
710 | 1 | |
711 | 1 | OldAddresses::insert(&address_id, &old_address); |
712 | 1 | |
713 | 1 | migrate::<Test>(); |
714 | 1 | |
715 | 1 | let migrated_address = super::Addresses::<Test>::get(&address_id).unwrap(); |
716 | 1 | |
717 | 1 | assert_eq!( |
718 | 1 | migrated_address, |
719 | 1 | super::Address { |
720 | 1 | blockchain: super::Blockchain::RINKEBY, |
721 | 1 | value: old_address.value, |
722 | 1 | owner: old_address.owner |
723 | 1 | } |
724 | 1 | ); |
725 | 1 | }); |
726 | 1 | } |
727 | | |
728 | 1 | #[test] |
729 | 1 | fn ask_bid_orders_with_transfer_migrate() { |
730 | 1 | ExtBuilder::default().build_and_execute(|| { |
731 | 1 | let test_info = TestInfo::default(); |
732 | 1 | |
733 | 1 | let ((ask_id, ask), (bid_id, bid), (offer_id, offer)) = old_ask_bid_offer(&test_info); |
734 | 1 | |
735 | 1 | OldAskOrders::insert(ask_id.expiration(), ask_id.hash(), &ask); |
736 | 1 | OldBidOrders::insert(bid_id.expiration(), bid_id.hash(), &bid); |
737 | 1 | crate::Offers::<Test>::insert(offer_id.expiration(), offer_id.hash(), &offer); |
738 | 1 | |
739 | 1 | let (deal_id, mut deal) = old_deal_order(&test_info, Some((offer, offer_id))); |
740 | 1 | |
741 | 1 | let (transfer_id, transfer) = old_transfer( |
742 | 1 | &test_info, |
743 | 1 | deal_id.clone(), |
744 | 1 | OldTransferKind::Ethless(CONTRACT.hex_to_address()), |
745 | 1 | ); |
746 | 1 | |
747 | 1 | insert_transfer(&transfer_id, &transfer); |
748 | 1 | attach_transfer(transfer_id, &mut deal); |
749 | 1 | |
750 | 1 | insert_deal(&deal_id, &deal); |
751 | 1 | |
752 | 1 | migrate::<Test>(); |
753 | 1 | |
754 | 1 | let migrated_ask = |
755 | 1 | super::AskOrders::<Test>::get(ask_id.expiration(), ask_id.hash()).unwrap(); |
756 | 1 | |
757 | 1 | let migrated_bid = |
758 | 1 | super::BidOrders::<Test>::get(bid_id.expiration(), bid_id.hash()).unwrap(); |
759 | 1 | |
760 | 1 | let currency = ethless_currency(CONTRACT); |
761 | 1 | |
762 | 1 | assert_eq!(migrated_ask, old_to_new_ask(ask, Some(currency.clone()))); |
763 | | |
764 | 1 | assert_eq!(migrated_bid, old_to_new_bid(bid, Some(currency))); |
765 | 1 | }); |
766 | 1 | } |
767 | | |
768 | 1 | #[test] |
769 | 1 | fn ask_bid_orders_without_transfer_migrate() { |
770 | 1 | ExtBuilder::default().build_and_execute(|| { |
771 | 1 | let test_info = TestInfo::default(); |
772 | 1 | |
773 | 1 | let ((ask_id, ask), (bid_id, bid), (offer_id, offer)) = old_ask_bid_offer(&test_info); |
774 | 1 | |
775 | 1 | OldAskOrders::insert(ask_id.expiration(), ask_id.hash(), &ask); |
776 | 1 | OldBidOrders::insert(bid_id.expiration(), bid_id.hash(), &bid); |
777 | 1 | crate::Offers::<Test>::insert(offer_id.expiration(), offer_id.hash(), &offer); |
778 | 1 | |
779 | 1 | let (deal_id, deal) = old_deal_order(&test_info, Some((offer, offer_id))); |
780 | 1 | |
781 | 1 | insert_deal(&deal_id, &deal); |
782 | 1 | |
783 | 1 | migrate::<Test>(); |
784 | 1 | |
785 | 1 | let migrated_ask = |
786 | 1 | super::AskOrders::<Test>::get(ask_id.expiration(), ask_id.hash()).unwrap(); |
787 | 1 | |
788 | 1 | let migrated_bid = |
789 | 1 | super::BidOrders::<Test>::get(bid_id.expiration(), bid_id.hash()).unwrap(); |
790 | 1 | |
791 | 1 | assert_eq!(migrated_ask, old_to_new_ask(ask, None)); |
792 | | |
793 | 1 | assert_eq!(migrated_bid, old_to_new_bid(bid, None)); |
794 | 1 | }); |
795 | 1 | } |
796 | | |
797 | 1 | #[test] |
798 | 1 | fn unverified_collected_coins_migrates() { |
799 | 1 | ExtBuilder::default().build_and_execute(|| { |
800 | 1 | let tx_id = "0xfafafafafafafa".hex_to_address(); |
801 | 1 | |
802 | 1 | let old_collect_coins = OldUnverifiedCollectedCoins { |
803 | 1 | to: b"baba".to_vec().try_into().unwrap(), |
804 | 1 | tx_id: tx_id.clone(), |
805 | 1 | }; |
806 | 1 | |
807 | 1 | let deadline = 100; |
808 | 1 | |
809 | 1 | let id = TaskId::from(crate::CollectedCoinsId::make(hash(&tx_id))); |
810 | 1 | |
811 | 1 | let new_collect_coins = UnverifiedCollectedCoins { |
812 | 1 | to: b"baba".to_vec().try_into().unwrap(), |
813 | 1 | tx_id, |
814 | 1 | contract: Default::default(), |
815 | 1 | }; |
816 | 1 | |
817 | 1 | OldPendingTasks::insert(deadline, &id, OldTask::from(old_collect_coins)); |
818 | 1 | |
819 | 1 | migrate::<Test>(); |
820 | 1 | |
821 | 1 | assert_eq!( |
822 | 1 | super::PendingTasks::<Test>::get(deadline, &id).unwrap(), |
823 | 1 | Task::CollectCoins(new_collect_coins) |
824 | 1 | ); |
825 | 1 | }); |
826 | 1 | } |
827 | | } |