@@ -46,16 +46,15 @@ uint256 HashBeaconPayload(const BeaconPayload& payload)
4646// !
4747bool TryRenewal (BeaconRegistry::BeaconMap& beacons,
4848 BeaconRegistry::HistoricalBeaconMap& historical_beacons,
49- const BeaconPayload& payload,
50- const uint256& ctx_hash)
49+ const BeaconPayload& payload)
5150{
5251 auto beacon_pair_iter = beacons.find (payload.m_cpid );
5352
5453 if (beacon_pair_iter == beacons.end ()) {
5554 return false ;
5655 }
5756
58- Beacon& current_beacon = beacon_pair_iter->second ;
57+ Beacon& current_beacon = * beacon_pair_iter->second ;
5958
6059 if (current_beacon.Expired (payload.m_beacon .m_timestamp )) {
6160 return false ;
@@ -65,12 +64,15 @@ bool TryRenewal(BeaconRegistry::BeaconMap& beacons,
6564 return false ;
6665 }
6766
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));
7069
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.
7273 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 ;
7476
7577 return true ;
7678}
@@ -89,19 +91,20 @@ BeaconRegistry& GRC::GetBeaconRegistry()
8991// Class: Beacon
9092// -----------------------------------------------------------------------------
9193
92- Beacon::Beacon () : m_public_key(), m_timestamp(0 )
94+ Beacon::Beacon () : m_public_key(), m_timestamp(0 ), m_ctx_hash()
9395{
9496}
9597
9698Beacon::Beacon (CPubKey public_key)
97- : Beacon(std::move(public_key), 0)
99+ : Beacon(std::move(public_key), 0, uint256 {} )
98100{
99101}
100102
101- Beacon::Beacon (CPubKey public_key, int64_t timestamp)
103+ Beacon::Beacon (CPubKey public_key, int64_t timestamp, uint256 hash )
102104 : 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()
105108{
106109}
107110
@@ -169,7 +172,7 @@ bool Beacon::Renewable(const int64_t now) const
169172bool Beacon::Renewed () const
170173{
171174 // If not empty, the beacon was a renewal.
172- return (m_prev_beacon_txn_hash != uint256 ());
175+ return (m_prev_beacon_ctx_hash != uint256 ());
173176}
174177
175178CKeyID Beacon::GetId () const
@@ -304,7 +307,7 @@ BeaconOption BeaconRegistry::Try(const Cpid& cpid) const
304307 return nullptr ;
305308 }
306309
307- return & iter->second ;
310+ return iter->second ;
308311}
309312
310313BeaconOption BeaconRegistry::TryActive (const Cpid& cpid, const int64_t now) const
@@ -363,18 +366,21 @@ void BeaconRegistry::Add(const ContractContext& ctx)
363366{
364367 BeaconPayload payload = ctx->CopyPayloadAs <BeaconPayload>();
365368 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 {};
366371
367372 // Legacy beacon contracts before block version 11--just load the beacon:
368373 //
369374 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 ()]);
371377 return ;
372378 }
373379
374380 // For beacon renewals, check that the new beacon contains the same public
375381 // key. If it matches, we don't need to verify it again:
376382 //
377- if (TryRenewal (m_beacons, m_historical, payload, ctx. m_tx . GetHash () )) {
383+ if (TryRenewal (m_beacons, m_historical, payload)) {
378384 return ;
379385 }
380386
@@ -384,6 +390,8 @@ void BeaconRegistry::Add(const ContractContext& ctx)
384390 PendingBeacon pending (payload.m_cpid , std::move (payload.m_beacon ));
385391
386392 m_pending.emplace (pending.GetId (), std::move (pending));
393+
394+ // Note that pending beacons do not get added to the historical map.
387395}
388396
389397void BeaconRegistry::Delete (const ContractContext& ctx)
@@ -395,6 +403,7 @@ void BeaconRegistry::Delete(const ContractContext& ctx)
395403 }
396404
397405 m_beacons.erase (payload->m_cpid );
406+ m_historical.erase (ctx.m_tx .GetHash ());
398407}
399408
400409bool BeaconRegistry::Validate (const Contract& contract, const CTransaction& tx) const
@@ -466,15 +475,18 @@ void BeaconRegistry::ActivatePending(
466475 const std::vector<uint160>& beacon_ids,
467476 const int64_t superblock_time)
468477{
478+ // Activate the pending beacons that are not expired with respect to pending age.
469479 for (const auto & id : beacon_ids) {
470480 auto iter_pair = m_pending.find (id);
471481
472482 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 ]);
474485 m_pending.erase (iter_pair);
475486 }
476487 }
477488
489+ // Discard pending beacons that are expired with respect to pending age.
478490 for (auto iter = m_pending.begin (); iter != m_pending.end (); /* no-op */ ) {
479491 if (iter->second .Expired (superblock_time)) {
480492 iter = m_pending.erase (iter);
@@ -487,10 +499,10 @@ void BeaconRegistry::ActivatePending(
487499void BeaconRegistry::Deactivate (const int64_t superblock_time)
488500{
489501 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 );
492504 m_pending.emplace (pending.GetId (), std::move (pending));
493-
505+ m_historical. erase (iter-> second -> m_ctx_hash );
494506 iter = m_beacons.erase (iter);
495507 } else {
496508 ++iter;
0 commit comments