@@ -23,30 +23,34 @@ const std::string testwif("Usr24VoC3h4cSfSrFiGJkWLYwmkM1VnsBiMyWZvrF6QR5ZQ6Fbuu"
23
23
const std::string testpk (" 034b082c5819b5bf8798a387630ad236a8e800dbce4c4e24a46f36dfddab3cbff5" );
24
24
const std::string testaddr (" RXTUtWXgkepi8f2ohWLL9KhtGKRjBV48hT" );
25
25
26
- const uint256 testPrevHash = uint256S(" 01f1fde483c591ae81bee34f3dfc26ca4d6f061bc4ca15806ae15e07befedce9" );
27
-
28
- // Fake the input of transaction testPrevHash/0
26
+ // Fake the input of transaction mtx0/0
29
27
class FakeCoinsViewDB2 : public CCoinsView { // change name to FakeCoinsViewDB2 to avoid name conflict with same class name in different files (seems a bug in macos gcc)
30
28
public:
31
- FakeCoinsViewDB2 () {}
29
+ FakeCoinsViewDB2 () {
30
+ // allowed mtx0 txids
31
+ sAllowedTxIn .insert (uint256S (" 01f1fde483c591ae81bee34f3dfc26ca4d6f061bc4ca15806ae15e07befedce9" )); // 1 * COIN , nLockTime = 0
32
+ sAllowedTxIn .insert (uint256S (" c8ff545cdc5e921cdbbd24555a462340fc1092e09977944ec687c5bf3ef9c30b" )); // 10 * COIN, nLockTime = 0
33
+ sAllowedTxIn .insert (uint256S (" 529d8dcec041465fdf6c1f873ef1055eec106db5f02ae222814d3764bb8e6660" )); // 10 * COIN, nLockTime = 1663755146
34
+ sAllowedTxIn .insert (uint256S (" 3533600e69a22776afb765305a0ec46bcb06e1942f36a113d73733190092f9d5" )); // 10 * COIN, nLockTime = 1663755147
35
+ }
32
36
33
37
bool GetCoins (const uint256 &txid, CCoins &coins) const {
34
- if (txid == testPrevHash) {
38
+ if (sAllowedTxIn . count ( txid)) {
35
39
CTxOut txOut;
36
- txOut.nValue = COIN;
40
+ txOut.nValue = 10 * COIN;
37
41
txOut.scriptPubKey = GetScriptForDestination (DecodeDestination (testaddr));
38
42
CCoins newCoins;
39
43
newCoins.vout .resize (1 );
40
44
newCoins.vout [0 ] = txOut;
41
- newCoins.nHeight = komodo_interest_height-1 ;
45
+ newCoins.nHeight = komodo_interest_height-1 ; /* TODO: return correct nHeight depends on txid */
42
46
coins.swap (newCoins);
43
47
return true ;
44
48
}
45
49
return false ;
46
50
}
47
51
48
52
bool HaveCoins (const uint256 &txid) const {
49
- if (txid == testPrevHash)
53
+ if (sAllowedTxIn . count ( txid))
50
54
return true ;
51
55
return false ;
52
56
}
@@ -72,6 +76,7 @@ class FakeCoinsViewDB2 : public CCoinsView { // change name to FakeCoinsViewDB2
72
76
}
73
77
74
78
uint256 bestBlockHash;
79
+ std::set<uint256> sAllowedTxIn ;
75
80
};
76
81
77
82
bool TestSignTx (const CKeyStore& keystore, CMutableTransaction& mtx, int32_t vini, CAmount utxovalue, const CScript scriptPubKey)
@@ -119,7 +124,8 @@ TEST_F(KomodoFeatures, komodo_interest_validate) {
119
124
// Add a fake transaction to the wallet
120
125
CMutableTransaction mtx0 = CreateNewContextualCMutableTransaction (Params ().GetConsensus (), komodo_interest_height-1 );
121
126
CScript scriptPubKey = GetScriptForDestination (DecodeDestination (testaddr));
122
- mtx0.vout .push_back (CTxOut (COIN, scriptPubKey));
127
+ mtx0.vout .push_back (CTxOut (10 * COIN, scriptPubKey));
128
+ mtx0.nLockTime = 1663755146 ;
123
129
124
130
// Fake-mine the transaction
125
131
ASSERT_EQ (-1 , chainActive.Height ());
@@ -137,20 +143,20 @@ TEST_F(KomodoFeatures, komodo_interest_validate) {
137
143
EXPECT_TRUE (chainActive.Contains (pfakeIndex));
138
144
EXPECT_EQ (komodo_interest_height-1 , chainActive.Height ());
139
145
140
- // std::cerr << " mtx0.GetHash()=" << mtx0.GetHash().GetHex() << std::endl;
141
- EXPECT_EQ (mtx0.GetHash (), testPrevHash);
142
-
143
146
FakeCoinsViewDB2 fakedb;
144
147
fakedb.bestBlockHash = blockHash;
145
148
CCoinsViewCache fakeview (&fakedb);
146
149
pcoinsTip = &fakeview;
147
150
151
+ // std::cerr << " mtx0.GetHash()=" << mtx0.GetHash().GetHex() << std::endl;
152
+ EXPECT_NE (fakedb.sAllowedTxIn .count (mtx0.GetHash ()), 0 );
153
+
148
154
CTxMemPool pool (::minRelayTxFee);
149
155
bool missingInputs;
150
156
CMutableTransaction mtxSpend = CreateNewContextualCMutableTransaction (Params ().GetConsensus (), komodo_interest_height);
151
157
mtxSpend.vin .push_back (CTxIn (mtx0.GetHash (), 0 ));
152
158
CScript scriptPubKey1 = GetScriptForDestination (DecodeDestination (testaddr));
153
- mtxSpend.vout .push_back (CTxOut (COIN, scriptPubKey1));
159
+ mtxSpend.vout .push_back (CTxOut (10 * COIN, scriptPubKey1));
154
160
155
161
CBasicKeyStore tempKeystore;
156
162
CKey key = DecodeSecret (testwif);
@@ -213,7 +219,6 @@ TEST_F(KomodoFeatures, komodo_interest_validate) {
213
219
214
220
{
215
221
// check valid interest in block
216
-
217
222
mtxSpend.nLockTime = chainActive.Tip ()->GetMedianTimePast () - 3600 ; // not too long time in mempool
218
223
mtxSpend.vin [0 ].scriptSig .clear ();
219
224
EXPECT_TRUE (TestSignTx (tempKeystore, mtxSpend, 0 , mtx0.vout [0 ].nValue , mtx0.vout [0 ].scriptPubKey ));
@@ -227,6 +232,102 @@ TEST_F(KomodoFeatures, komodo_interest_validate) {
227
232
CValidationState state1;
228
233
EXPECT_TRUE (ContextualCheckBlock (false , block, state1, pfakeIndex));
229
234
}
235
+
236
+ {
237
+ // test interest calculations via CCoinsViewCache::GetValueIn
238
+
239
+ const uint32_t tipTimes[] = {
240
+ 1663755146 ,
241
+ 1663762346 , // chainActive.Tip()->GetMedianTimePast() + 2 * 3600 (MTP from 1663755146 + 2 * 3600)
242
+ 1663762346 + 31 * 24 * 60 * 60 , /* month */
243
+ 1663762346 + 6 * 30 * 24 * 60 * 60 , /* half of a year */
244
+ 1663762346 + 12 * 30 * 24 * 60 * 60 , /* year (360 days) */
245
+ 1663762346 + 365 * 24 * 60 * 60 , /* year (365 days) */
246
+ };
247
+
248
+ /* komodo_interest_height = 247205+1 */
249
+ const CAmount interestCollectedBefore250k[] = {0 , 11415 , 4545454 , 25000000 , 50000000 , 50000000 };
250
+ /* komodo_interest_height = 333332 */
251
+ const CAmount interestCollectedBefore1M[] = {0 , 5802 , 4252378 , 24663337 , 49320871 , 49994387 };
252
+ /* komodo_interest_height = 3000000 */
253
+ const CAmount interestCollected[] = {0 , 5795 , 4235195 , 4235195 , 4235195 , 4235195 };
254
+
255
+ /* check collected interest */
256
+
257
+ const size_t nMaxTipTimes = sizeof (tipTimes) / sizeof (tipTimes[0 ]);
258
+ const size_t nMaxInterestCollected = sizeof (interestCollected) / sizeof (interestCollected[0 ]);
259
+ assert (nMaxTipTimes == nMaxInterestCollected);
260
+
261
+ const int testHeights[] = {
262
+ 247205 + 1 , 333332 , 3000000 };
263
+
264
+ CValidationState state;
265
+
266
+ for (size_t idx_ht = 0 ; idx_ht < sizeof (testHeights) / sizeof (testHeights[0 ]); ++idx_ht)
267
+ {
268
+
269
+ pfakeIndex->nHeight = testHeights[idx_ht] - 1 ;
270
+ mtx0.nLockTime = 1663755146 ;
271
+ mtxSpend.vin [0 ] = CTxIn (mtx0.GetHash (), 0 );
272
+
273
+ for (size_t idx = 0 ; idx < nMaxTipTimes; ++idx)
274
+ {
275
+ // make fake last block
276
+ CBlock lastBlock;
277
+ lastBlock.nTime = tipTimes[idx];
278
+
279
+ CBlockIndex *pLastBlockIndex = new CBlockIndex (block);
280
+ pLastBlockIndex->pprev = pfakeIndex;
281
+ pLastBlockIndex->nHeight = testHeights[idx_ht];
282
+ pLastBlockIndex->nTime = lastBlock.nTime ;
283
+ chainActive.SetTip (pLastBlockIndex);
284
+
285
+ mtxSpend.nLockTime = lastBlock.nTime ;
286
+ mtxSpend.vin [0 ].scriptSig .clear ();
287
+ EXPECT_TRUE (TestSignTx (tempKeystore, mtxSpend, 0 , mtx0.vout [0 ].nValue , mtx0.vout [0 ].scriptPubKey ));
288
+ CTransaction tx1 (mtxSpend);
289
+
290
+ mempool.clear ();
291
+ mapBlockIndex.clear ();
292
+
293
+ // put tx which we trying to spend into mempool,
294
+ // bcz CCoinsViewCache::GetValueIn will call komodo_accrued_interest
295
+ // -> komodo_interest_args -> GetTransaction
296
+
297
+ auto consensusBranchId = CurrentEpochBranchId (chainActive.Height () + 1 , Params ().GetConsensus ());
298
+ SetMockTime (mtxSpend.nLockTime );
299
+ CTxMemPoolEntry entry (mtx0, 0 , GetTime (), 0 , chainActive.Height (), mempool.HasNoInputsOf (mtx0), false , consensusBranchId);
300
+ mempool.addUnchecked (mtx0.GetHash (), entry, false );
301
+
302
+ EXPECT_TRUE (mempool.exists (mtx0.GetHash ()));
303
+
304
+ // force komodo_getblockindex in komodo_interest_args return a value
305
+ uint256 zero;
306
+ zero.SetNull ();
307
+ mapBlockIndex.insert (std::make_pair (zero, pfakeIndex));
308
+
309
+ fakeview.GetBestBlock (); // bring the best block into scope
310
+ EXPECT_EQ (chainActive.Tip ()->nHeight , testHeights[idx_ht]);
311
+ CAmount interest = 0 ;
312
+ CAmount nValueIn = fakeview.GetValueIn (chainActive.Tip ()->nHeight , interest, tx1);
313
+
314
+ switch (testHeights[idx_ht])
315
+ {
316
+ case 247205 + 1 :
317
+ ASSERT_EQ (interest, interestCollectedBefore250k[idx]);
318
+ break ;
319
+ case 333332 :
320
+ ASSERT_EQ (interest, interestCollectedBefore1M[idx]);
321
+ break ;
322
+ default :
323
+ ASSERT_EQ (interest, interestCollected[idx]);
324
+ break ;
325
+ }
326
+
327
+ delete pLastBlockIndex;
328
+ }
329
+ }
330
+ }
230
331
}
231
332
232
333
// check komodo_interestnew calculations
@@ -365,4 +466,4 @@ TEST_F(KomodoFeatures, komodo_interest) {
365
466
}
366
467
}
367
468
}
368
- }
469
+ }
0 commit comments