Coverage Report

Created: 2022-11-10 19:56

/home/runner/work/creditcoin/creditcoin/pallets/creditcoin/src/migrations/v2.rs
Line
Count
Source (jump to first uncovered line)
1
// `block` added to `DealOrder` and `timestamp` added to `Transfer`
2
3
use crate::ExternalAddress;
4
use crate::{AddressId, Config, DealOrderId, ExternalAmount, ExternalTxId, OfferId, TransferId};
5
use frame_support::{
6
  generate_storage_alias, pallet_prelude::*, Identity, RuntimeDebug, Twox64Concat,
7
};
8
9
pub use super::v1::Blockchain;
10
pub use super::v1::DealOrder as OldDealOrder;
11
pub use super::v1::LoanTerms;
12
pub use super::v1::{AskOrder, AskTerms, BidOrder, BidTerms, InterestRate};
13
14
type OtherTransferKindLen = ConstU32<256>;
15
pub type OtherTransferKind = BoundedVec<u8, OtherTransferKindLen>;
16
17
9
#[derive(
E7
ncod
e7
, Decode,
R0
untimeDebu
g0
,
C0
lon
e0
)]
18
2
#[cfg_attr(test, derive(PartialEq, Eq))]
19
pub enum TransferKind {
20
  Erc20(ExternalAddress),
21
  Ethless(ExternalAddress),
22
  Native,
23
  Other(OtherTransferKind),
24
}
25
26
0
#[derive(Encode, Decode, RuntimeDebug)]
27
0
#[cfg_attr(test, derive(PartialEq, Eq, Clone))]
28
pub struct RepaymentOrderId<BlockNum, Hash>(BlockNum, Hash);
29
30
9
#[derive(
E7
ncod
e7
, Decode)]
31
2
#[cfg_attr(test, derive(
D0
ebu
g0
, PartialEq, Eq,
C0
lon
e0
))]
32
pub enum OrderId<BlockNum, Hash> {
33
  Deal(DealOrderId<BlockNum, Hash>),
34
  Repayment(RepaymentOrderId<BlockNum, Hash>),
35
}
36
37
8
#[derive(
Encode6
, Decode)]
38
2
#[cfg_attr(test, derive(
Debug0
, PartialEq, Eq,
Clone0
))]
39
pub struct Transfer<AccountId, BlockNum, Hash, Moment> {
40
  pub blockchain: Blockchain,
41
  pub kind: TransferKind,
42
  pub from: AddressId<Hash>,
43
  pub to: AddressId<Hash>,
44
  pub order_id: OrderId<BlockNum, Hash>,
45
  pub amount: ExternalAmount,
46
  pub tx_id: ExternalTxId,
47
  pub block: BlockNum,
48
  pub is_processed: bool,
49
  pub account_id: AccountId,
50
  pub timestamp: Option<Moment>,
51
}
52
1
#[derive(Encode, Decode)]
53
struct OldTransfer<AccountId, BlockNum, Hash> {
54
  blockchain: Blockchain,
55
  kind: TransferKind,
56
  from: AddressId<Hash>,
57
  to: AddressId<Hash>,
58
  order_id: OrderId<BlockNum, Hash>,
59
  amount: ExternalAmount,
60
  tx: ExternalTxId,
61
  block: BlockNum,
62
  processed: bool,
63
  sighash: AccountId,
64
}
65
66
2
#[derive(Encode, Decode)]
67
1
#[cfg_attr(test, derive(
Debug0
, PartialEq, Eq))]
68
pub struct DealOrder<AccountId, BlockNum, Hash, Moment> {
69
  pub blockchain: Blockchain,
70
  pub offer_id: OfferId<BlockNum, Hash>,
71
  pub lender_address_id: AddressId<Hash>,
72
  pub borrower_address_id: AddressId<Hash>,
73
  pub terms: LoanTerms,
74
  pub expiration_block: BlockNum,
75
  pub timestamp: Moment,
76
  pub block: Option<BlockNum>,
77
  pub funding_transfer_id: Option<TransferId<Hash>>,
78
  pub repayment_transfer_id: Option<TransferId<Hash>>,
79
  pub lock: Option<AccountId>,
80
  pub borrower: AccountId,
81
}
82
83
generate_storage_alias!(
84
  Creditcoin,
85
  DealOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), DealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>>
