From 98533616d33b8c3b5d975e197a86aae5d1547ddc Mon Sep 17 00:00:00 2001
From: Crypto City <cryptocity@example.com>
Date: Wed, 14 Aug 2019 14:10:43 +0000
Subject: [PATCH] add a repair field to flag

---
 src/blockchain_db/blockchain_db.cpp     |  4 ++--
 src/blockchain_db/blockchain_db.h       |  2 +-
 src/blockchain_db/lmdb/db_lmdb.cpp      |  5 ++++-
 src/blockchain_db/lmdb/db_lmdb.h        |  2 +-
 src/blockchain_db/testdb.h              |  2 +-
 src/cc/cc.cpp                           |  8 ++++----
 src/cc/cc_command_handler_build.cpp     | 14 +++++++-------
 src/cc/cc_command_handler_buy_land.cpp  |  4 ++--
 src/daemon/rpc_command_executor.cpp     |  1 +
 src/rpc/core_rpc_server.cpp             |  4 ++--
 src/rpc/core_rpc_server_commands_defs.h |  2 ++
 tests/core_tests/cc.cpp                 |  4 ++--
 tests/unit_tests/cc.cpp                 |  6 ++++--
 13 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp
index 658364b46..6b9f09e08 100644
--- a/src/blockchain_db/blockchain_db.cpp
+++ b/src/blockchain_db/blockchain_db.cpp
@@ -408,8 +408,8 @@ bool BlockchainDB::does_cc_city_exist(uint32_t id) const
 
 bool BlockchainDB::does_cc_flag_exist(uint32_t id) const
 {
-  uint32_t owner, city, x0, y0, x1, y1;
-  return get_cc_flag_data(id, owner, city, x0, y0, x1, y1, NULL);
+  uint32_t owner, city, x0, y0, x1, y1, repair;
+  return get_cc_flag_data(id, owner, city, x0, y0, x1, y1, repair, NULL);
 }
 
 void BlockchainDB::reset_stats()
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 3c6ee27c0..afd76657a 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -1797,7 +1797,7 @@ public:
 
   virtual uint32_t allocate_new_cc_flag(uint32_t owner_id, uint32_t city_id, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1) = 0;
   virtual void delete_cc_flag(uint32_t id) = 0;
-  virtual bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, std::vector<std::vector<uint8_t>> *tiles) const = 0;
+  virtual bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, uint32_t &repair, std::vector<std::vector<uint8_t>> *tiles) const = 0;
   virtual void set_cc_flag_tiles(uint32_t id, const std::vector<std::vector<uint8_t>> &tiles) = 0;
   virtual uint32_t get_num_cc_flags() const = 0;
 
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 86edeaab5..18c535ff5 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -395,6 +395,7 @@ typedef struct mdb_cc_flag_data
   uint32_t y0;
   uint32_t x1;
   uint32_t y1;
+  uint32_t repair;
 } mdb_cc_flag_data;
 
 typedef struct mdb_cc_tile_data
@@ -4940,6 +4941,7 @@ uint32_t BlockchainLMDB::allocate_new_cc_flag(uint32_t owner_id, uint32_t city_i
   fd.y0 = y0;
   fd.x1 = x1;
   fd.y1 = y1;
+  fd.repair = 1000000;
 
   k.mv_data = (void*)&flag_id;
   k.mv_size = sizeof(flag_id);
@@ -5019,7 +5021,7 @@ void BlockchainLMDB::delete_cc_flag(uint32_t id)
     throw0(DB_ERROR(lmdb_error("Error deleting flag " + std::to_string(id) + ": ", result).c_str()));
 }
 
-bool BlockchainLMDB::get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, std::vector<std::vector<uint8_t>> *tiles) const
+bool BlockchainLMDB::get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, uint32_t &repair, std::vector<std::vector<uint8_t>> *tiles) const
 {
   LOG_PRINT_L3("BlockchainLMDB::" << __func__);
   check_open();
@@ -5049,6 +5051,7 @@ bool BlockchainLMDB::get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &ci
   y0 = fd.y0;
   x1 = fd.x1;
   y1 = fd.y1;
+  repair = fd.repair;
 
   if (tiles)
   {
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index 071bd25b0..335715e3c 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -457,7 +457,7 @@ private:
 
   uint32_t allocate_new_cc_flag(uint32_t owner_id, uint32_t city_id, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1);
   void delete_cc_flag(uint32_t id);
-  bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, std::vector<std::vector<uint8_t>> *tiles) const;
+  bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, uint32_t &repair, std::vector<std::vector<uint8_t>> *tiles) const;
   void set_cc_flag_tiles(uint32_t id, const std::vector<std::vector<uint8_t>> &tiles);
   uint32_t get_num_cc_flags() const;
 
diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h
index a9f4b92b7..f0cee0cff 100644
--- a/src/blockchain_db/testdb.h
+++ b/src/blockchain_db/testdb.h
@@ -182,7 +182,7 @@ public:
 
   virtual uint32_t allocate_new_cc_flag(uint32_t owner_id, uint32_t city_id, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1) { return 1; }
   virtual void delete_cc_flag(uint32_t id) {}
-  virtual bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, std::vector<std::vector<uint8_t>> *tiles) const { return false; }
+  virtual bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, uint32_t &repair, std::vector<std::vector<uint8_t>> *tiles) const { return false; }
   virtual void set_cc_flag_tiles(uint32_t id, const std::vector<std::vector<uint8_t>> &tiles) {}
   virtual uint32_t get_num_cc_flags() const { return 0; }
 
diff --git a/src/cc/cc.cpp b/src/cc/cc.cpp
index 64545d286..6c59ecbad 100644
--- a/src/cc/cc.cpp
+++ b/src/cc/cc.cpp
@@ -55,8 +55,8 @@ bool get_any_flag(const cryptonote::BlockchainDB &db, uint32_t x0, uint32_t y0,
   uint32_t n_flags = db.get_num_cc_flags();
   for (uint32_t i = 0; n_flags > 0; ++i)
   {
-    uint32_t owner, city, fx0, fy0, fx1, fy1;
-    if (db.get_cc_flag_data(i, owner, city, fx0, fy0, fx1, fy1, NULL))
+    uint32_t owner, city, fx0, fy0, fx1, fy1, repair;
+    if (db.get_cc_flag_data(i, owner, city, fx0, fy0, fx1, fy1, repair, NULL))
     {
       --n_flags;
       if (x1 < fx0)
@@ -110,9 +110,9 @@ bool get_build_cost(cryptonote::BlockchainDB &db, uint32_t flag, uint32_t dx, ui
     return false;
   }
 
-  uint32_t owner, city, x0, y0, x1, y1;
+  uint32_t owner, city, x0, y0, x1, y1, repair;
   std::vector<std::vector<uint8_t>> tiles;
-  if (!db.get_cc_flag_data(flag, owner, city, x0, y0, x1, y1, &tiles))
+  if (!db.get_cc_flag_data(flag, owner, city, x0, y0, x1, y1, repair, &tiles))
   {
     MERROR("Flag not found: " << flag);
     return false;
diff --git a/src/cc/cc_command_handler_build.cpp b/src/cc/cc_command_handler_build.cpp
index d9f5bf01e..d52afeebe 100644
--- a/src/cc/cc_command_handler_build.cpp
+++ b/src/cc/cc_command_handler_build.cpp
@@ -62,8 +62,8 @@ bool cc_command_handler_build::check(const cryptonote::BlockchainDB &db, const c
   }
 
   // get flag info, without tiles first, for sanity check
-  uint32_t owner, city, x0, y0, x1, y1;
-  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, NULL))
+  uint32_t owner, city, x0, y0, x1, y1, repair;
+  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, repair, NULL))
   {
     MERROR("build command refers to non existent flag");
     return false;
@@ -87,7 +87,7 @@ bool cc_command_handler_build::check(const cryptonote::BlockchainDB &db, const c
 
   // get tiles now (slower)
   std::vector<std::vector<uint8_t>> tiles;
-  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, &tiles))
+  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, repair, &tiles))
   {
     MERROR("build command refers to non existent flag " << build.flag);
     return false;
@@ -168,9 +168,9 @@ bool cc_command_handler_build::execute(cryptonote::BlockchainDB &db, const crypt
   uint32_t treasury;
   uint64_t balance;
 
-  uint32_t owner, city, x0, y0, x1, y1;
+  uint32_t owner, city, x0, y0, x1, y1, repair;
   std::vector<std::vector<uint8_t>> tiles;
-  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, &tiles))
+  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, repair, &tiles))
   {
     MERROR("build command refers to non existent flag " << build.flag);
     return false;
@@ -253,9 +253,9 @@ bool cc_command_handler_build::revert(cryptonote::BlockchainDB &db, const crypto
   uint32_t treasury;
   uint64_t balance;
 
-  uint32_t owner, city, x0, y0, x1, y1;
+  uint32_t owner, city, x0, y0, x1, y1, repair;
   std::vector<std::vector<uint8_t>> tiles;
-  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, &tiles))
+  if (!db.get_cc_flag_data(build.flag, owner, city, x0, y0, x1, y1, repair, &tiles))
   {
     MERROR("build command refers to non existent flag " << build.flag);
     return false;
diff --git a/src/cc/cc_command_handler_buy_land.cpp b/src/cc/cc_command_handler_buy_land.cpp
index 3a88012f7..8c3ee9e2e 100644
--- a/src/cc/cc_command_handler_buy_land.cpp
+++ b/src/cc/cc_command_handler_buy_land.cpp
@@ -149,8 +149,8 @@ bool cc_command_handler_buy_land::revert(cryptonote::BlockchainDB &db, const cry
 
   // check this is the correct flag
   const uint32_t flag_id = flags.back();
-  uint32_t owner, city, x0, y0, x1, y1;
-  if (!db.get_cc_flag_data(flag_id, owner, city, x0, y0, x1, y1, NULL))
+  uint32_t owner, city, x0, y0, x1, y1, repair;
+  if (!db.get_cc_flag_data(flag_id, owner, city, x0, y0, x1, y1, repair, NULL))
   {
     MERROR("Flag " << flag_id << " not found");
     return false;
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index e1d646ed8..2f03ec68c 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -2755,6 +2755,7 @@ bool t_rpc_command_executor::cc_get_flag(uint32_t id, bool get_tiles)
     tools::success_msg_writer() << "Flag data for: " << id;
     tools::success_msg_writer() << "Owner: " << res.owner;
     tools::success_msg_writer() << "City: " << res.city;
+    tools::success_msg_writer() << "Repair: " << res.repair << "(" << res.repair / 1000000.0f << "%)";
     tools::success_msg_writer() << "Extents: " << res.x0 << " " << res.y0 << " to " << res.x1 << " " << res.y1
         << " (" << res.x1-res.x0+1 << " x " << res.y1-res.y0+1 << ")";
     if (get_tiles)
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 661efd2d9..5a9d5beba 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -3417,7 +3417,7 @@ namespace cryptonote
     try
     {
       std::vector<std::vector<uint8_t>> tile_data;
-      if (!m_core.get_blockchain_storage().get_db().get_cc_flag_data(req.id, res.owner, res.city, res.x0, res.y0, res.x1, res.y1, req.get_tiles ? &tile_data : NULL))
+      if (!m_core.get_blockchain_storage().get_db().get_cc_flag_data(req.id, res.owner, res.city, res.x0, res.y0, res.x1, res.y1, res.repair, req.get_tiles ? &tile_data : NULL))
       {
         error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
         error_resp.message = "Flag not found";
@@ -3505,7 +3505,7 @@ namespace cryptonote
       {
         cryptonote::cc_snapshot::flag_state_t flag_state;
         std::vector<std::vector<uint8_t>> tiles;
-        if (db.get_cc_flag_data(flag_id, flag_state.owner, flag_state.city, flag_state.x0, flag_state.y0, flag_state.x1, flag_state.y1, &tiles))
+        if (db.get_cc_flag_data(flag_id, flag_state.owner, flag_state.city, flag_state.x0, flag_state.y0, flag_state.x1, flag_state.y1, flag_state.repair, &tiles))
         {
           flag_state.id = flag_id;
           flag_state.tiles.resize(tiles.size());
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 280a295ae..335a26ba0 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -2889,6 +2889,7 @@ namespace cryptonote
       uint32_t y0;
       uint32_t x1;
       uint32_t y1;
+      uint32_t repair;
       std::vector<tile_data_t> tiles;
       std::string status;
 
@@ -2900,6 +2901,7 @@ namespace cryptonote
         KV_SERIALIZE(y0)
         KV_SERIALIZE(x1)
         KV_SERIALIZE(y1)
+        KV_SERIALIZE(repair)
         KV_SERIALIZE(tiles)
       END_KV_SERIALIZE_MAP()
     };
diff --git a/tests/core_tests/cc.cpp b/tests/core_tests/cc.cpp
index 4569c3f72..24ead1745 100644
--- a/tests/core_tests/cc.cpp
+++ b/tests/core_tests/cc.cpp
@@ -201,9 +201,9 @@ static bool expect_treasury_balance(cryptonote::core &c, uint64_t expected_balan
 static bool expect_flag_tiles(cryptonote::core &c, uint32_t flag, const std::vector<std::vector<uint8_t>> &expected_tiles)
 {
   BlockchainDB &db = c.get_blockchain_storage().get_db();
-  uint32_t owner, city, x0, y0, x1, y1;
+  uint32_t owner, city, x0, y0, x1, y1, repair;
   std::vector<std::vector<uint8_t>> tiles;
-  if (!db.get_cc_flag_data(flag, owner, city, x0, y0, x1, y1, &tiles))
+  if (!db.get_cc_flag_data(flag, owner, city, x0, y0, x1, y1, repair, &tiles))
   {
     MERROR("Flag " << flag << " not found");
     return false;
diff --git a/tests/unit_tests/cc.cpp b/tests/unit_tests/cc.cpp
index a0a7b9738..6b7675640 100644
--- a/tests/unit_tests/cc.cpp
+++ b/tests/unit_tests/cc.cpp
@@ -79,8 +79,9 @@ private:
     uint32_t y0;
     uint32_t x1;
     uint32_t y1;
+    uint32_t repair;
 
-    bool operator==(const flag_t &other) const { return owner == other.owner && city == other.city && x0 == other.x0 && y0 == other.y0 && x1 == other.x1 && y1 == other.y1; }
+    bool operator==(const flag_t &other) const { return owner == other.owner && city == other.city && x0 == other.x0 && y0 == other.y0 && x1 == other.x1 && y1 == other.y1 && repair == other.repair; }
   };
 
   struct tile_t
@@ -273,7 +274,7 @@ protected:
     state.flags[id].active = false;
   }
 
-  virtual bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, std::vector<std::vector<uint8_t>> *tiles) const
+  virtual bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, uint32_t &repair, std::vector<std::vector<uint8_t>> *tiles) const
   {
     if (id >= state.flags.size() || !state.flags[id].active)
       return false;
@@ -283,6 +284,7 @@ protected:
     y0 = state.flags[id].y0;
     x1 = state.flags[id].x1;
     y1 = state.flags[id].y1;
+    repair = state.flags[id].repair;
     if (tiles)
     {
       tiles->resize((x1-x0+1) * (y1-y0+1));