From c50369d65d42555a4330dbeb973f2a433ed2c55d Mon Sep 17 00:00:00 2001
From: moneromooo-monero <moneromooo-monero@users.noreply.github.com>
Date: Sat, 23 Dec 2023 15:31:05 +0000
Subject: [PATCH] add support for townforge (monero fork using randomx)

---
 src/base/crypto/Coin.cpp                    |  1 +
 src/base/crypto/Coin.h                      |  1 +
 src/base/tools/cryptonote/BlockTemplate.cpp | 10 ++++++-
 src/base/tools/cryptonote/WalletAddress.cpp | 33 +++++++++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/src/base/crypto/Coin.cpp b/src/base/crypto/Coin.cpp
index 2508e9cc7..c528aceca 100644
--- a/src/base/crypto/Coin.cpp
+++ b/src/base/crypto/Coin.cpp
@@ -54,6 +54,7 @@ static const CoinInfo coinInfo[] = {
     { Algorithm::KAWPOW_RVN,      "RVN",      "Ravencoin",    0,      0,              BLUE_BG_BOLD(   WHITE_BOLD_S " raven   ") },
     { Algorithm::RX_WOW,          "WOW",      "Wownero",      300,    100000000000,   MAGENTA_BG_BOLD(WHITE_BOLD_S " wownero ") },
     { Algorithm::RX_0,            "ZEPH",     "Zephyr",       120,    1000000000000,  BLUE_BG_BOLD(   WHITE_BOLD_S " zephyr  ") },
+    { Algorithm::RX_0,            "Townforge","Townforge",    30,     100000000,      MAGENTA_BG_BOLD(WHITE_BOLD_S " townforge ") },
 };
 
 
diff --git a/src/base/crypto/Coin.h b/src/base/crypto/Coin.h
index 166618b19..12ac14973 100644
--- a/src/base/crypto/Coin.h
+++ b/src/base/crypto/Coin.h
@@ -40,6 +40,7 @@ public:
         RAVEN,
         WOWNERO,
         ZEPHYR,
+        TOWNFORGE,
         MAX
     };
 
diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp
index 1a26a914d..b0a6bd9d9 100644
--- a/src/base/tools/cryptonote/BlockTemplate.cpp
+++ b/src/base/tools/cryptonote/BlockTemplate.cpp
@@ -207,7 +207,8 @@ bool xmrig::BlockTemplate::parse(bool hashes)
     setOffset(MINER_TX_PREFIX_OFFSET, ar.index());
 
     ar(m_txVersion);
-    ar(m_unlockTime);
+    if (m_coin != Coin::TOWNFORGE)
+      ar(m_unlockTime);
     ar(m_numInputs);
 
     // must be 1 input
@@ -280,6 +281,9 @@ bool xmrig::BlockTemplate::parse(bool hashes)
         ar(m_viewTag);
     }
 
+    if (m_coin == Coin::TOWNFORGE)
+      ar(m_unlockTime);
+
     ar(m_extraSize);
 
     setOffset(TX_EXTRA_OFFSET, ar.index());
@@ -335,6 +339,10 @@ bool xmrig::BlockTemplate::parse(bool hashes)
     uint8_t vin_rct_type = 0;
     ar(vin_rct_type);
 
+    // no way I'm parsing a full game update here
+    if (m_coin == Coin::TOWNFORGE && m_height % 720 == 0)
+      return true;
+
     // must be RCTTypeNull (0)
     if (vin_rct_type != 0) {
         return false;
diff --git a/src/base/tools/cryptonote/WalletAddress.cpp b/src/base/tools/cryptonote/WalletAddress.cpp
index f9b8a9f7e..9e9a89e9d 100644
--- a/src/base/tools/cryptonote/WalletAddress.cpp
+++ b/src/base/tools/cryptonote/WalletAddress.cpp
@@ -33,6 +33,26 @@
 
 bool xmrig::WalletAddress::decode(const char *address, size_t size)
 {
+    uint64_t tf_tag = 0;
+    if (size >= 4 && !strncmp(address, "TF", 2))
+    {
+      tf_tag = 0x424200;
+      switch (address[2])
+      {
+        case '1': tf_tag |= 0; break;
+        case '2': tf_tag |= 1; break;
+        default: tf_tag = 0; return false;
+      }
+      switch (address[3]) {
+        case 'M': tf_tag |= 0; break;
+        case 'T': tf_tag |= 0x10; break;
+        case 'S': tf_tag |= 0x20; break;
+        default: tf_tag = 0; return false;
+      }
+      address += 4;
+      size -= 4;
+    }
+
     static constexpr std::array<int, 9> block_sizes{ 0, 2, 3, 5, 6, 7, 9, 10, 11 };
     static constexpr char alphabet[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
     constexpr size_t alphabet_size = sizeof(alphabet) - 1;
@@ -114,6 +134,9 @@ bool xmrig::WalletAddress::decode(const char *address, size_t size)
         if (memcmp(m_checksum, md, sizeof(m_checksum)) == 0) {
             m_data = { address, size };
 
+            if (tf_tag)
+              m_tag = tf_tag;
+
             return true;
         }
     }
@@ -228,6 +251,16 @@ const xmrig::WalletAddress::TagInfo &xmrig::WalletAddress::tagInfo(uint64_t tag)
         { 0x54,     { Coin::GRAFT,      TESTNET,    PUBLIC,         28881,  28882 } },
         { 0x55,     { Coin::GRAFT,      TESTNET,    INTEGRATED,     28881,  28882 } },
         { 0x70,     { Coin::GRAFT,      TESTNET,    SUBADDRESS,     28881,  28882 } },
+
+        { 0x424200,     { Coin::TOWNFORGE,     MAINNET,    PUBLIC,         18881,  18882 } },
+        { 0x424201,     { Coin::TOWNFORGE,     MAINNET,    SUBADDRESS,     18881,  18882 } },
+
+        { 0x424210,     { Coin::TOWNFORGE,     TESTNET,    PUBLIC,         28881,  28882 } },
+        { 0x424211,     { Coin::TOWNFORGE,     TESTNET,    SUBADDRESS,     28881,  28882 } },
+
+        { 0x424220,     { Coin::TOWNFORGE,     STAGENET,   PUBLIC,         38881,  38882 } },
+        { 0x424221,     { Coin::TOWNFORGE,     STAGENET,   SUBADDRESS,     38881,  38882 } },
+
     };
 
     const auto it = tags.find(tag);