2
2
// Distributed under the MIT/X11 software license, see the accompanying
3
3
// file COPYING or https://opensource.org/licenses/mit-license.php.
4
4
5
+ #include " gridcoin/claim.h"
5
6
#include " main.h"
7
+ #include " node/blockstorage.h"
8
+ #include " gridcoin/support/block_finder.h"
6
9
#include " gridcoin/project.h"
10
+ #include " gridcoin/quorum.h"
7
11
#include " node/ui_interface.h"
8
12
9
13
#include < algorithm>
@@ -296,6 +300,140 @@ WhitelistSnapshot WhitelistSnapshot::Sorted() const
296
300
return WhitelistSnapshot (std::make_shared<ProjectList>(sorted), m_filter);
297
301
}
298
302
303
+ // -----------------------------------------------------------------------------
304
+ // Class: AutoGreylist - automatic greylisting
305
+ // -----------------------------------------------------------------------------
306
+
307
+ AutoGreylist::AutoGreylist ()
308
+ : m_greylist_ptr(std::make_shared<Greylist>())
309
+ , m_superblock_hash(uint256 {})
310
+ {
311
+ // m_greylist_ptr = std::make_shared<Greylist>();
312
+
313
+ Refresh ();
314
+ }
315
+
316
+ AutoGreylist::Greylist::const_iterator AutoGreylist::begin () const
317
+ {
318
+ return m_greylist_ptr->begin ();
319
+ }
320
+
321
+ AutoGreylist::Greylist::const_iterator AutoGreylist::end () const
322
+ {
323
+ return m_greylist_ptr->end ();
324
+ }
325
+
326
+ AutoGreylist::Greylist::size_type AutoGreylist::size () const
327
+ {
328
+ return m_greylist_ptr->size ();
329
+ }
330
+
331
+ void AutoGreylist::Refresh ()
332
+ {
333
+ LOCK (cs_main);
334
+
335
+ // If the current superblock has not changed, then no need to do anything.
336
+ if (!m_superblock_hash.IsNull () && Quorum::CurrentSuperblock ()->GetHash () == m_superblock_hash) {
337
+ return ;
338
+ }
339
+
340
+ SuperblockPtr superblock_ptr = Quorum::CurrentSuperblock ();
341
+
342
+ if (!superblock_ptr.IsEmpty ()) {
343
+ RefreshWithSuperblock (superblock_ptr);
344
+ }
345
+ }
346
+
347
+ void AutoGreylist::RefreshWithSuperblock (SuperblockPtr superblock_ptr_in)
348
+ {
349
+ LOCK (lock);
350
+
351
+ // We need the current whitelist, including all records except deleted. This will include greylisted projects,
352
+ // whether currently marked as manually greylisted from protocol or overridden to auto greylisted by the auto greylist class.
353
+ const WhitelistSnapshot whitelist = GetWhitelist ().Snapshot (GRC::ProjectEntry::ProjectFilterFlag::ALL_BUT_DELETED);
354
+
355
+ m_greylist_ptr->clear ();
356
+
357
+ for (const auto & iter : whitelist) {
358
+ if (auto project = superblock_ptr_in->m_projects .Try (iter.m_name )) {
359
+ // Record new greylist candidate entry baseline with the total credit for each project present in superblock.
360
+ m_greylist_ptr->insert (std::make_pair (iter.m_name , GreylistCandidateEntry (iter.m_name , project->m_total_credit )));
361
+ } else {
362
+ // Record new greylist candidate entry with nullopt total credit. This is for a project that is in the whitelist,
363
+ // but does not have a project entry in the superblock. This would be because the scrapers could not converge on the
364
+ // project.
365
+ m_greylist_ptr->insert (std::make_pair (iter.m_name , GreylistCandidateEntry (iter.m_name ,
366
+ std::optional<uint64_t >(std::nullopt))));
367
+ }
368
+ }
369
+
370
+ CBlockIndex* index_ptr;
371
+ {
372
+ // Find the block index entry for the block before the provided superblock_ptr.
373
+ index_ptr = GRC::BlockFinder::FindByHeight (superblock_ptr_in.m_height - 1 );
374
+ }
375
+
376
+ // SuperblockPtr superblock_ptr;
377
+ unsigned int superblock_count = 1 ; // The 0 (baseline) superblock was processed above. Here we start with 1 and go up to 40
378
+
379
+ while (index_ptr != nullptr && index_ptr->pprev != nullptr && superblock_count <= 40 ) {
380
+
381
+ if (!index_ptr->IsSuperblock ()) {
382
+ index_ptr = index_ptr->pprev ;
383
+ continue ;
384
+ }
385
+
386
+ // For some reason this is not working.
387
+ // superblock_ptr.ReadFromDisk(index_ptr);
388
+
389
+ CBlock block;
390
+ if (!ReadBlockFromDisk (block, index_ptr, Params ().GetConsensus ())) {
391
+ error (" %s: Failed to read block from disk with requested height %u" ,
392
+ __func__,
393
+ index_ptr->nHeight );
394
+ continue ;
395
+ }
396
+
397
+ SuperblockPtr superblock_ptr = block.GetClaim ().m_superblock ;
398
+
399
+ for (const auto & iter : whitelist) {
400
+ // This is guaranteed to succeed, because every whitelisted project was inserted as a new baseline entry above.
401
+ auto greylist_entry = m_greylist_ptr->find (iter.m_name );
402
+
403
+ if (auto project = superblock_ptr->m_projects .Try (iter.m_name )) {
404
+ // Update greylist candidate entry with the total credit for each project present in superblock.
405
+ greylist_entry->second .UpdateGreylistCandidateEntry (project->m_total_credit , superblock_count);
406
+ } else {
407
+ // Record updated greylist candidate entry with nullopt total credit. This is for a project that is in the whitelist,
408
+ // but does not have a project entry in this superblock. This would be because the scrapers could not converge on the
409
+ // project for this superblock.
410
+ greylist_entry->second .UpdateGreylistCandidateEntry (std::optional<uint64_t >(std::nullopt), superblock_count);
411
+ }
412
+ }
413
+
414
+ ++superblock_count;
415
+ index_ptr = index_ptr->pprev ;
416
+ }
417
+
418
+ // Purge candidate elements that do not meet auto greylist criteria.
419
+ for (auto iter = m_greylist_ptr->begin (); iter != m_greylist_ptr->end (); ) {
420
+ if (iter->second .GetZCD () < 7 && iter->second .GetWAS () >= Fraction (1 , 10 )) {
421
+ // Candidate greylist entry does not meet auto greylist criteria, so remove from greylist entry map.
422
+ iter = m_greylist_ptr->erase (iter);
423
+ } else {
424
+ iter++;
425
+ }
426
+ }
427
+ }
428
+
429
+ // This is the global cached (singleton) for the auto greylist.
430
+ std::shared_ptr<AutoGreylist> g_autogreylist_ptr = std::make_shared<AutoGreylist>();
431
+
432
+ std::shared_ptr<AutoGreylist> AutoGreylist::GetAutoGreylistCache ()
433
+ {
434
+ return g_autogreylist_ptr;
435
+ }
436
+
299
437
// -----------------------------------------------------------------------------
300
438
// Class: Whitelist (Registry)
301
439
// -----------------------------------------------------------------------------
@@ -304,6 +442,8 @@ WhitelistSnapshot Whitelist::Snapshot(const ProjectEntry::ProjectFilterFlag& fil
304
442
{
305
443
LOCK (cs_lock);
306
444
445
+ // AutoGreylist::GetAutoGreylistCache()->Refresh();
446
+
307
447
ProjectList projects;
308
448
309
449
for (const auto & iter : m_project_entries) {
0 commit comments