Electroneum
cryptonote::checkpoints Class Reference

A container for blockchain checkpoints. More...

#include <checkpoints.h>

Public Member Functions

 checkpoints ()
 default constructor More...
 
bool add_checkpoint (uint64_t height, const std::string &hash_str)
 adds a checkpoint to the container More...
 
bool is_in_checkpoint_zone (uint64_t height) const
 checks if there is a checkpoint in the future More...
 
bool check_block (uint64_t height, const crypto::hash &h, bool &is_a_checkpoint) const
 checks if the given height and hash agree with the checkpoints More...
 
bool check_block (uint64_t height, const crypto::hash &h) const
 
bool is_alternative_block_allowed (uint64_t blockchain_height, uint64_t block_height) const
 checks if alternate chain blocks should be kept for a given height More...
 
uint64_t get_max_height () const
 gets the highest checkpoint height More...
 
const std::map< uint64_t, crypto::hash > & get_points () const
 gets the checkpoints container More...
 
bool check_for_conflicts (const checkpoints &other) const
 checks if our checkpoints container conflicts with another More...
 
bool init_default_checkpoints (network_type nettype)
 loads the default main chain checkpoints More...
 
bool load_new_checkpoints (const std::string &json_hashfile_fullpath, network_type nettype=MAINNET, bool dns=true)
 load new checkpoints More...
 
bool load_checkpoints_from_json (const std::string &json_hashfile_fullpath)
 load new checkpoints from json More...
 
bool load_checkpoints_from_dns (network_type nettype=MAINNET)
 load new checkpoints from DNS More...
 

Detailed Description

A container for blockchain checkpoints.

A checkpoint is a pre-defined hash for the block at a given height. Some of these are compiled-in, while others can be loaded at runtime either from a json file or via DNS from a checkpoint-hosting server.

Definition at line 51 of file checkpoints.h.

Constructor & Destructor Documentation

◆ checkpoints()

cryptonote::checkpoints::checkpoints ( )

default constructor

Definition at line 72 of file checkpoints.cpp.

73  {
74  }

Member Function Documentation

◆ add_checkpoint()

bool cryptonote::checkpoints::add_checkpoint ( uint64_t  height,
const std::string &  hash_str 
)

adds a checkpoint to the container

Parameters
heightthe height of the block the checkpoint is for
hash_strthe hash of the block, as a string
Returns
false if parsing the hash fails, or if the height is a duplicate AND the existing checkpoint hash does not match the new one, otherwise returns true

Definition at line 76 of file checkpoints.cpp.

77  {
78  crypto::hash h = crypto::null_hash;
79  bool r = epee::string_tools::hex_to_pod(hash_str, h);
80  CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!");
81 
82  // return false if adding at a height we already have AND the hash is different
83  if (m_points.count(height))
84  {
85  CHECK_AND_ASSERT_MES(h == m_points[height], false, "Checkpoint at given height already exists, and hash for new checkpoint was different!");
86  }
87  m_points[height] = h;
88  return true;
89  }
uint64_t height
Definition: blockchain.cpp:91
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Definition: misc_log_ex.h:181
POD_CLASS hash
Definition: hash.h:50
bool hex_to_pod(const std::string &hex_str, t_pod_type &s)
Definition: string_tools.h:324
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_block() [1/2]

bool cryptonote::checkpoints::check_block ( uint64_t  height,
const crypto::hash h 
) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 114 of file checkpoints.cpp.

115  {
116  bool ignored;
117  return check_block(height, h, ignored);
118  }
bool check_block(uint64_t height, const crypto::hash &h, bool &is_a_checkpoint) const
checks if the given height and hash agree with the checkpoints
Definition: checkpoints.cpp:96

◆ check_block() [2/2]

bool cryptonote::checkpoints::check_block ( uint64_t  height,
const crypto::hash h,
bool is_a_checkpoint 
) const

checks if the given height and hash agree with the checkpoints

This function checks if the given height and hash exist in the checkpoints container. If so, it returns whether or not the passed parameters match the stored values.

Parameters
heightthe height to be checked
hthe hash to be checked
is_a_checkpointreturn-by-reference if there is a checkpoint at the given height
Returns
true if there is no checkpoint at the given height, true if the passed parameters match the stored checkpoint, false otherwise

Definition at line 96 of file checkpoints.cpp.

