@@ -46,16 +46,15 @@ uint256 HashBeaconPayload(const BeaconPayload& payload)
46
46
// !
47
47
bool TryRenewal (BeaconRegistry::BeaconMap& beacons,
48
48
BeaconRegistry::HistoricalBeaconMap& historical_beacons,
49
- const BeaconPayload& payload,
50
- const uint256& ctx_hash)
49
+ const BeaconPayload& payload)
51
50
{
52
51
auto beacon_pair_iter = beacons.find (payload.m_cpid );
53
52
54
53
if (beacon_pair_iter == beacons.end ()) {
55
54
return false ;
56
55
}
57
56
58
- Beacon& current_beacon = beacon_pair_iter->second ;
57
+ Beacon& current_beacon = * beacon_pair_iter->second ;
59
58
60
59
if (current_beacon.Expired (payload.m_beacon .m_timestamp )) {
61
60
return false ;
@@ -65,12 +64,15 @@ bool TryRenewal(BeaconRegistry::BeaconMap& beacons,
65
64
return false ;
66
65
}
67
66
68
- // Insert current beacon into historical map.
69
- historical_beacons.emplace (std::make_pair (ctx_hash , current_beacon));
67
+ // Insert copy of current beacon into historical map.
68
+ historical_beacons.emplace (std::make_pair (current_beacon. m_ctx_hash , current_beacon));
70
69
71
- // Update current beacon record.
70
+ // Set the previous transaction hash to the current.
71
+ current_beacon.m_prev_beacon_ctx_hash = current_beacon.m_ctx_hash ;
72
+ // Update current beacon record timestamp to the incoming payload transaction hash.
72
73
current_beacon.m_timestamp = payload.m_beacon .m_timestamp ;
73
- current_beacon.m_prev_beacon_txn_hash = ctx_hash;
74
+ // Update the current transaction hash to the incoming payload transaction hash.
75
+ current_beacon.m_ctx_hash = payload.m_beacon .m_ctx_hash ;
74
76
75
77
return true ;
76
78
}
@@ -89,19 +91,20 @@ BeaconRegistry& GRC::GetBeaconRegistry()
89
91
// Class: Beacon
90
92
// -----------------------------------------------------------------------------
91
93
92
- Beacon::Beacon () : m_public_key(), m_timestamp(0 )
94
+ Beacon::Beacon () : m_public_key(), m_timestamp(0 ), m_ctx_hash()
93
95
{
94
96
}
95
97
96
98
Beacon::Beacon (CPubKey public_key)
97
- : Beacon(std::move(public_key), 0)
99
+ : Beacon(std::move(public_key), 0, uint256 {} )
98
100
{
99
101
}
100
102
101
- Beacon::Beacon (CPubKey public_key, int64_t timestamp)
103
+ Beacon::Beacon (CPubKey public_key, int64_t timestamp, uint256 hash )
102
104
: m_public_key(std::move(public_key))
103
- , m_timestamp(timestamp)
104
- , m_prev_beacon_txn_hash()
105
+ , m_timestamp(timestamp),
106
+ m_ctx_hash(hash)
107
+ , m_prev_beacon_ctx_hash()
105
108
{
106
109
}
107
110
@@ -169,7 +172,7 @@ bool Beacon::Renewable(const int64_t now) const
169
172
bool Beacon::Renewed () const
170
173
{
171
174
// If not empty, the beacon was a renewal.
172
- return (m_prev_beacon_txn_hash != uint256 ());
175
+ return (m_prev_beacon_ctx_hash != uint256 ());
173
176
}
174
177
175
178
CKeyID Beacon::GetId () const
@@ -304,7 +307,7 @@ BeaconOption BeaconRegistry::Try(const Cpid& cpid) const
304
307
return nullptr ;
305
308
}
306
309
307
- return & iter->second ;
310
+ return iter->second ;
308
311
}
309
312
310
313
BeaconOption BeaconRegistry::TryActive (const Cpid& cpid, const int64_t now) const
@@ -363,18 +366,21 @@ void BeaconRegistry::Add(const ContractContext& ctx)
363
366
{
364
367
BeaconPayload payload = ctx->CopyPayloadAs <BeaconPayload>();
365
368
payload.m_beacon .m_timestamp = ctx.m_tx .nTime ;
369
+ payload.m_beacon .m_ctx_hash = ctx.m_tx .GetHash ();
370
+ payload.m_beacon .m_prev_beacon_ctx_hash = uint256 {};
366
371
367
372
// Legacy beacon contracts before block version 11--just load the beacon:
368
373
//
369
374
if (ctx->m_version == 1 ) {
370
- m_beacons[payload.m_cpid ] = std::move (payload.m_beacon );
375
+ m_historical[ctx.m_tx .GetHash ()] = std::move (payload.m_beacon );
376
+ m_beacons[payload.m_cpid ] = std::make_shared<Beacon>(m_historical[ctx.m_tx .GetHash ()]);
371
377
return ;
372
378
}
373
379
374
380
// For beacon renewals, check that the new beacon contains the same public
375
381
// key. If it matches, we don't need to verify it again:
376
382
//
377
- if (TryRenewal (m_beacons, m_historical, payload, ctx. m_tx . GetHash () )) {
383
+ if (TryRenewal (m_beacons, m_historical, payload)) {
378
384
return ;
379
385
}
380
386
@@ -384,6 +390,8 @@ void BeaconRegistry::Add(const ContractContext& ctx)
384
390
PendingBeacon pending (payload.m_cpid , std::move (payload.m_beacon ));
385
391
386
392
m_pending.emplace (pending.GetId (), std::move (pending));
393
+
394
+ // Note that pending beacons do not get added to the historical map.
387
395
}
388
396
389
397
void BeaconRegistry::Delete (const ContractContext& ctx)
@@ -395,6 +403,7 @@ void BeaconRegistry::Delete(const ContractContext& ctx)
395
403
}
396
404
397
405
m_beacons.erase (payload->m_cpid );
406
+ m_historical.erase (ctx.m_tx .GetHash ());
398
407
}
399
408
400
409
bool BeaconRegistry::Validate (const Contract& contract, const CTransaction& tx) const
@@ -466,15 +475,18 @@ void BeaconRegistry::ActivatePending(
466
475
const std::vector<uint160>& beacon_ids,
467
476
const int64_t superblock_time)
468
477
{
478
+ // Activate the pending beacons that are not expired with respect to pending age.
469
479
for (const auto & id : beacon_ids) {
470
480
auto iter_pair = m_pending.find (id);
471
481
472
482
if (iter_pair != m_pending.end ()) {
473
- m_beacons[iter_pair->second .m_cpid ] = std::move (iter_pair->second );
483
+ m_historical.emplace (std::make_pair (iter_pair->second .m_ctx_hash , iter_pair->second ));
484
+ m_beacons[iter_pair->second .m_cpid ] = std::make_shared<Beacon>(m_historical[iter_pair->second .m_ctx_hash ]);
474
485
m_pending.erase (iter_pair);
475
486
}
476
487
}
477
488
489
+ // Discard pending beacons that are expired with respect to pending age.
478
490
for (auto iter = m_pending.begin (); iter != m_pending.end (); /* no-op */ ) {
479
491
if (iter->second .Expired (superblock_time)) {
480
492
iter = m_pending.erase (iter);
@@ -487,10 +499,10 @@ void BeaconRegistry::ActivatePending(
487
499
void BeaconRegistry::Deactivate (const int64_t superblock_time)
488
500
{
489
501
for (auto iter = m_beacons.begin (); iter != m_beacons.end (); /* no-op */ ) {
490
- if (iter->second . m_timestamp >= superblock_time) {
491
- PendingBeacon pending (iter->first , std::move ( iter->second ) );
502
+ if (iter->second -> m_timestamp >= superblock_time) {
503
+ PendingBeacon pending (iter->first , * iter->second );
492
504
m_pending.emplace (pending.GetId (), std::move (pending));
493
-
505
+ m_historical. erase (iter-> second -> m_ctx_hash );
494
506
iter = m_beacons.erase (iter);
495
507
} else {
496
508
++iter;
0 commit comments