86
);
87
88
generate_storage_alias!(
89
  Creditcoin,
90
  Transfers<T: Config> => Map<(Identity, TransferId<T::Hash>), Transfer<T::AccountId, T::BlockNumber, T::Hash, T::Moment>>
91
);
92
93
2
pub(crate) fn migrate<T: Config>() -> Weight {
94
2
  let mut weight: Weight = 0;
95
2
  let weight_each = T::DbWeight::get().reads_writes(1, 1);
96
2
97
2
  DealOrders::<T>::translate::<OldDealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>, _>(
98
2
    |_exp, _hash, deal| {
99
1
      weight = weight.saturating_add(weight_each);
100
1
      Some(DealOrder {
101
1
        blockchain: deal.blockchain,
102
1
        offer_id: deal.offer_id,
103
1
        lender_address_id: deal.lender_address_id,
104
1
        borrower_address_id: deal.borrower_address_id,
105
1
        terms: deal.terms,
106
1
        expiration_block: deal.expiration_block,
107
1
        timestamp: deal.timestamp,
108
1
        funding_transfer_id: deal.funding_transfer_id,
109
1
        lock: deal.lock,
110
1
        borrower: deal.borrower,
111
1
        repayment_transfer_id: deal.repayment_transfer_id,
112
1
        block: None,
113
1
      })
114
2
    },
115
2
  );
116
2
117
2
  Transfers::<T>::translate::<OldTransfer<T::AccountId, T::BlockNumber, T::Hash>, _>(
118
2
    |_id, transfer| {
119
1
      weight = weight.saturating_add(weight_each);
120
1
      Some(Transfer {
121
1
        blockchain: transfer.blockchain,
122
1
        kind: transfer.kind,
123
1
        from: transfer.from,
124
1
        to: transfer.to,
125
1
        order_id: transfer.order_id,
126
1
        amount: transfer.amount,
127
1
        tx_id: transfer.tx,
128
1
        block: transfer.block,
129
1
        is_processed: transfer.processed,
130
1
        account_id: transfer.sighash,
131
1
        timestamp: None,
132
1
      })
133
2
    },
134
2
  );
135
2
136
2
  weight
137
2
}
138
139
#[cfg(test)]
140
mod test {
141
  use core::convert::TryInto;
142
143
  use super::{
144
    Blockchain, Config, DealOrder, Identity, OldDealOrder, OldTransfer, OrderId, Transfer,
145
    TransferKind, Twox64Concat,
146
  };
147
  use crate::{
148
    mock::{ExtBuilder, Test},
149
    tests::TestInfo,
150
    DealOrderId, DoubleMapExt, Duration, OfferId, TransferId,
151
  };
152
  use frame_support::generate_storage_alias;
153
  use sp_runtime::traits::Hash;
154
155
  impl<H> TransferId<H> {
156
2
    pub fn from_old_blockchain<Config>(
157
2
      blockchain: &Blockchain,
158
2
      blockchain_tx_id: &[u8],
159
2
    ) -> TransferId<H>
160
2
    where
161
2
      Config: frame_system::Config,
162
2
      <Config as frame_system::Config>::Hashing: Hash<Output = H>,
163
2
    {
164
2
      let key = crate::types::concatenate!(blockchain.as_bytes(), blockchain_tx_id);
165
2
      TransferId::make(Config::Hashing::hash(&key))
166
2
    }
167
  }
168
169
  generate_storage_alias!(
170
    Creditcoin,
171
    DealOrders<T: Config> => DoubleMap<(Twox64Concat, T::BlockNumber), (Identity, T::Hash), OldDealOrder<T::AccountId, T::BlockNumber, T::Hash, T::Moment>>
172
  );
173
174
  type OldDealOrders = DealOrders<Test>;
175
176
  generate_storage_alias!(
177
    Creditcoin,
178
    Transfers<T: Config> => Map<(Identity, TransferId<T::Hash>), OldTransfer<T::AccountId, T::BlockNumber, T::Hash>>
179
  );
180
181
  type OldTransfers = Transfers<Test>;
182
183
1
  #[test]
184
1
  fn deal_order_migrates() {
185
1
    ExtBuilder::default().build_and_execute(|| {
186
1
      let test_info = TestInfo::new_defaults();
187
1
188
1
      let deal_id = DealOrderId::with_expiration_hash::<Test>(100, [0u8; 32].into());
189
1
      let offer_id = OfferId::with_expiration_hash::<Test>(100, [1u8; 32].into());
190
1
191
1
      let old_deal = OldDealOrder {
192
1
        blockchain: Blockchain::Ethereum,
193
1
        offer_id,
194
1
        lender_address_id: test_info.lender.address_id,
195
1
        borrower_address_id: test_info.borrower.address_id,
196
1
        terms: super::LoanTerms {
197
1
          amount: 100u64.into(),
198
1
          interest_rate: super::super::v1::InterestRate {
199
1
            rate_per_period: 100,
200
1
            decimals: 4,
201
1
            period: Duration::from_millis(2000),
202
1
          },
203
1
          term_length: Duration::from_millis(10000),
204
1
        },
205
1
        expiration_block: 100,
206
1
        timestamp: 0,
207
1
        funding_transfer_id: None,
208
1
        repayment_transfer_id: None,
209
1
        lock: None,
210
1
        borrower: test_info.borrower.account_id,
211
1
      };
212
1
213
1
      OldDealOrders::insert_id(&deal_id, &old_deal);
214
1
215
1
      super::migrate::<Test>();
216
1
217
1
      let deal = super::DealOrders::<Test>::try_get_id(&deal_id).unwrap();
218
1
219
1
      assert_eq!(
220
1
        deal,
221
1
        DealOrder {
222
1
          blockchain: old_deal.blockchain,
223
1
          offer_id: old_deal.offer_id,
224
1
          lender_address_id: old_deal.lender_address_id,
225
1
          borrower_address_id: old_deal.borrower_address_id,
226
1
          terms: old_deal.terms,
227
1
          expiration_block: old_deal.expiration_block,
228
1
          timestamp: old_deal.timestamp,
229
1
          funding_transfer_id: old_deal.funding_transfer_id,
230
1
          repayment_transfer_id: old_deal.repayment_transfer_id,
231
1
          lock: old_deal.lock,
232
1
          borrower: old_deal.borrower,
233
1
          block: None,
234
1
        }
235
1
      );
236
1
    });
237
1
  }
238
239
1
  #[test]
240
1
  fn transfer_migrates() {
241
1
    ExtBuilder::default().build_and_execute(|| {
242
1
      let test_info = TestInfo::new_defaults();
243
1
      let blockchain = Blockchain::Ethereum;
244
1
      let transfer_id = TransferId::from_old_blockchain::<Test>(&blockchain, &[0]);
245
1
      let old_transfer = OldTransfer {
246
1
        blockchain: Blockchain::Ethereum,
247
1
        kind: TransferKind::Native,
248
1
        from: test_info.lender.address_id,
249
1
        to: test_info.borrower.address_id,
250
1
        order_id: OrderId::Deal(DealOrderId::dummy()),
251
1
        amount: 100u64.into(),
252
1
        tx: vec![0u8; 32].try_into().unwrap(),
253
1
        block: 1,
254
1
        processed: false,
255
1
        sighash: test_info.borrower.account_id,
256
1
      };
257
1
258
1
      OldTransfers::insert(&transfer_id, &old_transfer);
259
1
260
1
      super::migrate::<Test>();
261
1
262
1
      let transfer = super::Transfers::<Test>::try_get(&transfer_id).unwrap();
263
1
264
1
      assert_eq!(
265
1
        transfer,
266
1
        Transfer {
267
1
          blockchain: old_transfer.blockchain,
268
1
          kind: old_transfer.kind,
269
1
          from: old_transfer.from,
270
1
          to: old_transfer.to,
271
1
          order_id: old_transfer.order_id,
272
1
          amount: old_transfer.amount,
273
1
          tx_id: old_transfer.tx,
274
1
          block: old_transfer.block,
275
1
          is_processed: old_transfer.processed,
276
1
          account_id: old_transfer.sighash,
277
1
          timestamp: None,
278
1
        }
279
1
      );
280
1
    });
281
1
  }
282
}