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  }
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Definition: misc_log_ex.h:181
uint64_t height
Definition: blockchain.cpp:91
bool hex_to_pod(const std::string &hex_str, t_pod_type &s)
Definition: string_tools.h:324
POD_CLASS hash
Definition: hash.h:50
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,
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 MINFO(x)
Definition: misc_log_ex.h:75
uint64_t height
Definition: blockchain.cpp:91
#define MWARNING(x)
Definition: misc_log_ex.h:74
Here is the caller graph for this function:

◆ check_block() [2/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  }
uint64_t height
Definition: blockchain.cpp:91
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_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  }
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Definition: misc_log_ex.h:181
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  ADD_CHECKPOINT(1811310, "f09bc360b87fd1161e28391528e432e7bde14e5183249c06a9db93a0c624499a");
190  }
191  if (nettype == TESTNET){
192  }
193  return true;
194  }
#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  }
uint64_t height
Definition: blockchain.cpp:91

◆ 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 232 of file checkpoints.cpp.

233  {
234  std::vector<std::string> records;
235 
236  // All four ElectroneumPulse domains have DNSSEC on and valid
237  static const std::vector<std::string> dns_urls = {
238  "checkpoints.electroneumpulse.com",
239  "checkpoints.electroneumpulse.info",
240  "checkpoints.electroneumpulse.net",
241  "checkpoints.electroneumpulse.org"
242  };
243 
244  static const std::vector<std::string> testnet_dns_urls = {
245  "testpoints.electroneumpulse.com",
246  "testpoints.electroneumpulse.info",
247  "testpoints.electroneumpulse.net",
248  "testpoints.electroneumpulse.org"
249  };
250 
251  static const std::vector<std::string> stagenet_dns_urls = {
252  "stagenetpoints.electroneumpulse.com",
253  "stagenetpoints.electroneumpulse.info",
254  "stagenetpoints.electroneumpulse.net",
255  "stagenetpoints.electroneumpulse.org"
256  };
257 
258  if (!tools::dns_utils::load_txt_records_from_dns(records, nettype == TESTNET ? testnet_dns_urls : nettype == STAGENET ? stagenet_dns_urls : dns_urls, "checkpoints"))
259  return true; // why true ?
260 
261  for (const auto& record : records)
262  {
263  auto pos = record.find(":");
264  if (pos != std::string::npos)
265  {
268 
269  // parse the first part as uint64_t,
270  // if this fails move on to the next record
271  std::stringstream ss(record.substr(0, pos));
272  if (!(ss >> height))
273  {
274  continue;
275  }
276 
277  // parse the second part as crypto::hash,
278  // if this fails move on to the next record
279  std::string hashStr = record.substr(pos + 1);
280  if (!epee::string_tools::hex_to_pod(hashStr, hash))
281  {
282  continue;
283  }
284 
285  ADD_CHECKPOINT(height, hashStr);
286  }
287  }
288  return true;
289  }
::std::string string
Definition: gtest-port.h:1097
#define ADD_CHECKPOINT(h, hash)
Definition: checkpoints.h:38
uint64_t height
Definition: blockchain.cpp:91
unsigned __int64 uint64_t
Definition: stdint.h:136
bool hex_to_pod(const std::string &hex_str, t_pod_type &s)
Definition: string_tools.h:324
POD_CLASS hash
Definition: hash.h:50
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 196 of file checkpoints.cpp.

197  {
198  boost::system::error_code errcode;
199  if (! (boost::filesystem::exists(json_hashfile_fullpath, errcode)))
200  {
201  LOG_PRINT_L1("Blockchain checkpoints file not found");
202  return true;
203  }
204 
205  LOG_PRINT_L1("Adding checkpoints from blockchain hashfile");
206 
207  uint64_t prev_max_height = get_max_height();
208  LOG_PRINT_L1("Hard-coded max checkpoint height is " << prev_max_height);
209  t_hash_json hashes;
210  if (!epee::serialization::load_t_from_json_file(hashes, json_hashfile_fullpath))
211  {
212  MERROR("Error loading checkpoints from " << json_hashfile_fullpath);
213  return false;
214  }
215  for (std::vector<t_hashline>::const_iterator it = hashes.hashlines.begin(); it != hashes.hashlines.end(); )
216  {
218  height = it->height;
219  if (height <= prev_max_height) {
220  LOG_PRINT_L1("ignoring checkpoint height " << height);
221  } else {
222  std::string blockhash = it->hash;
223  LOG_PRINT_L1("Adding checkpoint height " << height << ", hash=" << blockhash);
224  ADD_CHECKPOINT(height, blockhash);
225  }
226  ++it;
227  }
228 
229  return true;
230  }
#define MERROR(x)
Definition: misc_log_ex.h:73
#define LOG_PRINT_L1(x)
Definition: misc_log_ex.h:100
::std::string string
Definition: gtest-port.h:1097
#define ADD_CHECKPOINT(h, hash)
Definition: checkpoints.h:38
uint64_t get_max_height() const
gets the highest checkpoint height
uint64_t height
Definition: blockchain.cpp:91
struct hash_func hashes[]
unsigned __int64 uint64_t
Definition: stdint.h:136
bool load_t_from_json_file(t_struct &out, const std::string &json_file)
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 291 of file checkpoints.cpp.

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

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