@@ -800,127 +800,100 @@ int BeaconRegistry::GetDBHeight()
800
800
Beacon_ptr BeaconRegistry::GetBeaconChainletRoot (Beacon_ptr beacon,
801
801
std::shared_ptr<std::vector<std::pair<uint256, int64_t >>> beacon_chain_out)
802
802
{
803
- Cpid cpid = beacon->m_cpid ;
804
-
805
- // The chain head itself.
806
- auto beacon_iter = m_beacon_db.find (beacon->m_hash );
807
-
808
- if (beacon_iter == m_beacon_db.end ()) {
809
- // Beacon chainlet chainhead cannot be found. This is fatal.
810
-
811
- error (" %s: Beacon chainlet is corrupted at chainhead for cpid %s: timestamp = %s" PRId64 " , ctx_hash = %s,"
812
- " prev_beacon_ctx_hash = %s, status = %s: not found in the registry." ,
803
+ const auto ChainletErrorHandle = [this ](unsigned int i, Beacon_ptr beacon, std::string error_message) {
804
+ error (" %s: Beacon chainlet is corrupted at link %u for cpid %s: timestamp = %s" PRId64 " , ctx_hash = %s,"
805
+ " prev_beacon_ctx_hash = %s, status = %s: %s." ,
813
806
__func__,
807
+ i,
814
808
beacon->m_cpid .ToString (),
815
809
beacon->m_timestamp ,
816
810
beacon->m_hash .GetHex (),
817
811
beacon->m_previous_hash .GetHex (),
818
- beacon->StatusToString ());
812
+ beacon->StatusToString (),
813
+ error_message);
819
814
820
- std::string str_error = strprintf (" ERROR: %s: Beacon chainlet is corrupted at chainhead for cpid %s: timestamp = %s"
821
- PRId64 " , ctx_hash = %s, prev_beacon_ctx_hash = %s, status = %s: not found "
822
- " in the registry." ,
815
+ std::string str_error = strprintf (" ERROR: %s: Beacon chainlet is corrupted at link %u for cpid %s: timestamp = %s"
816
+ PRId64 " , ctx_hash = %s, prev_beacon_ctx_hash = %s, status = %s: %s." ,
823
817
__func__,
818
+ i,
824
819
beacon->m_cpid .ToString (),
825
820
beacon->m_timestamp ,
826
821
beacon->m_hash .GetHex (),
827
822
beacon->m_previous_hash .GetHex (),
828
- beacon->StatusToString ());
823
+ beacon->StatusToString (),
824
+ error_message);
829
825
830
826
Reset ();
831
827
832
828
uiInterface.ThreadSafeMessageBox (str_error, " Gridcoin" , CClientUIInterface::MSG_ERROR);
833
829
834
- throw std::runtime_error (std::string {" The beacon registry is corrupted and Gridcoin cannot continue. Please restart." });
835
- }
836
-
837
- // Given that we have had rare situations where somehow circularity has occurred in the beacon chainlet, which either
838
- // results in the current hash and previous hash being the same, or even suspected previous hash of another entry pointing
839
- // back to a beacon in a circular manner, this vector is used to detect the circularity.
840
- std::vector<uint256> encountered_hashes { beacon->m_hash };
830
+ throw std::runtime_error (std::string {" The beacon registry is corrupted and will be rebuilt on the next start. "
831
+ " Please restart." });
832
+ };
841
833
842
- if (beacon_chain_out != nullptr ) {
843
- LogPrint (BCLog::LogFlags::ACCRUAL, " INFO %s: chainlet head beacon for cpid %s: timestamp = %" PRId64 " , ctx_hash = %s,"
834
+ const auto ChainletLinkLog = [&beacon_chain_out]( unsigned int i, Beacon_ptr beacon ) {
835
+ LogPrint (BCLog::LogFlags::ACCRUAL, " INFO %s: beacon chainlet link %u for cpid %s: timestamp = %" PRId64 " , ctx_hash = %s,"
844
836
" prev_beacon_ctx_hash = %s, status = %s." ,
845
837
__func__,
838
+ i,
846
839
beacon->m_cpid .ToString (),
847
840
beacon->m_timestamp ,
848
841
beacon->m_hash .GetHex (),
849
842
beacon->m_previous_hash .GetHex (),
850
843
beacon->StatusToString ());
851
844
845
+ if (beacon_chain_out == nullptr ) {
846
+ return ;
847
+ }
848
+
852
849
beacon_chain_out->push_back (std::make_pair (beacon->m_hash , beacon->m_timestamp ));
850
+ };
851
+
852
+ unsigned int i = 0 ;
853
+
854
+ // Given that we have had rare situations where somehow circularity has occurred in the beacon chainlet, which either
855
+ // results in the current hash and previous hash being the same, or even suspected previous hash of another entry pointing
856
+ // back to a beacon in a circular manner, this vector is used to detect the circularity.
857
+ std::vector<uint256> encountered_hashes;
858
+
859
+ // The chain head itself. (This uses a scope to separate beacon_iter.)
860
+ {
861
+ auto beacon_iter = m_beacon_db.find (beacon->m_hash );
862
+
863
+ if (beacon_iter == m_beacon_db.end ()) {
864
+ // Beacon chainlet chainhead cannot be found. This is fatal.
865
+ ChainletErrorHandle (i, beacon, " not found in the registry" );
866
+ }
867
+
868
+ // Make sure status is renewed or active.
869
+ if (beacon_iter->second ->m_status != BeaconStatusForStorage::ACTIVE
870
+ && beacon_iter->second ->m_status != BeaconStatusForStorage::RENEWAL) {
871
+ ChainletErrorHandle (i, beacon, " beacon status is not active or renewal" );
872
+ }
873
+
874
+ encountered_hashes.push_back (beacon->m_hash );
875
+
876
+ ChainletLinkLog (i, beacon);
877
+
878
+ ++i;
853
879
}
854
880
855
881
// Walk back the entries in the historical beacon map linked by renewal prev tx hash until the first
856
882
// beacon in the renewal chain is found (the original advertisement). The accrual starts no earlier
857
883
// than here.
858
- unsigned int i = 0 ;
859
-
860
884
while (beacon->Renewed ())
861
885
{
862
886
// Select previous beacon in chainlet
863
887
auto beacon_iter = m_beacon_db.find (beacon->m_previous_hash );
864
888
865
889
if (beacon_iter == m_beacon_db.end ()) {
866
- // Linked beacon in chainlet cannot be found. This is fatal.
867
-
868
- error (" %s: Beacon chainlet is corrupted at %u links back for cpid %s: timestamp = %s" PRId64 " , ctx_hash = %s,"
869
- " prev_beacon_ctx_hash = %s, status = %s: prev_beacon not found in the registry." ,
870
- __func__,
871
- i + 1 ,
872
- beacon->m_cpid .ToString (),
873
- beacon->m_timestamp ,
874
- beacon->m_hash .GetHex (),
875
- beacon->m_previous_hash .GetHex (),
876
- beacon->StatusToString ());
877
-
878
- std::string str_error = strprintf (" ERROR: %s: Beacon chainlet is corrupted at %u links back for cpid %s: timestamp = %s"
879
- PRId64 " , ctx_hash = %s, prev_beacon_ctx_hash = %s, status = %s: prev_beacon not found "
880
- " in the registry." ,
881
- __func__,
882
- i + 1 ,
883
- beacon->m_cpid .ToString (),
884
- beacon->m_timestamp ,
885
- beacon->m_hash .GetHex (),
886
- beacon->m_previous_hash .GetHex (),
887
- beacon->StatusToString ());
888
-
889
- Reset ();
890
-
891
- uiInterface.ThreadSafeMessageBox (str_error, " Gridcoin" , CClientUIInterface::MSG_ERROR);
892
-
893
- throw std::runtime_error (std::string {" The beacon registry is corrupted and Gridcoin cannot continue. Please restart." });
890
+ ChainletErrorHandle (i, beacon, " previous beacon not found in the registry" );
894
891
}
895
892
896
893
if (std::find (encountered_hashes.begin (), encountered_hashes.end (), beacon->m_previous_hash ) != encountered_hashes.end ()) {
897
894
// If circularity is found this is an indication of corruption of beacon state and is fatal.
898
895
// Produce an error message, reset the beacon registry, and require a restart of the node.
899
-
900
- error (" %s: Circularity encountered in beacon ownership chain for beacon with CPID %s, starting at hash %s, "
901
- " at %u linked entries back from the start, with offending hash %s." ,
902
- __func__,
903
- cpid.ToString (),
904
- beacon->m_hash .GetHex (),
905
- i + 1 ,
906
- beacon->m_previous_hash .GetHex ());
907
-
908
- std::string str_error = strprintf (" ERROR: %s: Circularity encountered in beacon ownership chain for beacon with CPID %s, "
909
- " starting at hash %s, at %u linked entries back from the start, with offending hash %s.\n "
910
- " \n "
911
- " The client cannot continue and the beacon history has been reset and will be rebuilt "
912
- " on the next restart. Please restart Gridcoin." ,
913
- __func__,
914
- cpid.ToString (),
915
- beacon->m_hash .GetHex (),
916
- i + 1 ,
917
- beacon->m_previous_hash .GetHex ());
918
-
919
- Reset ();
920
-
921
- uiInterface.ThreadSafeMessageBox (str_error, " Gridcoin" , CClientUIInterface::MSG_ERROR);
922
-
923
- throw std::runtime_error (std::string {" The beacon registry is corrupted and Gridcoin cannot continue. Please restart." });
896
+ ChainletErrorHandle (i, beacon, " circularity encountered" );
924
897
}
925
898
926
899
// Reassign previous beacon to beacon.
@@ -929,51 +902,34 @@ Beacon_ptr BeaconRegistry::GetBeaconChainletRoot(Beacon_ptr beacon,
929
902
encountered_hashes.push_back (beacon->m_hash );
930
903
931
904
if (beacon_chain_out != nullptr ) {
932
- LogPrint (BCLog::LogFlags::ACCRUAL, " INFO %s: beacon %u links back for cpid %s: timestamp = %" PRId64 " , ctx_hash = %s,"
933
- " prev_beacon_ctx_hash = %s, status = %s." ,
934
- __func__,
935
- i + 1 ,
936
- beacon->m_cpid .ToString (),
937
- beacon->m_timestamp ,
938
- beacon->m_hash .GetHex (),
939
- beacon->m_previous_hash .GetHex (),
940
- beacon->StatusToString ());
941
-
942
- beacon_chain_out->push_back (std::make_pair (beacon->m_hash , beacon->m_timestamp ));
905
+ ChainletLinkLog (i, beacon);
943
906
}
944
907
945
908
++i;
946
909
}
947
910
948
- // Check of initial advertised beacon's previous hash.
949
- if (std::find (encountered_hashes.begin (), encountered_hashes.end (), beacon->m_previous_hash ) != encountered_hashes.end ()) {
950
- // If circularity is found this is an indication of corruption of beacon state and is fatal.
951
- // Produce an error message, reset the beacon registry, and require a restart of the node.
911
+ // Check of initial advertised beacon's previous hash. This should point to the pending beacon that was activated and not
912
+ // anywhere else.
913
+ {
914
+ // Select previous beacon in chainlet
915
+ auto beacon_iter = m_beacon_db.find (beacon->m_previous_hash );
952
916
953
- error (" %s: Circularity encountered in beacon ownership chain for beacon with CPID %s, starting at hash %s, "
954
- " at %u linked entries back from the start, with offending hash %s." ,
955
- __func__,
956
- cpid.ToString (),
957
- beacon->m_hash .GetHex (),
958
- i + 1 ,
959
- beacon->m_previous_hash .GetHex ());
960
-
961
- std::string str_error = strprintf (" ERROR: %s: Circularity encountered in beacon ownership chain for beacon with CPID %s, "
962
- " starting at hash %s, at %u linked entries back from the start, with offending hash %s.\n "
963
- " \n "
964
- " The client cannot continue and the beacon history has been reset and will be rebuilt "
965
- " on the next restart. Please restart Gridcoin." ,
966
- __func__,
967
- cpid.ToString (),
968
- beacon->m_hash .GetHex (),
969
- i + 1 ,
970
- beacon->m_previous_hash .GetHex ());
917
+ if (beacon_iter == m_beacon_db.end ()) {
918
+ ChainletErrorHandle (i, beacon, " previous beacon not found in the registry" );
919
+ }
971
920
972
- Reset ();
921
+ // Make sure status of previous beacon is pending.
922
+ if (beacon_iter->second ->m_status != BeaconStatusForStorage::PENDING) {
923
+ ChainletErrorHandle (i, beacon, " previous beacon to the beacon marked active is not pending" );
924
+ }
973
925
974
- uiInterface.ThreadSafeMessageBox (str_error, " Gridcoin" , CClientUIInterface::MSG_ERROR);
926
+ if (std::find (encountered_hashes.begin (), encountered_hashes.end (), beacon->m_previous_hash ) != encountered_hashes.end ()) {
927
+ // If circularity is found this is an indication of corruption of beacon state and is fatal.
928
+ // Produce an error message, reset the beacon registry, and require a restart of the node.
929
+ ChainletErrorHandle (i, beacon, " circularity encountered" );
930
+ }
975
931
976
- throw std::runtime_error (std::string { " The beacon registry is corrupted and Gridcoin cannot continue. Please restart. " });
932
+ // Note that we do not actually walk back to the pending beacon. The parameter beacon remains at the activated beacon.
977
933
}
978
934
979
935
return beacon;
0 commit comments