97  {
98  auto it = m_points.find(height);
99  is_a_checkpoint = it != m_points.end();
100  if(!is_a_checkpoint)
101  return true;
102 
103  if(it->second == h)
104  {
105  MINFO("CHECKPOINT PASSED FOR HEIGHT " << height << " " << h);
106  return true;
107  }else
108  {
109  MWARNING("CHECKPOINT FAILED FOR HEIGHT " << height << ". EXPECTED HASH: " << it->second << ", FETCHED HASH: " << h);
110  return false;
111  }
112  }
#define MWARNING(x)
Definition: misc_log_ex.h:74
#define MINFO(x)
Definition: misc_log_ex.h:75
Here is the caller graph for this function:

◆ check_for_conflicts()

bool cryptonote::checkpoints::check_for_conflicts ( const checkpoints other) const

checks if our checkpoints container conflicts with another

A conflict refers to a case where both checkpoint sets have a checkpoint for a specific height but their hashes for that height do not match.

Parameters
otherthe other checkpoints instance to check against
Returns
false if any conflict is found, otherwise true

Definition at line 148 of file checkpoints.cpp.

149  {
150  for (auto& pt : other.get_points())
151  {
152  if (m_points.count(pt.first))
153  {
154  CHECK_AND_ASSERT_MES(pt.second == m_points.at(pt.first), false, "Checkpoint at given height already exists, and hash for new checkpoint was different!");
155  }
156  }
157  return true;
158  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_max_height()

uint64_t cryptonote::checkpoints::get_max_height ( ) const

gets the highest checkpoint height

Returns
the height of the highest checkpoint

Definition at line 136 of file checkpoints.cpp.

137  {
138  if (m_points.empty())
139  return 0;
140  return m_points.rbegin()->first;
141  }

◆ get_points()

const std::map< uint64_t, crypto::hash > & cryptonote::checkpoints::get_points ( ) const

gets the checkpoints container

Returns
a const reference to the checkpoints container

Definition at line 143 of file checkpoints.cpp.

144  {
145  return m_points;
146  }
Here is the caller graph for this function:

◆ init_default_checkpoints()

bool cryptonote::checkpoints::init_default_checkpoints ( network_type  nettype)

loads the default main chain checkpoints

Parameters
nettypenetwork type
Returns
true unless adding a checkpoint fails

Definition at line 160 of file checkpoints.cpp.

161  {
162  if (nettype == MAINNET)
163  {
164  ADD_CHECKPOINT(1, "4536e1e23ff7179a126a7e61cd9e89ded0e258176f2bc879c999caa155f68cc3");
165  ADD_CHECKPOINT(10, "e5aefcb1d575a788ecfb65bb7be3bdd135eb76ccefb38a60d7800e86d25d408e");
166  ADD_CHECKPOINT(100, "e3548600cc0e2991af4f36bbf44addd95051748fc09e8cac5f8237fd841132c0");
167  ADD_CHECKPOINT(1000, "d7ec8a6329948fee02cdc95b13f286bd69fe9540863a80dfff7fe14940756293");
168  ADD_CHECKPOINT(10000, "95dad4575ba43eb0d4ba9b6081d5d52e6a74fc8fe3391d9628f78ddd3b71c965");
169  ADD_CHECKPOINT(100000, "a7b51ca66b2525903efbd4a32604a7ad5000df4b9da8bdd9cb3062cb014b0cad");
170  ADD_CHECKPOINT(150000, "e9b66d3f12f9cedece7d9925721b15f1ec6cb2f6b438b3ddd288237c27ffe20e");
171  ADD_CHECKPOINT(179839, "f8631f50ef79b840cba9fe3484764d0c7515ff2884e1f5be2f7298a4d08e88ee");
172  ADD_CHECKPOINT(179840, "74958c1b19505ab49babc91dfd14251146256873ae875ac97c26fb2000490e70");
173  ADD_CHECKPOINT(179841, "8a793f1aef368e83fa72ac3a236309c06ae7726958120514e0f6d33ff3b24548");
174  ADD_CHECKPOINT(200000, "9a7853584fbe0d88746d3d7bb6a3efd02ecaa3f0158808fde9f3c8339b3d5d8f");
175  ADD_CHECKPOINT(250000, "0b4d542eeaf6fbd5ceb196ca5ed44edb6ee0c0f1cdf391ba62710b04e1da9f29");
176  ADD_CHECKPOINT(300000, "e3d192196c70c259164fec04868d5cf21a57242cccf54ca0ba9fd8eaeddb8d72");
177  ADD_CHECKPOINT(307499, "c08f9eecdebf4f1f99c4c273368df54422e6861829213ad5d0dbde1cf6f4f08c");
178  ADD_CHECKPOINT(307500, "a65844a64acf5d0aa421892dee64e3552ef390fd29894b7d6c77d08d6609952e");
179  ADD_CHECKPOINT(307501, "4a5a86a4c6ecee29c2d41d8f633e82a5b3340e354c55f2767f722fc03b950fae");
180  ADD_CHECKPOINT(310000, "82dfd6ee74a5ae7526af923f1637b59082ef917d84ad80944edb1debd557bb96");
181  ADD_CHECKPOINT(400000, "251e07872ce8b05dedafbce2dd27f978e71a46aca7fa3b6cdbd94d6b357b5078");
182  ADD_CHECKPOINT(500000, "c2f37b178f4e1cf3460bcefd6eaf14eeaf4258ee67b97e6146b171766bd8101d");
183  ADD_CHECKPOINT(600000, "e8eeceec76ea9718ebf7fac34250403f586d01224b343c6e122baa0799023a4f");
184  ADD_CHECKPOINT(700000, "09af67f7f5b01219dd18c59a424a7570cadfe3c50408180fcaf12cec205155f7");
185  ADD_CHECKPOINT(800000, "748bfc3c736ac106a8c731114648b8c11c0c2bc3d6b9ab074bbbfc8cc1914a3f");
186  ADD_CHECKPOINT(900000, "e0fce3c156932d38d8bde4e21fabbf2a8208e96fb1b0848cc796d7338a70f7de");
187  ADD_CHECKPOINT(1000000, "26da34bde63cfb6447e0dcc190b00e4db04127e2673d48316e63e64c661ab19c");
188  ADD_CHECKPOINT(1100000, "d9d9637c9468c3d8a3a552cef38e52effbe79d0f140b0a0551d5c15f61e07a08");
189  }
190  return true;
191  }
#define ADD_CHECKPOINT(h, hash)
Definition: checkpoints.h:38
Here is the caller graph for this function:

◆ is_alternative_block_allowed()

bool cryptonote::checkpoints::is_alternative_block_allowed ( uint64_t  blockchain_height,
uint64_t  block_height 
) const

checks if alternate chain blocks should be kept for a given height

this basically says if the blockchain is smaller than the first checkpoint then alternate blocks are allowed. Alternatively, if the last checkpoint before the end of the current chain is also before the block to be added, then this is fine.

Parameters
blockchain_heightthe current blockchain height
block_heightthe height of the block to be added as alternate
Returns
true if alternate blocks are allowed given the parameters, otherwise false

Definition at line 121 of file checkpoints.cpp.

122  {
123  if (0 == block_height)
124  return false;
125 
126  auto it = m_points.upper_bound(blockchain_height);
127  // Is blockchain_height before the first checkpoint?
128  if (it == m_points.begin())
129  return true;
130 
131  --it;
132  uint64_t checkpoint_height = it->first;
133  return checkpoint_height < block_height;
134  }
unsigned __int64 uint64_t
Definition: stdint.h:136
Here is the caller graph for this function:

◆ is_in_checkpoint_zone()

bool cryptonote::checkpoints::is_in_checkpoint_zone ( uint64_t  height) const

checks if there is a checkpoint in the future

This function checks if the height passed is lower than the highest checkpoint.

Parameters
heightthe height to check against
Returns
false if no checkpoints, otherwise returns whether or not the height passed is lower than the highest checkpoint.

Definition at line 91 of file checkpoints.cpp.

92  {
93  return !m_points.empty() && (height <= (--m_points.end())->first);
94  }

◆ load_checkpoints_from_dns()

bool cryptonote::checkpoints::load_checkpoints_from_dns ( network_type  nettype = MAINNET)

load new checkpoints from DNS

Parameters
nettypenetwork type
Returns
true if loading successful and no conflicts

Definition at line 229 of file checkpoints.cpp.

230  {
231  std::vector<std::string> records;
232 
233  // All four ElectroneumPulse domains have DNSSEC on and valid
234  static const std::vector<std::string> dns_urls = {
235  "checkpoints.electroneumpulse.com",
236  "checkpoints.electroneumpulse.info",
237  "checkpoints.electroneumpulse.net",
238  "checkpoints.electroneumpulse.org"
239  };
240 
241  static const std::vector<std::string> testnet_dns_urls = {
242  "testpoints.electroneumpulse.com",
243  "testpoints.electroneumpulse.info",
244  "testpoints.electroneumpulse.net",
245  "testpoints.electroneumpulse.org"
246  };
247 
248  static const std::vector<std::string> stagenet_dns_urls = {
249  "stagenetpoints.electroneumpulse.com",
250  "stagenetpoints.electroneumpulse.info",
251  "stagenetpoints.electroneumpulse.net",
252  "stagenetpoints.electroneumpulse.org"
253  };
254 
255  if (!tools::dns_utils::load_txt_records_from_dns(records, nettype == TESTNET ? testnet_dns_urls : nettype == STAGENET ? stagenet_dns_urls : dns_urls, "checkpoints"))
256  return true; // why true ?
257 
258  for (const auto& record : records)
259  {
260  auto pos = record.find(":");
261  if (pos != std::string::npos)
262  {
265 
266  // parse the first part as uint64_t,
267  // if this fails move on to the next record
268  std::stringstream ss(record.substr(0, pos));
269  if (!(ss >> height))
270  {
271  continue;
272  }
273 
274  // parse the second part as crypto::hash,
275  // if this fails move on to the next record
276  std::string hashStr = record.substr(pos + 1);
277  if (!epee::string_tools::hex_to_pod(hashStr, hash))
278  {
279  continue;
280  }
281 
282  ADD_CHECKPOINT(height, hashStr);
283  }
284  }
285  return true;
286  }
::std::string string
Definition: gtest-port.h:1097
bool load_txt_records_from_dns(std::vector< std::string > &good_records, const std::vector< std::string > &dns_urls, std::string type)
Definition: dns_utils.cpp:515
Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_checkpoints_from_json()

bool cryptonote::checkpoints::load_checkpoints_from_json ( const std::string &  json_hashfile_fullpath)

load new checkpoints from json

Parameters
json_hashfile_fullpathpath to the json checkpoints file
Returns
true if loading successful and no conflicts

Definition at line 193 of file checkpoints.cpp.

194  {
195  boost::system::error_code errcode;
196  if (! (boost::filesystem::exists(json_hashfile_fullpath, errcode)))
197  {
198  LOG_PRINT_L1("Blockchain checkpoints file not found");
199  return true;
200  }
201 
202  LOG_PRINT_L1("Adding checkpoints from blockchain hashfile");
203 
204  uint64_t prev_max_height = get_max_height();
205  LOG_PRINT_L1("Hard-coded max checkpoint height is " << prev_max_height);
206  t_hash_json hashes;
207  if (!epee::serialization::load_t_from_json_file(hashes, json_hashfile_fullpath))
208  {
209  MERROR("Error loading checkpoints from " << json_hashfile_fullpath);
210  return false;
211  }
212  for (std::vector<t_hashline>::const_iterator it = hashes.hashlines.begin(); it != hashes.hashlines.end(); )
213  {
215  height = it->height;
216  if (height <= prev_max_height) {
217  LOG_PRINT_L1("ignoring checkpoint height " << height);
218  } else {
219  std::string blockhash = it->hash;
220  LOG_PRINT_L1("Adding checkpoint height " << height << ", hash=" << blockhash);
221  ADD_CHECKPOINT(height, blockhash);
222  }
223  ++it;
224  }
225 
226  return true;
227  }
uint64_t get_max_height() const
gets the highest checkpoint height
#define MERROR(x)
Definition: misc_log_ex.h:73
#define LOG_PRINT_L1(x)
Definition: misc_log_ex.h:100
bool load_t_from_json_file(t_struct &out, const std::string &json_file)
struct hash_func hashes[]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_new_checkpoints()

bool cryptonote::checkpoints::load_new_checkpoints ( const std::string &  json_hashfile_fullpath,
network_type  nettype = MAINNET,
bool  dns = true 
)

load new checkpoints

Loads new checkpoints from the specified json file, as well as (optionally) from DNS.

Parameters
json_hashfile_fullpathpath to the json checkpoints file
nettypenetwork type
dnswhether or not to load DNS checkpoints
Returns
true if loading successful and no conflicts

Definition at line 288 of file checkpoints.cpp.

289  {
290  bool result;
291 
292  result = load_checkpoints_from_json(json_hashfile_fullpath);
293  if (dns)
294  {
295  result &= load_checkpoints_from_dns(nettype);
296  }
297 
298  return result;
299  }
bool load_checkpoints_from_dns(network_type nettype=MAINNET)
load new checkpoints from DNS
bool load_checkpoints_from_json(const std::string &json_hashfile_fullpath)
load new checkpoints from json

The documentation for this class was generated from the following files: