Coverage Report

Created: 2022-11-10 19:56

/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
}