Rename extern/global variables to g_varName instead of varName to avoid shadowing

This commit is contained in:
2026-09-15 17:54:50 +02:00
parent 099433b9df
commit fd27c2bac4
14 changed files with 251 additions and 251 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ extern "C" {
typedef struct Autolykos2Context Autolykos2Context; typedef struct Autolykos2Context Autolykos2Context;
extern uint64_t autolykos2_sleepBetweenHashOperationsMicroseconds; extern uint64_t g_autolykos2_sleepBetweenHashOperationsMicroseconds;
Autolykos2Context* Autolykos2_Create(void); Autolykos2Context* Autolykos2_Create(void);
void Autolykos2_Destroy(Autolykos2Context* ctx); void Autolykos2_Destroy(Autolykos2Context* ctx);
+1 -1
View File
@@ -43,7 +43,7 @@ KHASH_INIT(balance_sheet_map_m, key32_t, balance_sheet_entry_t, 1, hash_key32, e
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
extern khash_t(balance_sheet_map_m)* sheetMap; extern khash_t(balance_sheet_map_m)* g_sheetMap;
void BalanceSheet_Init(); void BalanceSheet_Init();
int BalanceSheet_Insert(balance_sheet_entry_t entry); int BalanceSheet_Insert(balance_sheet_entry_t entry);
+7 -7
View File
@@ -37,7 +37,7 @@ typedef struct blockchain {
* an epoch once the *following* entry has been computed, so it is valid on * an epoch once the *following* entry has been computed, so it is valid on
* [0, dagEpochsComputed - 1). * [0, dagEpochsComputed - 1).
* *
* Guarded by `dagCacheLock`, which is always taken AFTER `chainLock` and is never held across a * Guarded by `dagCacheLock`, which is always taken AFTER `g_chainLock` and is never held across a
* call back into chain.c. * call back into chain.c.
**/ **/
dag_epoch_state_t* dagEpochs; dag_epoch_state_t* dagEpochs;
@@ -106,7 +106,7 @@ uint64_t Chain_ReorgPenaltyForDepth(uint64_t reorgDepth);
**/ **/
bool Chain_BlockRespectsSenderOrdering(const block_t* block); bool Chain_BlockRespectsSenderOrdering(const block_t* block);
// Recompute `currentSupply` and `currentReward` from the in-memory chain blocks. // Recompute `g_currentSupply` and `g_currentReward` from the in-memory chain blocks.
// Returns true on success and updates runtime state globals. // Returns true on success and updates runtime state globals.
bool Chain_RecomputeRuntimeState(blockchain_t* chain); bool Chain_RecomputeRuntimeState(blockchain_t* chain);
@@ -120,15 +120,15 @@ bool Chain_LoadBlockFromFile(const char* dirpath, uint64_t blockNumber, bool loa
// Difficulty // Difficulty
// Retarget for the block at `height`, measured over the window [height - INTERVAL, height - 1]. // Retarget for the block at `height`, measured over the window [height - INTERVAL, height - 1].
// `chain` must hold blocks 0..height-1. Takes no locks; safe to call while holding `chainLock`. // `chain` must hold blocks 0..height-1. Takes no locks; safe to call while holding `g_chainLock`.
uint32_t Chain_ComputeTargetAtHeight(blockchain_t* chain, uint64_t height, uint32_t currentTarget); uint32_t Chain_ComputeTargetAtHeight(blockchain_t* chain, uint64_t height, uint32_t currentTarget);
// The consensus-required difficultyTarget for the block at `height`, derived from the chain alone. // The consensus-required difficultyTarget for the block at `height`, derived from the chain alone.
// Takes no locks; safe to call while holding `chainLock`. // Takes no locks; safe to call while holding `g_chainLock`.
uint32_t Chain_GetTargetForHeight(blockchain_t* chain, uint64_t height); uint32_t Chain_GetTargetForHeight(blockchain_t* chain, uint64_t height);
// Refresh runtime state derived from the chain tip (difficulty target, epoch DAG). // Refresh runtime state derived from the chain tip (difficulty target, epoch DAG).
// Call after any change to the tip. Must NOT be called while holding `chainLock`. // Call after any change to the tip. Must NOT be called while holding `g_chainLock`.
void Chain_OnTipAdvanced(blockchain_t* chain); void Chain_OnTipAdvanced(blockchain_t* chain);
// DAG // DAG
@@ -145,7 +145,7 @@ void Chain_OnTipAdvanced(blockchain_t* chain);
* true when validating or mining a block at that height. Returns false if it cannot produce both * true when validating or mining a block at that height. Returns false if it cannot produce both
* values; callers MUST treat that as an invalid proof rather than falling back to a default. * values; callers MUST treat that as an invalid proof rather than falling back to a default.
* *
* Takes `chainLock` for reading internally. Must NOT be called while holding it. * Takes `g_chainLock` for reading internally. Must NOT be called while holding it.
**/ **/
bool Chain_DagParamsForHeight(blockchain_t* chain, uint64_t blockHeight, bool Chain_DagParamsForHeight(blockchain_t* chain, uint64_t blockHeight,
size_t* outDagBytes, uint8_t outSeed[32]); size_t* outDagBytes, uint8_t outSeed[32]);
@@ -155,7 +155,7 @@ bool Chain_DagParamsForHeight(blockchain_t* chain, uint64_t blockHeight,
bool Chain_ComputeBlockWork(uint32_t difficultyTargetBits, uint256_t* outWork); bool Chain_ComputeBlockWork(uint32_t difficultyTargetBits, uint256_t* outWork);
// Summed work of the chain's blocks over the half-open range [from, to). // Summed work of the chain's blocks over the half-open range [from, to).
// Takes no locks; safe to call while holding `chainLock`. // Takes no locks; safe to call while holding `g_chainLock`.
bool Chain_ComputeWorkRange(blockchain_t* chain, size_t from, size_t to, uint256_t* outWork); bool Chain_ComputeWorkRange(blockchain_t* chain, size_t from, size_t to, uint256_t* outWork);
// Summed work of a candidate branch that is not (yet) part of the chain. // Summed work of a candidate branch that is not (yet) part of the chain.
+7 -7
View File
@@ -208,7 +208,7 @@ static const uint64_t TAIL_EMISSION = 750000000000ULL; // 0.75 coins per block f
// Phase 3: update once per effective epoch and keep a fixed per-block reward for that epoch. // Phase 3: update once per effective epoch and keep a fixed per-block reward for that epoch.
// //
// The *AtHeight variants take the height directly and never call Chain_Size/Chain_GetBlockCopy, so // The *AtHeight variants take the height directly and never call Chain_Size/Chain_GetBlockCopy, so
// they are safe to call from inside a chainLock critical section. chainLock is a non-recursive // they are safe to call from inside a g_chainLock critical section. g_chainLock is a non-recursive
// pthread_rwlock_t: taking it for reading while this thread already holds it for writing deadlocks // pthread_rwlock_t: taking it for reading while this thread already holds it for writing deadlocks
// as soon as another thread is queued for the write lock. // as soon as another thread is queued for the write lock.
static inline uint64_t GetInflationRateRewardAtHeight(uint256_t currentSupply, uint64_t height) { static inline uint64_t GetInflationRateRewardAtHeight(uint256_t currentSupply, uint64_t height) {
@@ -218,8 +218,8 @@ static inline uint64_t GetInflationRateRewardAtHeight(uint256_t currentSupply, u
: 1; : 1;
if (height == 0) { if (height == 0) {
currentReward = TAIL_EMISSION; g_currentReward = TAIL_EMISSION;
return currentReward; return g_currentReward;
} }
if (height % effectiveEpochLength == 0) { if (height % effectiveEpochLength == 0) {
@@ -242,11 +242,11 @@ static inline uint64_t GetInflationRateRewardAtHeight(uint256_t currentSupply, u
} }
uint64_t inflationPerBlock = quotient.limbs[0]; uint64_t inflationPerBlock = quotient.limbs[0];
currentReward = (inflationPerBlock > TAIL_EMISSION) ? inflationPerBlock : TAIL_EMISSION; g_currentReward = (inflationPerBlock > TAIL_EMISSION) ? inflationPerBlock : TAIL_EMISSION;
return currentReward; return g_currentReward;
} }
return (currentReward > TAIL_EMISSION) ? currentReward : TAIL_EMISSION; return (g_currentReward > TAIL_EMISSION) ? g_currentReward : TAIL_EMISSION;
} }
static inline uint64_t GetInflationRateReward(uint256_t currentSupply, blockchain_t* chain) { static inline uint64_t GetInflationRateReward(uint256_t currentSupply, blockchain_t* chain) {
@@ -313,7 +313,7 @@ static inline uint64_t CalculateBlockReward(uint256_t currentSupply, blockchain_
// Hashing DAG: see Chain_DagParamsForHeight in block/chain.h. Both the size and the epoch seed are // Hashing DAG: see Chain_DagParamsForHeight in block/chain.h. Both the size and the epoch seed are
// derived from the chain by that one function, so the mining and verification paths cannot drift // derived from the chain by that one function, so the mining and verification paths cannot drift
// apart. The previous CalculateTargetDAGSize/GetNextDAGSeed pair lived here, took chainLock // apart. The previous CalculateTargetDAGSize/GetNextDAGSeed pair lived here, took g_chainLock
// internally, was not epoch-aligned, and disagreed with the verifier's own copy in main.c. // internally, was not epoch-aligned, and disagreed with the verifier's own copy in main.c.
#endif #endif
+12 -12
View File
@@ -8,22 +8,22 @@
#include <block/chain.h> #include <block/chain.h>
#include <pthread.h> #include <pthread.h>
extern uint64_t currentBlockHeight; extern uint64_t g_currentBlockHeight;
extern blockchain_t* currentChain; extern blockchain_t* g_currentChain;
extern uint256_t currentSupply; extern uint256_t g_currentSupply;
extern uint64_t currentReward; extern uint64_t g_currentReward;
extern uint32_t difficultyTarget; extern uint32_t g_difficultyTarget;
extern const char* chainDataDir; extern const char* g_chainDataDir;
extern unsigned short listenPort; extern unsigned short g_listenPort;
extern bool echoPeersEnabled; extern bool g_echoPeersEnabled;
extern bool forceOrphanReorgEnabled; extern bool g_forceOrphanReorgEnabled;
// Random per-run identity of this node, advertised in HELLO/ACK_HELLO. A host can be reachable // Random per-run identity of this node, advertised in HELLO/ACK_HELLO. A host can be reachable
// under many addresses (especially over IPv6), so an (ip, port) endpoint is not a peer identity: // under many addresses (especially over IPv6), so an (ip, port) endpoint is not a peer identity:
// this nonce is what lets us recognise our own connections and a peer we already talk to. // this nonce is what lets us recognise our own connections and a peer we already talk to.
extern uint64_t localNodeId; extern uint64_t g_localNodeId;
// Global synchronization primitives for runtime state // Global synchronization primitives for runtime state
extern pthread_rwlock_t chainLock; // protects chain structure and related mutations extern pthread_rwlock_t g_chainLock; // protects chain structure and related mutations
extern pthread_mutex_t balanceSheetLock; // protects balance sheet map extern pthread_mutex_t g_balanceSheetLock; // protects balance sheet map
#endif #endif
+1 -1
View File
@@ -16,7 +16,7 @@ KHASH_INIT(tx_mempool_map_m, key32_t, signed_transaction_t, 1, hash_key32, eq_ke
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
extern khash_t(tx_mempool_map_m)* txMempool; extern khash_t(tx_mempool_map_m)* g_txMempool;
void TxMempool_Init(); void TxMempool_Init();
// Assumed that the transation was confirmed to be valid // Assumed that the transation was confirmed to be valid
+5 -5
View File
@@ -10,7 +10,7 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
uint64_t autolykos2_sleepBetweenHashOperationsMicroseconds = 0; uint64_t g_autolykos2_sleepBetweenHashOperationsMicroseconds = 0;
typedef struct { typedef struct {
uint8_t* buf; uint8_t* buf;
@@ -249,12 +249,12 @@ static bool Autolykos2_HashCore(
bool ok = Blake2b_Hash(finalInput, sizeof(finalInput), outHash, 32); bool ok = Blake2b_Hash(finalInput, sizeof(finalInput), outHash, 32);
// Throttle between hash operations if configured (applies to all hash paths). // Throttle between hash operations if configured (applies to all hash paths).
if (autolykos2_sleepBetweenHashOperationsMicroseconds > 0) { if (g_autolykos2_sleepBetweenHashOperationsMicroseconds > 0) {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
DWORD ms = (DWORD)((autolykos2_sleepBetweenHashOperationsMicroseconds + 999) / 1000); DWORD ms = (DWORD)((g_autolykos2_sleepBetweenHashOperationsMicroseconds + 999) / 1000);
Sleep(ms); Sleep(ms);
#else #else
sleep_for_microseconds(autolykos2_sleepBetweenHashOperationsMicroseconds); sleep_for_microseconds(g_autolykos2_sleepBetweenHashOperationsMicroseconds);
#endif #endif
} }
@@ -500,5 +500,5 @@ bool Autolykos2_FindNonceSingleCore(
} }
void Autolykos2_SetSleepBetweenHashOperations(uint64_t sleepMicroseconds) { void Autolykos2_SetSleepBetweenHashOperations(uint64_t sleepMicroseconds) {
autolykos2_sleepBetweenHashOperationsMicroseconds = sleepMicroseconds; g_autolykos2_sleepBetweenHashOperationsMicroseconds = sleepMicroseconds;
} }
+22 -22
View File
@@ -1,7 +1,7 @@
#include <balance_sheet.h> #include <balance_sheet.h>
#include <pthread.h> #include <pthread.h>
khash_t(balance_sheet_map_m)* sheetMap = NULL; khash_t(balance_sheet_map_m)* g_sheetMap = NULL;
static pthread_mutex_t g_sheetLock; static pthread_mutex_t g_sheetLock;
static bool BalanceSheet_GetSimEntry( static bool BalanceSheet_GetSimEntry(
@@ -139,7 +139,7 @@ static bool BalanceSheet_ApplyCandidateTransaction(
} }
static int BalanceSheet_InsertLocked(balance_sheet_entry_t entry) { static int BalanceSheet_InsertLocked(balance_sheet_entry_t entry) {
if (!sheetMap) { if (!g_sheetMap) {
return -1; return -1;
} }
@@ -147,22 +147,22 @@ static int BalanceSheet_InsertLocked(balance_sheet_entry_t entry) {
memcpy(key.bytes, entry.address, 32); memcpy(key.bytes, entry.address, 32);
int ret = 0; int ret = 0;
khiter_t k = kh_put(balance_sheet_map_m, sheetMap, key, &ret); khiter_t k = kh_put(balance_sheet_map_m, g_sheetMap, key, &ret);
if (k == kh_end(sheetMap)) { if (k == kh_end(g_sheetMap)) {
return -1; return -1;
} }
kh_value(sheetMap, k) = entry; kh_value(g_sheetMap, k) = entry;
return ret; return ret;
} }
void BalanceSheet_Init() { void BalanceSheet_Init() {
sheetMap = kh_init(balance_sheet_map_m); g_sheetMap = kh_init(balance_sheet_map_m);
pthread_mutex_init(&g_sheetLock, NULL); pthread_mutex_init(&g_sheetLock, NULL);
} }
int BalanceSheet_Insert(balance_sheet_entry_t entry) { int BalanceSheet_Insert(balance_sheet_entry_t entry) {
if (!sheetMap) { return -1; } if (!g_sheetMap) { return -1; }
pthread_mutex_lock(&g_sheetLock); pthread_mutex_lock(&g_sheetLock);
int ret = BalanceSheet_InsertLocked(entry); int ret = BalanceSheet_InsertLocked(entry);
@@ -177,9 +177,9 @@ bool BalanceSheet_Lookup(uint8_t* address, balance_sheet_entry_t* out) {
key32_t key; key32_t key;
memcpy(key.bytes, address, 32); memcpy(key.bytes, address, 32);
khiter_t k = kh_get(balance_sheet_map_m, sheetMap, key); khiter_t k = kh_get(balance_sheet_map_m, g_sheetMap, key);
if (k != kh_end(sheetMap)) { if (k != kh_end(g_sheetMap)) {
balance_sheet_entry_t entry = kh_value(sheetMap, k); balance_sheet_entry_t entry = kh_value(g_sheetMap, k);
memcpy(out, &entry, sizeof(balance_sheet_entry_t)); memcpy(out, &entry, sizeof(balance_sheet_entry_t));
pthread_mutex_unlock(&g_sheetLock); pthread_mutex_unlock(&g_sheetLock);
return true; return true;
@@ -190,7 +190,7 @@ bool BalanceSheet_Lookup(uint8_t* address, balance_sheet_entry_t* out) {
} }
bool BalanceSheet_SaveToFile(const char* outPath) { bool BalanceSheet_SaveToFile(const char* outPath) {
if (!sheetMap) { return false; } if (!g_sheetMap) { return false; }
pthread_mutex_lock(&g_sheetLock); pthread_mutex_lock(&g_sheetLock);
char outFile[512]; char outFile[512];
@@ -203,9 +203,9 @@ bool BalanceSheet_SaveToFile(const char* outPath) {
} }
khiter_t k; khiter_t k;
for (k = kh_begin(sheetMap); k != kh_end(sheetMap); ++k) { for (k = kh_begin(g_sheetMap); k != kh_end(g_sheetMap); ++k) {
if (kh_exist(sheetMap, k)) { if (kh_exist(g_sheetMap, k)) {
balance_sheet_entry_t entry = kh_val(sheetMap, k); balance_sheet_entry_t entry = kh_val(g_sheetMap, k);
if (fwrite(&entry, sizeof(balance_sheet_entry_t), 1, file) != 1) { if (fwrite(&entry, sizeof(balance_sheet_entry_t), 1, file) != 1) {
fclose(file); fclose(file);
pthread_mutex_unlock(&g_sheetLock); pthread_mutex_unlock(&g_sheetLock);
@@ -220,7 +220,7 @@ bool BalanceSheet_SaveToFile(const char* outPath) {
} }
bool BalanceSheet_LoadFromFile(const char* inPath) { bool BalanceSheet_LoadFromFile(const char* inPath) {
if (!sheetMap) { return false; } if (!g_sheetMap) { return false; }
pthread_mutex_lock(&g_sheetLock); pthread_mutex_lock(&g_sheetLock);
char inFile[512]; char inFile[512];
@@ -247,15 +247,15 @@ bool BalanceSheet_LoadFromFile(const char* inPath) {
} }
void BalanceSheet_Print() { void BalanceSheet_Print() {
if (!sheetMap) { return; } if (!g_sheetMap) { return; }
pthread_mutex_lock(&g_sheetLock); pthread_mutex_lock(&g_sheetLock);
// Iterate through every entry // Iterate through every entry
khiter_t k; khiter_t k;
for (k = kh_begin(sheetMap); k != kh_end(sheetMap); ++k) { for (k = kh_begin(g_sheetMap); k != kh_end(g_sheetMap); ++k) {
if (kh_exist(sheetMap, k)) { if (kh_exist(g_sheetMap, k)) {
key32_t key = kh_key(sheetMap, k); key32_t key = kh_key(g_sheetMap, k);
balance_sheet_entry_t val = kh_val(sheetMap, k); balance_sheet_entry_t val = kh_val(g_sheetMap, k);
char balanceStr[80]; char balanceStr[80];
uint256_serialize(&val.balance, balanceStr); uint256_serialize(&val.balance, balanceStr);
@@ -273,8 +273,8 @@ void BalanceSheet_Print() {
} }
void BalanceSheet_Destroy() { void BalanceSheet_Destroy() {
kh_destroy(balance_sheet_map_m, sheetMap); kh_destroy(balance_sheet_map_m, g_sheetMap);
sheetMap = NULL; g_sheetMap = NULL;
pthread_mutex_destroy(&g_sheetLock); pthread_mutex_destroy(&g_sheetLock);
} }
+65 -65
View File
@@ -8,10 +8,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <pthread.h> #include <pthread.h>
uint64_t currentBlockHeight = 0; uint64_t g_currentBlockHeight = 0;
// Defined near the DAG helpers at the bottom; needed early by Chain_AddBlockLocked, which verifies // Defined near the DAG helpers at the bottom; needed early by Chain_AddBlockLocked, which verifies
// proof of work while already holding chainLock for writing. // proof of work while already holding g_chainLock for writing.
static bool Chain_DagParamsForHeightLocked(blockchain_t* chain, uint64_t blockHeight, static bool Chain_DagParamsForHeightLocked(blockchain_t* chain, uint64_t blockHeight,
size_t* outDagBytes, uint8_t outSeed[32]); size_t* outDagBytes, uint8_t outSeed[32]);
@@ -123,7 +123,7 @@ static bool DebitAddress(const uint8_t address[32], const uint256_t* amount, uin
* or loaded without transactions (Chain_LoadFromFile), so any full replay of the chain has to be * or loaded without transactions (Chain_LoadFromFile), so any full replay of the chain has to be
* able to fall back to the on-disk copy. On success `*outLoadedFromDisk` tells the caller whether * able to fall back to the on-disk copy. On success `*outLoadedFromDisk` tells the caller whether
* the returned block is a temporary that must be released with Chain_ReturnBlockTransactions. * the returned block is a temporary that must be released with Chain_ReturnBlockTransactions.
* Takes no locks; callers are expected to already hold `chainLock`. * Takes no locks; callers are expected to already hold `g_chainLock`.
**/ **/
static bool Chain_BorrowBlockTransactions(blockchain_t* chain, size_t index, block_t** outBlock, bool* outLoadedFromDisk) { static bool Chain_BorrowBlockTransactions(blockchain_t* chain, size_t index, block_t** outBlock, bool* outLoadedFromDisk) {
if (!chain || !chain->blocks || !outBlock || !outLoadedFromDisk) { if (!chain || !chain->blocks || !outBlock || !outLoadedFromDisk) {
@@ -141,7 +141,7 @@ static bool Chain_BorrowBlockTransactions(blockchain_t* chain, size_t index, blo
block_t* loadedBlk = NULL; block_t* loadedBlk = NULL;
size_t txCount = 0; size_t txCount = 0;
if (!Chain_LoadBlockFromFile(chainDataDir, (uint64_t)index, true, &loadedBlk, &txCount) || !loadedBlk) { if (!Chain_LoadBlockFromFile(g_chainDataDir, (uint64_t)index, true, &loadedBlk, &txCount) || !loadedBlk) {
return false; return false;
} }
@@ -190,9 +190,9 @@ bool Chain_RecomputeRuntimeState(blockchain_t* chain) {
Chain_ReturnBlockTransactions(blk, loadedFromDisk); Chain_ReturnBlockTransactions(blk, loadedFromDisk);
} }
currentSupply = rebuiltSupply; g_currentSupply = rebuiltSupply;
// *AtHeight: never take chainLock from here, callers may already hold it. // *AtHeight: never take g_chainLock from here, callers may already hold it.
currentReward = CalculateBlockRewardAtHeight(currentSupply, (uint64_t)chain->size); g_currentReward = CalculateBlockRewardAtHeight(g_currentSupply, (uint64_t)chain->size);
return true; return true;
} }
@@ -204,7 +204,7 @@ bool Chain_RecomputeRuntimeState(blockchain_t* chain) {
* headers reading a single byte each -- so blowing it away wholesale is both correct and cheap, * headers reading a single byte each -- so blowing it away wholesale is both correct and cheap,
* and far safer than trying to work out which suffix a reorg actually disturbed. * and far safer than trying to work out which suffix a reorg actually disturbed.
* *
* Takes `dagCacheLock`. Safe to call while holding `chainLock` (that is the required lock order); * Takes `dagCacheLock`. Safe to call while holding `g_chainLock` (that is the required lock order);
* must NOT be called while already holding `dagCacheLock`. * must NOT be called while already holding `dagCacheLock`.
**/ **/
static void Chain_InvalidateDagEpochs(blockchain_t* chain) { static void Chain_InvalidateDagEpochs(blockchain_t* chain) {
@@ -280,7 +280,7 @@ void Chain_Destroy(blockchain_t* chain) {
/** /**
* Append `block` to the tip. * Append `block` to the tip.
* *
* Caller MUST already hold `chainLock` (write) and `balanceSheetLock`, and MUST call * Caller MUST already hold `g_chainLock` (write) and `g_balanceSheetLock`, and MUST call
* Chain_OnTipAdvanced afterwards (outside the locks) if this returns true. Chain_AddBlock is the * Chain_OnTipAdvanced afterwards (outside the locks) if this returns true. Chain_AddBlock is the
* locked wrapper for single appends; Chain_ReplaceBranch drives this directly so that a whole * locked wrapper for single appends; Chain_ReplaceBranch drives this directly so that a whole
* branch swap happens under one lock acquisition. * branch swap happens under one lock acquisition.
@@ -407,7 +407,7 @@ static bool Chain_AddBlockLocked(blockchain_t* chain, block_t* block) {
break; break;
} }
uint64_t expectedCoinbaseAmount = currentReward; uint64_t expectedCoinbaseAmount = g_currentReward;
if (UINT64_MAX - expectedCoinbaseAmount < totalFees) { if (UINT64_MAX - expectedCoinbaseAmount < totalFees) {
free(spendableTxs); free(spendableTxs);
ok = false; ok = false;
@@ -425,13 +425,13 @@ static bool Chain_AddBlockLocked(blockchain_t* chain, block_t* block) {
} }
} }
char supplyStr[80]; char supplyStr[80];
Uint256ToDecimal(&currentSupply, supplyStr, sizeof(supplyStr)); Uint256ToDecimal(&g_currentSupply, supplyStr, sizeof(supplyStr));
printf("Chain_AddBlock: blockIndex=%zu expectedCoinbase=%llu totalFees=%llu observedBlockCoinbase=%llu currentReward=%llu currentSupply=%s\n", printf("Chain_AddBlock: blockIndex=%zu expectedCoinbase=%llu totalFees=%llu observedBlockCoinbase=%llu currentReward=%llu currentSupply=%s\n",
expectedIndex, expectedIndex,
(unsigned long long)expectedCoinbaseAmount, (unsigned long long)expectedCoinbaseAmount,
(unsigned long long)totalFees, (unsigned long long)totalFees,
(unsigned long long)cbAmount, (unsigned long long)cbAmount,
(unsigned long long)currentReward, (unsigned long long)g_currentReward,
supplyStr); supplyStr);
} }
@@ -479,7 +479,7 @@ static bool Chain_AddBlockLocked(blockchain_t* chain, block_t* block) {
block_t* blk = (block_t*)vector_back(chain->blocks); block_t* blk = (block_t*)vector_back(chain->blocks);
stored = blk; stored = blk;
chain->size++; chain->size++;
currentBlockHeight = (uint64_t)(chain->size - 1); g_currentBlockHeight = (uint64_t)(chain->size - 1);
/** /**
* The chain now owns the transaction vector, so clear the CALLER's pointer to it. * The chain now owns the transaction vector, so clear the CALLER's pointer to it.
@@ -556,14 +556,14 @@ static bool Chain_AddBlockLocked(blockchain_t* chain, block_t* block) {
// Advance supply and reward here rather than in each caller. Callers used to do this // Advance supply and reward here rather than in each caller. Callers used to do this
// themselves, which meant the orphan-attach and maintenance-thread paths never did it: the // themselves, which meant the orphan-attach and maintenance-thread paths never did it: the
// next block's coinbase was then validated against a stale currentReward and rejected // next block's coinbase was then validated against a stale g_currentReward and rejected
// forever. It also has to happen per block so that applying a whole branch works. // forever. It also has to happen per block so that applying a whole branch works.
if (ok) { if (ok) {
(void)uint256_add_u64(&currentSupply, expectedCoinbaseAmount); (void)uint256_add_u64(&g_currentSupply, expectedCoinbaseAmount);
// Must be the *AtHeight variant: we hold chainLock for writing here, and // Must be the *AtHeight variant: we hold g_chainLock for writing here, and
// CalculateBlockReward would take it for reading via Chain_Size. chainLock is not // CalculateBlockReward would take it for reading via Chain_Size. g_chainLock is not
// recursive, so that self-deadlocks as soon as another thread queues for the write lock. // recursive, so that self-deadlocks as soon as another thread queues for the write lock.
currentReward = CalculateBlockRewardAtHeight(currentSupply, (uint64_t)chain->size); g_currentReward = CalculateBlockRewardAtHeight(g_currentSupply, (uint64_t)chain->size);
} }
// ok remains true if no failures // ok remains true if no failures
} while (0); } while (0);
@@ -582,13 +582,13 @@ bool Chain_AddBlock(blockchain_t* chain, block_t* block) {
} }
// Acquire global write locks to protect chain and balance sheet mutations. // Acquire global write locks to protect chain and balance sheet mutations.
pthread_rwlock_wrlock(&chainLock); pthread_rwlock_wrlock(&g_chainLock);
pthread_mutex_lock(&balanceSheetLock); pthread_mutex_lock(&g_balanceSheetLock);
bool ok = Chain_AddBlockLocked(chain, block); bool ok = Chain_AddBlockLocked(chain, block);
pthread_mutex_unlock(&balanceSheetLock); pthread_mutex_unlock(&g_balanceSheetLock);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
if (ok) { if (ok) {
// Every path that appends comes through here, so this is where difficulty/DAG catch up. // Every path that appends comes through here, so this is where difficulty/DAG catch up.
@@ -601,23 +601,23 @@ bool Chain_AddBlock(blockchain_t* chain, block_t* block) {
block_t* Chain_GetBlock(blockchain_t* chain, size_t index) { block_t* Chain_GetBlock(blockchain_t* chain, size_t index) {
if (!chain) return NULL; if (!chain) return NULL;
block_t* blk = NULL; block_t* blk = NULL;
pthread_rwlock_rdlock(&chainLock); pthread_rwlock_rdlock(&g_chainLock);
blk = (block_t*)vector_get(chain->blocks, index); blk = (block_t*)vector_get(chain->blocks, index);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
return blk; return blk;
} }
bool Chain_GetBlockCopy(blockchain_t* chain, size_t index, block_t** outCopy) { bool Chain_GetBlockCopy(blockchain_t* chain, size_t index, block_t** outCopy) {
if (!chain || !outCopy) return false; if (!chain || !outCopy) return false;
*outCopy = NULL; *outCopy = NULL;
pthread_rwlock_rdlock(&chainLock); pthread_rwlock_rdlock(&g_chainLock);
block_t* src = (block_t*)vector_get(chain->blocks, index); block_t* src = (block_t*)vector_get(chain->blocks, index);
if (!src) { if (!src) {
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
return false; return false;
} }
block_t* copy = Block_Copy(src); block_t* copy = Block_Copy(src);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
if (!copy) return false; if (!copy) return false;
*outCopy = copy; *outCopy = copy;
return true; return true;
@@ -626,9 +626,9 @@ bool Chain_GetBlockCopy(blockchain_t* chain, size_t index, block_t** outCopy) {
size_t Chain_Size(blockchain_t* chain) { size_t Chain_Size(blockchain_t* chain) {
if (!chain) return 0; if (!chain) return 0;
size_t sz = 0; size_t sz = 0;
pthread_rwlock_rdlock(&chainLock); pthread_rwlock_rdlock(&g_chainLock);
sz = vector_size(chain->blocks); sz = vector_size(chain->blocks);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
return sz; return sz;
} }
@@ -671,7 +671,7 @@ bool Chain_IsValid(blockchain_t* chain) {
/** /**
* Truncate the chain to `height` blocks and rebuild the balance sheet and supply from what remains. * Truncate the chain to `height` blocks and rebuild the balance sheet and supply from what remains.
* *
* Caller MUST already hold `chainLock` (write) and `balanceSheetLock`, and MUST call * Caller MUST already hold `g_chainLock` (write) and `g_balanceSheetLock`, and MUST call
* Chain_OnTipAdvanced afterwards (outside the locks). Chain_RollbackToHeight is the locked wrapper. * Chain_OnTipAdvanced afterwards (outside the locks). Chain_RollbackToHeight is the locked wrapper.
**/ **/
static bool Chain_RollbackToHeightLocked(blockchain_t* chain, size_t height) { static bool Chain_RollbackToHeightLocked(blockchain_t* chain, size_t height) {
@@ -734,7 +734,7 @@ static bool Chain_RollbackToHeightLocked(blockchain_t* chain, size_t height) {
} }
chain->size = vector_size(chain->blocks); chain->size = vector_size(chain->blocks);
currentBlockHeight = chain->size ? (uint64_t)(chain->size - 1) : 0ULL; g_currentBlockHeight = chain->size ? (uint64_t)(chain->size - 1) : 0ULL;
// Blocks below the old tip are gone, so the DAG recurrence folded from their votes is stale. // Blocks below the old tip are gone, so the DAG recurrence folded from their votes is stale.
Chain_InvalidateDagEpochs(chain); Chain_InvalidateDagEpochs(chain);
@@ -830,9 +830,9 @@ static bool Chain_RollbackToHeightLocked(blockchain_t* chain, size_t height) {
Chain_ReturnBlockTransactions(toProcess, loaded); Chain_ReturnBlockTransactions(toProcess, loaded);
} }
currentSupply = rebuiltSupply; g_currentSupply = rebuiltSupply;
// *AtHeight: chainLock is held for writing here (see Chain_RollbackToHeight). // *AtHeight: g_chainLock is held for writing here (see Chain_RollbackToHeight).
currentReward = CalculateBlockRewardAtHeight(currentSupply, (uint64_t)chain->size); g_currentReward = CalculateBlockRewardAtHeight(g_currentSupply, (uint64_t)chain->size);
return true; return true;
} }
@@ -840,13 +840,13 @@ static bool Chain_RollbackToHeightLocked(blockchain_t* chain, size_t height) {
bool Chain_RollbackToHeight(blockchain_t* chain, size_t height) { bool Chain_RollbackToHeight(blockchain_t* chain, size_t height) {
if (!chain || !chain->blocks) return false; if (!chain || !chain->blocks) return false;
pthread_rwlock_wrlock(&chainLock); pthread_rwlock_wrlock(&g_chainLock);
pthread_mutex_lock(&balanceSheetLock); pthread_mutex_lock(&g_balanceSheetLock);
bool ok = Chain_RollbackToHeightLocked(chain, height); bool ok = Chain_RollbackToHeightLocked(chain, height);
pthread_mutex_unlock(&balanceSheetLock); pthread_mutex_unlock(&g_balanceSheetLock);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
// A reorg can move the tip back across an adjustment boundary, so the target must come down too. // A reorg can move the tip back across an adjustment boundary, so the target must come down too.
Chain_OnTipAdvanced(chain); Chain_OnTipAdvanced(chain);
@@ -863,7 +863,7 @@ static int Chain_CompareTimestamps(const void* lhs, const void* rhs) {
} }
/** /**
* Median timestamp of the last MEDIAN_TIME_SPAN blocks. Caller must hold `chainLock`. * Median timestamp of the last MEDIAN_TIME_SPAN blocks. Caller must hold `g_chainLock`.
**/ **/
static uint64_t Chain_MedianTimePastLocked(blockchain_t* chain) { static uint64_t Chain_MedianTimePastLocked(blockchain_t* chain) {
if (!chain || !chain->blocks) { if (!chain || !chain->blocks) {
@@ -916,7 +916,7 @@ bool Chain_IsInitialBlockDownload(blockchain_t* chain) {
/** /**
* Verify that a candidate branch is internally linked and attaches to the block below `forkHeight`. * Verify that a candidate branch is internally linked and attaches to the block below `forkHeight`.
* Caller must hold `chainLock`. * Caller must hold `g_chainLock`.
**/ **/
static bool Chain_BranchIsLinkedLocked(blockchain_t* chain, size_t forkHeight, block_t** blocks, size_t count) { static bool Chain_BranchIsLinkedLocked(blockchain_t* chain, size_t forkHeight, block_t** blocks, size_t count) {
if (!chain || !chain->blocks || !blocks || count == 0 || forkHeight == 0) { if (!chain || !chain->blocks || !blocks || count == 0 || forkHeight == 0) {
@@ -1035,8 +1035,8 @@ bool Chain_ReplaceBranch(blockchain_t* chain,
return false; return false;
} }
pthread_rwlock_wrlock(&chainLock); pthread_rwlock_wrlock(&g_chainLock);
pthread_mutex_lock(&balanceSheetLock); pthread_mutex_lock(&g_balanceSheetLock);
bool ok = false; bool ok = false;
block_t** snapshot = NULL; // deep copies of the blocks we are replacing block_t** snapshot = NULL; // deep copies of the blocks we are replacing
@@ -1109,7 +1109,7 @@ bool Chain_ReplaceBranch(blockchain_t* chain,
// only change when our own tip moves -- so without this the same line is printed // only change when our own tip moves -- so without this the same line is printed
// every second for as long as the branch stays deferred, which on a node that is // every second for as long as the branch stays deferred, which on a node that is
// not mining is forever. Report each distinct deferral once, and again whenever the // not mining is forever. Report each distinct deferral once, and again whenever the
// situation actually changes. Guarded by chainLock (held for writing here). // situation actually changes. Guarded by g_chainLock (held for writing here).
static size_t lastDeferredFork = SIZE_MAX; static size_t lastDeferredFork = SIZE_MAX;
static uint64_t lastDeferredTip = UINT64_MAX; static uint64_t lastDeferredTip = UINT64_MAX;
static uint64_t lastDeferredPenalty = UINT64_MAX; static uint64_t lastDeferredPenalty = UINT64_MAX;
@@ -1247,8 +1247,8 @@ bool Chain_ReplaceBranch(blockchain_t* chain,
Chain_FreeBlockArray(snapshot, snapshotCount); Chain_FreeBlockArray(snapshot, snapshotCount);
Chain_FreeBlockArray(candidate, candidate ? count : 0); Chain_FreeBlockArray(candidate, candidate ? count : 0);
pthread_mutex_unlock(&balanceSheetLock); pthread_mutex_unlock(&g_balanceSheetLock);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
Chain_OnTipAdvanced(chain); Chain_OnTipAdvanced(chain);
@@ -1257,8 +1257,8 @@ bool Chain_ReplaceBranch(blockchain_t* chain,
void Chain_Wipe(blockchain_t* chain) { void Chain_Wipe(blockchain_t* chain) {
Chain_ClearBlocks(chain); Chain_ClearBlocks(chain);
currentBlockHeight = 0; g_currentBlockHeight = 0;
difficultyTarget = INITIAL_DIFFICULTY; g_difficultyTarget = INITIAL_DIFFICULTY;
} }
bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t currentSupply, uint64_t currentReward) { bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t currentSupply, uint64_t currentReward) {
@@ -1293,7 +1293,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
return false; return false;
} }
pthread_rwlock_wrlock(&chainLock); pthread_rwlock_wrlock(&g_chainLock);
FILE* metaFile = fopen(metaTmpPath, "wb+"); FILE* metaFile = fopen(metaTmpPath, "wb+");
FILE* chainFile = fopen(chainTmpPath, "wb+"); FILE* chainFile = fopen(chainTmpPath, "wb+");
@@ -1302,7 +1302,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
if (metaFile) fclose(metaFile); if (metaFile) fclose(metaFile);
if (chainFile) fclose(chainFile); if (chainFile) fclose(chainFile);
if (tableFile) fclose(tableFile); if (tableFile) fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1317,7 +1317,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(metaFile); fclose(metaFile);
fclose(chainFile); fclose(chainFile);
fclose(tableFile); fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1334,7 +1334,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(metaFile); fclose(metaFile);
fclose(chainFile); fclose(chainFile);
fclose(tableFile); fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1349,7 +1349,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(metaFile); fclose(metaFile);
fclose(chainFile); fclose(chainFile);
fclose(tableFile); fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1362,7 +1362,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(metaFile); fclose(metaFile);
fclose(chainFile); fclose(chainFile);
fclose(tableFile); fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1377,7 +1377,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(metaFile); fclose(metaFile);
fclose(chainFile); fclose(chainFile);
fclose(tableFile); fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1395,7 +1395,7 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(metaFile); fclose(metaFile);
fclose(chainFile); fclose(chainFile);
fclose(tableFile); fclose(tableFile);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
@@ -1436,14 +1436,14 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
fclose(tableFile); fclose(tableFile);
if (rename(metaTmpPath, metaPath) != 0 || rename(chainTmpPath, chainPath) != 0 || rename(tableTmpPath, tablePath) != 0) { if (rename(metaTmpPath, metaPath) != 0 || rename(chainTmpPath, chainPath) != 0 || rename(tableTmpPath, tablePath) != 0) {
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
remove(metaTmpPath); remove(metaTmpPath);
remove(chainTmpPath); remove(chainTmpPath);
remove(tableTmpPath); remove(tableTmpPath);
return false; return false;
} }
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
return true; return true;
} }
@@ -2023,7 +2023,7 @@ static bool Chain_ReserveDagEpochsLocked(blockchain_t* chain, size_t needed) {
* [0, k * EPOCH_LENGTH) to all be present. Growth is the default: the size only stays put or falls * [0, k * EPOCH_LENGTH) to all be present. Growth is the default: the size only stays put or falls
* when miners actively say so, and there is no vote that makes it climb faster. * when miners actively say so, and there is no vote that makes it climb faster.
* *
* Caller must hold `chainLock` (read) and `chain->dagCacheLock`. * Caller must hold `g_chainLock` (read) and `chain->dagCacheLock`.
**/ **/
static bool Chain_ExtendDagEpochsLocked(blockchain_t* chain, size_t epochIndex) { static bool Chain_ExtendDagEpochsLocked(blockchain_t* chain, size_t epochIndex) {
if (!chain || !chain->blocks) { if (!chain || !chain->blocks) {
@@ -2112,7 +2112,7 @@ static bool Chain_ExtendDagEpochsLocked(blockchain_t* chain, size_t epochIndex)
* last block of the previous epoch. Constant for a whole epoch, which is what lets the DAG be * last block of the previous epoch. Constant for a whole epoch, which is what lets the DAG be
* generated once per epoch instead of once per block. * generated once per epoch instead of once per block.
* *
* Caller must hold `chainLock`. * Caller must hold `g_chainLock`.
**/ **/
static bool Chain_EpochDagSeedForHeightLocked(blockchain_t* chain, uint64_t blockHeight, uint8_t outSeed[32]) { static bool Chain_EpochDagSeedForHeightLocked(blockchain_t* chain, uint64_t blockHeight, uint8_t outSeed[32]) {
const uint64_t epochIndex = blockHeight / (uint64_t)EPOCH_LENGTH; const uint64_t epochIndex = blockHeight / (uint64_t)EPOCH_LENGTH;
@@ -2136,10 +2136,10 @@ static bool Chain_EpochDagSeedForHeightLocked(blockchain_t* chain, uint64_t bloc
} }
/** /**
* As Chain_DagParamsForHeight, but assumes `chainLock` is already held (read OR write). * As Chain_DagParamsForHeight, but assumes `g_chainLock` is already held (read OR write).
* *
* Needed because Chain_AddBlockLocked verifies proof of work while holding the write lock, and * Needed because Chain_AddBlockLocked verifies proof of work while holding the write lock, and
* chainLock is not recursive -- taking it for reading there deadlocks the moment another thread * g_chainLock is not recursive -- taking it for reading there deadlocks the moment another thread
* queues for the write lock. * queues for the write lock.
**/ **/
static bool Chain_DagParamsForHeightLocked(blockchain_t* chain, uint64_t blockHeight, static bool Chain_DagParamsForHeightLocked(blockchain_t* chain, uint64_t blockHeight,
@@ -2153,7 +2153,7 @@ static bool Chain_DagParamsForHeightLocked(blockchain_t* chain, uint64_t blockHe
uint64_t bytes = 0; uint64_t bytes = 0;
bool ok = false; bool ok = false;
// Lock order is chainLock -> dagCacheLock, everywhere. Nothing under dagCacheLock calls back // Lock order is g_chainLock -> dagCacheLock, everywhere. Nothing under dagCacheLock calls back
// into chain.c, so this pair cannot deadlock. // into chain.c, so this pair cannot deadlock.
pthread_mutex_lock(&chain->dagCacheLock); pthread_mutex_lock(&chain->dagCacheLock);
if (Chain_ExtendDagEpochsLocked(chain, epochIndex)) { if (Chain_ExtendDagEpochsLocked(chain, epochIndex)) {
@@ -2186,9 +2186,9 @@ bool Chain_DagParamsForHeight(blockchain_t* chain, uint64_t blockHeight,
return false; return false;
} }
pthread_rwlock_rdlock(&chainLock); pthread_rwlock_rdlock(&g_chainLock);
const bool ok = Chain_DagParamsForHeightLocked(chain, blockHeight, outDagBytes, outSeed); const bool ok = Chain_DagParamsForHeightLocked(chain, blockHeight, outDagBytes, outSeed);
pthread_rwlock_unlock(&chainLock); pthread_rwlock_unlock(&g_chainLock);
return ok; return ok;
} }
@@ -2202,7 +2202,7 @@ void Chain_OnTipAdvanced(blockchain_t* chain) {
// Refresh the cached target for the block that comes next, so every path that moves the tip // Refresh the cached target for the block that comes next, so every path that moves the tip
// (mining, P2P accept, sync, orphan attach, reorg) stays on the same difficulty as its peers. // (mining, P2P accept, sync, orphan attach, reorg) stays on the same difficulty as its peers.
difficultyTarget = Chain_GetTargetForHeight(chain, (uint64_t)chainSize); g_difficultyTarget = Chain_GetTargetForHeight(chain, (uint64_t)chainSize);
// The epoch DAG is deliberately NOT rebuilt here. It is a mining accelerator only -- validation // The epoch DAG is deliberately NOT rebuilt here. It is a mining accelerator only -- validation
// derives its lanes from the epoch seed, so a node that does not mine never allocates one -- // derives its lanes from the epoch seed, so a node that does not mine never allocates one --
+58 -58
View File
@@ -29,18 +29,18 @@
#define CHAIN_DATA_DIR "chain_data" #define CHAIN_DATA_DIR "chain_data"
#endif #endif
blockchain_t* currentChain = NULL; blockchain_t* g_currentChain = NULL;
const char* chainDataDir = CHAIN_DATA_DIR; const char* g_chainDataDir = CHAIN_DATA_DIR;
unsigned short listenPort = LISTEN_PORT; unsigned short g_listenPort = LISTEN_PORT;
bool echoPeersEnabled = ECHO_PEERS != 0; bool g_echoPeersEnabled = ECHO_PEERS != 0;
bool forceOrphanReorgEnabled = false; bool g_forceOrphanReorgEnabled = false;
uint256_t currentSupply = {{0, 0, 0, 0}}; uint256_t g_currentSupply = {{0, 0, 0, 0}};
uint64_t currentReward = 750000000000ULL; uint64_t g_currentReward = 750000000000ULL;
uint64_t localNodeId = 0; // Randomised in main() before the node comes up uint64_t g_localNodeId = 0; // Randomised in main() before the node comes up
// Define the synchronization primitives declared in runtime_state.h // Define the synchronization primitives declared in runtime_state.h
pthread_rwlock_t chainLock; pthread_rwlock_t g_chainLock;
pthread_mutex_t balanceSheetLock; pthread_mutex_t g_balanceSheetLock;
void handle_sigint(int sig) { void handle_sigint(int sig) {
printf("Caught signal %d, exiting...\n", sig); printf("Caught signal %d, exiting...\n", sig);
@@ -52,7 +52,7 @@ void handle_sigint(int sig) {
static void ApplyRuntimeConfigFromEnv(void) { static void ApplyRuntimeConfigFromEnv(void) {
const char* dataDir = getenv("SKALACOIN_CHAIN_DATA_DIR"); const char* dataDir = getenv("SKALACOIN_CHAIN_DATA_DIR");
if (dataDir && dataDir[0] != '\0') { if (dataDir && dataDir[0] != '\0') {
chainDataDir = dataDir; g_chainDataDir = dataDir;
} }
const char* portStr = getenv("SKALACOIN_LISTEN_PORT"); const char* portStr = getenv("SKALACOIN_LISTEN_PORT");
@@ -60,29 +60,29 @@ static void ApplyRuntimeConfigFromEnv(void) {
char* end = NULL; char* end = NULL;
long parsed = strtol(portStr, &end, 10); long parsed = strtol(portStr, &end, 10);
if (end != portStr && *end == '\0' && parsed > 0 && parsed <= 65535) { if (end != portStr && *end == '\0' && parsed > 0 && parsed <= 65535) {
listenPort = (unsigned short)parsed; g_listenPort = (unsigned short)parsed;
} }
} }
const char* echoStr = getenv("SKALACOIN_ECHO_PEERS"); const char* echoStr = getenv("SKALACOIN_ECHO_PEERS");
if (echoStr && echoStr[0] != '\0') { if (echoStr && echoStr[0] != '\0') {
echoPeersEnabled = (strcmp(echoStr, "0") != 0); g_echoPeersEnabled = (strcmp(echoStr, "0") != 0);
} }
const char* forceOrphanStr = getenv("SKALACOIN_FORCE_ORPHAN_REORG"); const char* forceOrphanStr = getenv("SKALACOIN_FORCE_ORPHAN_REORG");
if (forceOrphanStr && forceOrphanStr[0] != '\0') { if (forceOrphanStr && forceOrphanStr[0] != '\0') {
forceOrphanReorgEnabled = (strcmp(forceOrphanStr, "0") != 0); g_forceOrphanReorgEnabled = (strcmp(forceOrphanStr, "0") != 0);
} }
} }
uint32_t difficultyTarget = INITIAL_DIFFICULTY; uint32_t g_difficultyTarget = INITIAL_DIFFICULTY;
static bool MineBlock(blockchain_t* chain, block_t* block) { static bool MineBlock(blockchain_t* chain, block_t* block) {
if (!chain || !block) { if (!chain || !block) {
return false; return false;
} }
// Resolve the epoch parameters ONCE. Doing it per nonce would take chainLock millions of times // Resolve the epoch parameters ONCE. Doing it per nonce would take g_chainLock millions of times
// per block and contend with every network thread. // per block and contend with every network thread.
size_t dagBytes = 0; size_t dagBytes = 0;
uint8_t seed[32]; uint8_t seed[32];
@@ -568,8 +568,8 @@ static bool MineAndAppendBlock(blockchain_t* chain,
if (attached > 0) { if (attached > 0) {
printf("Attached %zu orphan(s) after mining/appending block\n", attached); printf("Attached %zu orphan(s) after mining/appending block\n", attached);
// Persist chain/sheet after attaching orphans // Persist chain/sheet after attaching orphans
Chain_SaveToFile(chain, chainDataDir, *currentSupply, *currentReward); Chain_SaveToFile(chain, g_chainDataDir, *currentSupply, *currentReward);
BalanceSheet_SaveToFile(chainDataDir); BalanceSheet_SaveToFile(g_chainDataDir);
} }
uint8_t canonicalHash[32]; uint8_t canonicalHash[32];
@@ -711,9 +711,9 @@ static bool VerifyChainFully(blockchain_t* chain) {
} }
uint64_t expectedReward = 0; uint64_t expectedReward = 0;
uint64_t savedReward = currentReward; uint64_t savedReward = g_currentReward;
expectedReward = CalculateBlockReward(replaySupply, prevChain); expectedReward = CalculateBlockReward(replaySupply, prevChain);
currentReward = savedReward; g_currentReward = savedReward;
if (!Block_AllTransactionsValid(blk)) { if (!Block_AllTransactionsValid(blk)) {
Block_Destroy(blk); Block_Destroy(blk);
@@ -772,7 +772,7 @@ static bool VerifyChainFully(blockchain_t* chain) {
// Use when error // Use when error
[[noreturn]] void KillEverythingAndExit(net_node_t* node, blockchain_t* chain) { [[noreturn]] void KillEverythingAndExit(net_node_t* node, blockchain_t* chain) {
Node_Destroy(node); Node_Destroy(node);
currentChain = NULL; g_currentChain = NULL;
Chain_Destroy(chain); Chain_Destroy(chain);
Block_ShutdownPowContext(); Block_ShutdownPowContext();
BalanceSheet_Destroy(); BalanceSheet_Destroy();
@@ -818,12 +818,12 @@ int main(int argc, char* argv[]) {
// Pick this run's node identity before the node (and with it the listener) comes up, so every // Pick this run's node identity before the node (and with it the listener) comes up, so every
// handshake can carry it. Peers are identified by this nonce rather than by an (ip, port) // handshake can carry it. Peers are identified by this nonce rather than by an (ip, port)
// endpoint, which a multi-homed host has several of. // endpoint, which a multi-homed host has several of.
localNodeId = random_secure_eight_byte(); g_localNodeId = random_secure_eight_byte();
printf("Node identity: %016" PRIx64 "\n", localNodeId); printf("Node identity: %016" PRIx64 "\n", g_localNodeId);
// Initialize runtime locks before any thread or helper can touch chain state. // Initialize runtime locks before any thread or helper can touch chain state.
pthread_rwlock_init(&chainLock, NULL); pthread_rwlock_init(&g_chainLock, NULL);
pthread_mutex_init(&balanceSheetLock, NULL); pthread_mutex_init(&g_balanceSheetLock, NULL);
BalanceSheet_Init(); BalanceSheet_Init();
blockchain_t* chain = Chain_Create(); blockchain_t* chain = Chain_Create();
@@ -833,19 +833,19 @@ int main(int argc, char* argv[]) {
return 1; return 1;
} }
currentChain = chain; g_currentChain = chain;
net_node_t* node = Node_Create(); net_node_t* node = Node_Create();
if (!node) { if (!node) {
currentChain = NULL; g_currentChain = NULL;
Chain_Destroy(chain); Chain_Destroy(chain);
BalanceSheet_Destroy(); BalanceSheet_Destroy();
return 1; return 1;
} }
uint8_t lastSavedHash[32] = {0}; uint8_t lastSavedHash[32] = {0};
if (!Chain_LoadFromFile(chain, chainDataDir, &currentSupply, &difficultyTarget, &currentReward, lastSavedHash, false)) { if (!Chain_LoadFromFile(chain, g_chainDataDir, &g_currentSupply, &g_difficultyTarget, &g_currentReward, lastSavedHash, false)) {
printf("No existing chain loaded from %s\n", chainDataDir); printf("No existing chain loaded from %s\n", g_chainDataDir);
} else { } else {
// Recompute runtime supply/reward from loaded blocks to avoid trusting stale meta values. // Recompute runtime supply/reward from loaded blocks to avoid trusting stale meta values.
if (!Chain_RecomputeRuntimeState(chain)) { if (!Chain_RecomputeRuntimeState(chain)) {
@@ -857,7 +857,7 @@ int main(int argc, char* argv[]) {
Chain_OnTipAdvanced(chain); Chain_OnTipAdvanced(chain);
} }
if (!BalanceSheet_LoadFromFile(chainDataDir)) { if (!BalanceSheet_LoadFromFile(g_chainDataDir)) {
printf("Failed to load the balance sheet or none existing\n"); printf("Failed to load the balance sheet or none existing\n");
} }
@@ -866,8 +866,8 @@ int main(int argc, char* argv[]) {
? (PHASE1_TARGET_BLOCKS / EMISSION_ACCELERATION_FACTOR) ? (PHASE1_TARGET_BLOCKS / EMISSION_ACCELERATION_FACTOR)
: 1; : 1;
if ((uint64_t)Chain_Size(chain) < effectivePhase1Blocks || currentReward == 0) { if ((uint64_t)Chain_Size(chain) < effectivePhase1Blocks || g_currentReward == 0) {
currentReward = CalculateBlockReward(currentSupply, chain); g_currentReward = CalculateBlockReward(g_currentSupply, chain);
} }
{ {
@@ -895,13 +895,13 @@ int main(int argc, char* argv[]) {
printf("Loaded chain with %zu blocks from disk\n", Chain_Size(chain)); printf("Loaded chain with %zu blocks from disk\n", Chain_Size(chain));
} else { } else {
fprintf(stderr, "loaded chain is invalid, wiping persisted state.\n"); fprintf(stderr, "loaded chain is invalid, wiping persisted state.\n");
WipeChainFiles(chainDataDir); WipeChainFiles(g_chainDataDir);
Chain_Wipe(chain); Chain_Wipe(chain);
BalanceSheet_Destroy(); BalanceSheet_Destroy();
BalanceSheet_Init(); BalanceSheet_Init();
currentSupply = uint256_from_u64(0); g_currentSupply = uint256_from_u64(0);
difficultyTarget = INITIAL_DIFFICULTY; g_difficultyTarget = INITIAL_DIFFICULTY;
currentReward = CalculateBlockReward(currentSupply, chain); g_currentReward = CalculateBlockReward(g_currentSupply, chain);
} }
} }
@@ -984,7 +984,7 @@ int main(int argc, char* argv[]) {
if (!GenerateTestMinerIdentity(minerPrivateKey, minerCompressedPubkey, minerAddress)) { if (!GenerateTestMinerIdentity(minerPrivateKey, minerCompressedPubkey, minerAddress)) {
fprintf(stderr, "failed to generate test miner keypair\n"); fprintf(stderr, "failed to generate test miner keypair\n");
Node_Destroy(node); Node_Destroy(node);
currentChain = NULL; g_currentChain = NULL;
Chain_Destroy(chain); Chain_Destroy(chain);
Block_ShutdownPowContext(); Block_ShutdownPowContext();
BalanceSheet_Destroy(); BalanceSheet_Destroy();
@@ -996,7 +996,7 @@ int main(int argc, char* argv[]) {
printf("Test miner address: %s\n", minerAddressHex); printf("Test miner address: %s\n", minerAddressHex);
char supplyStr[80]; char supplyStr[80];
Uint256ToDecimal(&currentSupply, supplyStr, sizeof(supplyStr)); Uint256ToDecimal(&g_currentSupply, supplyStr, sizeof(supplyStr));
printf("Current chain has %zu blocks, total supply %s\n", Chain_Size(chain), supplyStr); printf("Current chain has %zu blocks, total supply %s\n", Chain_Size(chain), supplyStr);
printf("Commands: mine <x>, send <address> <amount> [fee], sendrawtx <hex_tx>, txpooldetail <txhash>, balance [address], connect <ipv4> [port], peers, sync [force] (requires nodes), dagvote <grow|hold|down>, flushchain, fullverify, blockdetail <block number>, wipechain, genaddr, exit\n"); printf("Commands: mine <x>, send <address> <amount> [fee], sendrawtx <hex_tx>, txpooldetail <txhash>, balance [address], connect <ipv4> [port], peers, sync [force] (requires nodes), dagvote <grow|hold|down>, flushchain, fullverify, blockdetail <block number>, wipechain, genaddr, exit\n");
@@ -1079,7 +1079,7 @@ int main(int argc, char* argv[]) {
break; break;
} }
uint64_t coinbaseAmount = currentReward; uint64_t coinbaseAmount = g_currentReward;
if (UINT64_MAX - coinbaseAmount < totalFees) { if (UINT64_MAX - coinbaseAmount < totalFees) {
free(acceptedTxs); free(acceptedTxs);
Block_Destroy(block); Block_Destroy(block);
@@ -1095,7 +1095,7 @@ int main(int argc, char* argv[]) {
} }
free(acceptedTxs); free(acceptedTxs);
if (!MineAndAppendBlock(chain, block, &currentSupply, &currentReward)) { if (!MineAndAppendBlock(chain, block, &g_currentSupply, &g_currentReward)) {
Block_Destroy(block); Block_Destroy(block);
minedAll = false; minedAll = false;
break; break;
@@ -1110,14 +1110,14 @@ int main(int argc, char* argv[]) {
if (i % 50 == 0) { if (i % 50 == 0) {
// Mid-mine flush // Mid-mine flush
(void)FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward); (void)FlushChainAndSheet(chain, g_chainDataDir, g_currentSupply, g_currentReward);
} }
} }
if (minedAll) { if (minedAll) {
(void)FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward); (void)FlushChainAndSheet(chain, g_chainDataDir, g_currentSupply, g_currentReward);
printf("mine finished and chain flushed\n"); printf("mine finished and chain flushed\n");
} }
continue; continue;
@@ -1189,7 +1189,7 @@ int main(int argc, char* argv[]) {
continue; continue;
} }
uint64_t coinbaseAmount = currentReward; uint64_t coinbaseAmount = g_currentReward;
AddCoinbaseTransaction(block, minerAddress, coinbaseAmount); AddCoinbaseTransaction(block, minerAddress, coinbaseAmount);
signed_transaction_t spendTx; signed_transaction_t spendTx;
@@ -1212,12 +1212,12 @@ int main(int argc, char* argv[]) {
AddressToHexString(recipientAddress, recipientHex); AddressToHexString(recipientAddress, recipientHex);
printf("%s\n\nMining block...\n", recipientHex); printf("%s\n\nMining block...\n", recipientHex);
if (!MineAndAppendBlock(chain, block, &currentSupply, &currentReward)) { if (!MineAndAppendBlock(chain, block, &g_currentSupply, &g_currentReward)) {
Block_Destroy(block); Block_Destroy(block);
continue; continue;
} }
FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward); FlushChainAndSheet(chain, g_chainDataDir, g_currentSupply, g_currentReward);
Block_Destroy(block); // the chain took the transaction array; this frees the wrapper Block_Destroy(block); // the chain took the transaction array; this frees the wrapper
if (node) { if (node) {
@@ -1749,7 +1749,7 @@ int main(int argc, char* argv[]) {
block_t* detailBlock = NULL; block_t* detailBlock = NULL;
size_t txCount = 0; size_t txCount = 0;
if (!Chain_LoadBlockFromFile(chainDataDir, (uint64_t)requestedBlock, false, &detailBlock, &txCount)) { if (!Chain_LoadBlockFromFile(g_chainDataDir, (uint64_t)requestedBlock, false, &detailBlock, &txCount)) {
printf("block %llu not found\n", requestedBlock); printf("block %llu not found\n", requestedBlock);
continue; continue;
} }
@@ -1757,7 +1757,7 @@ int main(int argc, char* argv[]) {
uint8_t canonicalHash[32]; uint8_t canonicalHash[32];
uint8_t powHash[32]; uint8_t powHash[32];
Block_CalculateHash(detailBlock, canonicalHash); Block_CalculateHash(detailBlock, canonicalHash);
if (!ComputeHistoricalAutolykosHashFromDisk(chainDataDir, (uint64_t)requestedBlock, detailBlock, powHash)) { if (!ComputeHistoricalAutolykosHashFromDisk(g_chainDataDir, (uint64_t)requestedBlock, detailBlock, powHash)) {
Block_Destroy(detailBlock); Block_Destroy(detailBlock);
printf("failed to calculate block %llu proof hash\n", requestedBlock); printf("failed to calculate block %llu proof hash\n", requestedBlock);
continue; continue;
@@ -1822,7 +1822,7 @@ int main(int argc, char* argv[]) {
continue; continue;
} }
unsigned short peerPort = listenPort; unsigned short peerPort = g_listenPort;
if (portStr) { if (portStr) {
char* end = NULL; char* end = NULL;
long parsedPort = strtol(portStr, &end, 10); long parsedPort = strtol(portStr, &end, 10);
@@ -1860,7 +1860,7 @@ int main(int argc, char* argv[]) {
} }
if (strcmp(cmd, "flushchain") == 0) { if (strcmp(cmd, "flushchain") == 0) {
if (FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward)) { if (FlushChainAndSheet(chain, g_chainDataDir, g_currentSupply, g_currentReward)) {
printf("chain flushed\n"); printf("chain flushed\n");
} }
continue; continue;
@@ -1880,7 +1880,7 @@ int main(int argc, char* argv[]) {
bool loaded = Chain_LoadFromFile( bool loaded = Chain_LoadFromFile(
verifyChain, verifyChain,
chainDataDir, g_chainDataDir,
&verifySupply, &verifySupply,
&verifyDifficulty, &verifyDifficulty,
&verifyReward, &verifyReward,
@@ -1899,13 +1899,13 @@ int main(int argc, char* argv[]) {
} }
if (strcmp(cmd, "wipechain") == 0) { if (strcmp(cmd, "wipechain") == 0) {
WipeChainFiles(chainDataDir); WipeChainFiles(g_chainDataDir);
Chain_Wipe(chain); Chain_Wipe(chain);
BalanceSheet_Destroy(); BalanceSheet_Destroy();
BalanceSheet_Init(); BalanceSheet_Init();
currentSupply = uint256_from_u64(0); g_currentSupply = uint256_from_u64(0);
difficultyTarget = INITIAL_DIFFICULTY; g_difficultyTarget = INITIAL_DIFFICULTY;
currentReward = CalculateBlockReward(currentSupply, chain); g_currentReward = CalculateBlockReward(g_currentSupply, chain);
// No DAG rebuild needed: Chain_Wipe drops the memoised epoch table, and MineBlock // No DAG rebuild needed: Chain_Wipe drops the memoised epoch table, and MineBlock
// rebuilds the DAG on demand for whatever epoch it next mines in. // rebuilds the DAG on demand for whatever epoch it next mines in.
@@ -1934,16 +1934,16 @@ int main(int argc, char* argv[]) {
printf("Unknown command. Available: mine, send, sendrawtx, sync, txpooldetail, blockdetail, balance, connect, peers, flushchain, fullverify, wipechain, genaddr, exit\n"); printf("Unknown command. Available: mine, send, sendrawtx, sync, txpooldetail, blockdetail, balance, connect, peers, flushchain, fullverify, wipechain, genaddr, exit\n");
} }
(void)FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward); (void)FlushChainAndSheet(chain, g_chainDataDir, g_currentSupply, g_currentReward);
Block_ShutdownPowContext(); Block_ShutdownPowContext();
Node_Destroy(node); Node_Destroy(node);
currentChain = NULL; g_currentChain = NULL;
Chain_Destroy(chain); Chain_Destroy(chain);
BalanceSheet_Destroy(); BalanceSheet_Destroy();
pthread_mutex_destroy(&balanceSheetLock); pthread_mutex_destroy(&g_balanceSheetLock);
pthread_rwlock_destroy(&chainLock); pthread_rwlock_destroy(&g_chainLock);
return 0; return 0;
} }
+36 -36
View File
@@ -25,11 +25,11 @@ static net_node_t* Node_FromConnection(tcp_connection_t* conn) {
} }
static uint64_t Node_GetCurrentBlockHeight(void) { static uint64_t Node_GetCurrentBlockHeight(void) {
if (currentChain) { if (g_currentChain) {
return (uint64_t)Chain_Size(currentChain); return (uint64_t)Chain_Size(g_currentChain);
} }
return currentBlockHeight; return g_currentBlockHeight;
} }
// Compares two listen endpoints (family + IP + port). // Compares two listen endpoints (family + IP + port).
@@ -300,7 +300,7 @@ static node_identity_result_t Node_CheckPeerIdentity(net_node_t* node, tcp_conne
struct sockaddr_storage ep; struct sockaddr_storage ep;
int haveEp = Node_ConnListenEndpoint(conn, &ep); int haveEp = Node_ConnListenEndpoint(conn, &ep);
if (conn->peerNodeId == localNodeId) { if (conn->peerNodeId == g_localNodeId) {
// We dialled ourselves (or accepted our own dial). Remember the endpoint as our own so // We dialled ourselves (or accepted our own dial). Remember the endpoint as our own so
// discovery stops offering it back to us, and drop the connection. // discovery stops offering it back to us, and drop the connection.
if (haveEp && node->discovery) { if (haveEp && node->discovery) {
@@ -449,12 +449,12 @@ static void* Node_MaintenanceThread(void* arg) {
net_node_t* n = (net_node_t*)arg; net_node_t* n = (net_node_t*)arg;
if (!n) return NULL; if (!n) return NULL;
while (n->maintenanceRunning) { while (n->maintenanceRunning) {
if (currentChain) { if (g_currentChain) {
size_t attached = OrphanPool_AttemptAttach(currentChain); size_t attached = OrphanPool_AttemptAttach(g_currentChain);
if (attached > 0) { if (attached > 0) {
printf("Maintenance: attached %zu orphan(s)\n", attached); printf("Maintenance: attached %zu orphan(s)\n", attached);
Chain_SaveToFile(currentChain, chainDataDir, currentSupply, currentReward); Chain_SaveToFile(g_currentChain, g_chainDataDir, g_currentSupply, g_currentReward);
BalanceSheet_SaveToFile(chainDataDir); BalanceSheet_SaveToFile(g_chainDataDir);
} }
} }
// Drop transactions too old to be worth holding, so the pool is not inflated by junk that // Drop transactions too old to be worth holding, so the pool is not inflated by junk that
@@ -546,7 +546,7 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
// The chain check has to come first now: PoW validity is chain-relative (the epoch DAG size and // The chain check has to come first now: PoW validity is chain-relative (the epoch DAG size and
// seed are derived from it), so there is nothing to validate against without a chain. // seed are derived from it), so there is nothing to validate against without a chain.
if (!currentChain) { if (!g_currentChain) {
printf("Rejected BLOCK_DATA at height %" PRIu64 ": no active chain\n", blockHeight); printf("Rejected BLOCK_DATA at height %" PRIu64 ": no active chain\n", blockHeight);
vector_destroy(&blk->transactions); vector_destroy(&blk->transactions);
free(blk); free(blk);
@@ -570,11 +570,11 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
// The orphan pool stamps the local tip height at first sight; that stamp drives the reorg // The orphan pool stamps the local tip height at first sight; that stamp drives the reorg
// penalty and must be taken now, not re-derived later from a moved tip. // penalty and must be taken now, not re-derived later from a moved tip.
uint64_t chainSize = Chain_Size(currentChain); uint64_t chainSize = Chain_Size(g_currentChain);
const uint64_t observedAtTipHeight = chainSize > 0 ? (chainSize - 1) : 0ULL; const uint64_t observedAtTipHeight = chainSize > 0 ? (chainSize - 1) : 0ULL;
// Temporary debug mode: force network-received blocks through the orphan pool to exercise reorg handling. // Temporary debug mode: force network-received blocks through the orphan pool to exercise reorg handling.
if (forceOrphanReorgEnabled && blk->header.blockNumber > 0) { if (g_forceOrphanReorgEnabled && blk->header.blockNumber > 0) {
OrphanPool_Insert(blk, blockHeight, observedAtTipHeight); OrphanPool_Insert(blk, blockHeight, observedAtTipHeight);
printf("Forced orphan BLOCK_DATA at height %" PRIu64 "\n", blockHeight); printf("Forced orphan BLOCK_DATA at height %" PRIu64 "\n", blockHeight);
return NODE_BLOCK_ORPHAN_QUEUED; return NODE_BLOCK_ORPHAN_QUEUED;
@@ -591,7 +591,7 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
// branch. Dropping both (as this used to) made any fork that diverges below the tip // branch. Dropping both (as this used to) made any fork that diverges below the tip
// impossible to discover: the fork point itself was always thrown away. // impossible to discover: the fork point itself was always thrown away.
block_t* local = NULL; block_t* local = NULL;
if (Chain_GetBlockCopy(currentChain, (size_t)blk->header.blockNumber, &local) && local) { if (Chain_GetBlockCopy(g_currentChain, (size_t)blk->header.blockNumber, &local) && local) {
uint8_t localHash[32]; uint8_t localHash[32];
uint8_t incomingHash[32]; uint8_t incomingHash[32];
Block_CalculateHash(local, localHash); Block_CalculateHash(local, localHash);
@@ -613,7 +613,7 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
// blk->header.blockNumber == chainSize -> candidate to append. Ensure prevHash matches current tip. // blk->header.blockNumber == chainSize -> candidate to append. Ensure prevHash matches current tip.
if (chainSize > 0) { if (chainSize > 0) {
block_t* last = NULL; block_t* last = NULL;
if (!Chain_GetBlockCopy(currentChain, (size_t)(chainSize - 1), &last) || !last) { if (!Chain_GetBlockCopy(g_currentChain, (size_t)(chainSize - 1), &last) || !last) {
// Can't verify parent; queue as orphan conservatively // Can't verify parent; queue as orphan conservatively
OrphanPool_Insert(blk, blockHeight, observedAtTipHeight); OrphanPool_Insert(blk, blockHeight, observedAtTipHeight);
printf("Queued orphan BLOCK_DATA at height %" PRIu64 " (unable to verify parent)\n", blockHeight); printf("Queued orphan BLOCK_DATA at height %" PRIu64 " (unable to verify parent)\n", blockHeight);
@@ -633,7 +633,7 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
} }
} }
if (!Chain_AddBlock(currentChain, blk)) { if (!Chain_AddBlock(g_currentChain, blk)) {
// Chain_AddBlock failed; cleanup. Safe either way: if it failed before taking the block we // Chain_AddBlock failed; cleanup. Safe either way: if it failed before taking the block we
// still own the transactions, and if it failed after (the ledger pass can fail with the // still own the transactions, and if it failed after (the ledger pass can fail with the
// block already pushed) our pointer to them was cleared, so this frees only the wrapper. // block already pushed) our pointer to them was cleared, so this frees only the wrapper.
@@ -642,25 +642,25 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
return NODE_BLOCK_REJECTED; return NODE_BLOCK_REJECTED;
} }
// currentSupply/currentReward are advanced inside Chain_AddBlock, so that every path that // g_currentSupply/g_currentReward are advanced inside Chain_AddBlock, so that every path that
// appends (mining, this one, orphan attach, reorg) keeps them consistent. // appends (mining, this one, orphan attach, reorg) keeps them consistent.
// Persist on accept if requested // Persist on accept if requested
if (persist) { if (persist) {
Chain_SaveToFile(currentChain, chainDataDir, currentSupply, currentReward); Chain_SaveToFile(g_currentChain, g_chainDataDir, g_currentSupply, g_currentReward);
BalanceSheet_SaveToFile(chainDataDir); BalanceSheet_SaveToFile(g_chainDataDir);
} }
// Chain_AddBlock took ownership of the transaction array and cleared our pointer to it, so // Chain_AddBlock took ownership of the transaction array and cleared our pointer to it, so
// destroying the wrapper here frees only the wrapper. // destroying the wrapper here frees only the wrapper.
Block_Destroy(blk); Block_Destroy(blk);
// Attempt to attach any orphans that may now have their parents present. // Attempt to attach any orphans that may now have their parents present.
size_t attached = OrphanPool_AttemptAttach(currentChain); size_t attached = OrphanPool_AttemptAttach(g_currentChain);
if (attached > 0) { if (attached > 0) {
printf("Attached %zu orphan(s) after accepting block\n", attached); printf("Attached %zu orphan(s) after accepting block\n", attached);
// Persist after attaching orphans // Persist after attaching orphans
Chain_SaveToFile(currentChain, chainDataDir, currentSupply, currentReward); Chain_SaveToFile(g_currentChain, g_chainDataDir, g_currentSupply, g_currentReward);
BalanceSheet_SaveToFile(chainDataDir); BalanceSheet_SaveToFile(g_chainDataDir);
} }
return NODE_BLOCK_ACCEPTED; return NODE_BLOCK_ACCEPTED;
} }
@@ -710,7 +710,7 @@ net_node_t* Node_Create() {
node->seenBlocks = set_create(32); // 32-byte canonical hashes; raw bytes, so memcmp equality is right node->seenBlocks = set_create(32); // 32-byte canonical hashes; raw bytes, so memcmp equality is right
TxMempool_Init(); TxMempool_Init();
TcpServer_Init(node->server, listenPort, "::"); TcpServer_Init(node->server, g_listenPort, "::");
node->server->owner = node; node->server->owner = node;
node->server->on_connect = Node_Server_OnConnect; node->server->on_connect = Node_Server_OnConnect;
@@ -725,7 +725,7 @@ net_node_t* Node_Create() {
// the node still works without discovery, it just won't crawl for new peers. // the node still works without discovery, it just won't crawl for new peers.
node->udpNode = (udp_node_t*)malloc(sizeof(udp_node_t)); node->udpNode = (udp_node_t*)malloc(sizeof(udp_node_t));
if (node->udpNode) { if (node->udpNode) {
if (UdpNode_Init(node->udpNode, (uint16_t)listenPort) == 0) { if (UdpNode_Init(node->udpNode, (uint16_t)g_listenPort) == 0) {
UdpNode_SetCallbacks(node->udpNode, Node_OnPongThunk, Node_OnPingTimeoutThunk, node); UdpNode_SetCallbacks(node->udpNode, Node_OnPongThunk, Node_OnPingTimeoutThunk, node);
if (UdpNode_Start(node->udpNode) == 0) { if (UdpNode_Start(node->udpNode) == 0) {
node->discovery = NodeDiscovery_Create(node, node->udpNode); node->discovery = NodeDiscovery_Create(node, node->udpNode);
@@ -968,13 +968,13 @@ void Node_Server_OnConnect(tcp_connection_t* client) {
Node_ForwardConnect(node, client); Node_ForwardConnect(node, client);
printf("Inbound node connected: %u\n", client ? client->connectionId : 0U); printf("Inbound node connected: %u\n", client ? client->connectionId : 0U);
if (echoPeersEnabled && node && client) { if (g_echoPeersEnabled && node && client) {
// Attempt to create an outbound connection back to the peer's IP on our configured port. // Attempt to create an outbound connection back to the peer's IP on our configured port.
// We avoid connecting if we already have an outbound to the same IP. // We avoid connecting if we already have an outbound to the same IP.
char ipbuf[INET6_ADDRSTRLEN]; char ipbuf[INET6_ADDRSTRLEN];
if (TcpConnection_GetPeerAddrStr(client, ipbuf, sizeof(ipbuf))) { if (TcpConnection_GetPeerAddrStr(client, ipbuf, sizeof(ipbuf))) {
// Use the configured port as the target port for the peer's listening service. // Use the configured port as the target port for the peer's listening service.
unsigned short targetPort = listenPort; unsigned short targetPort = g_listenPort;
int shouldConnect = 1; int shouldConnect = 1;
pthread_mutex_lock(&node->outboundLock); pthread_mutex_lock(&node->outboundLock);
@@ -1051,10 +1051,10 @@ void Node_Server_OnData(tcp_connection_t* client) {
uint64_t currentHeight = Node_GetCurrentBlockHeight(); uint64_t currentHeight = Node_GetCurrentBlockHeight();
memcpy(ackData + ackOffset, &currentHeight, sizeof(currentHeight)); memcpy(ackData + ackOffset, &currentHeight, sizeof(currentHeight));
ackOffset += sizeof(currentHeight); ackOffset += sizeof(currentHeight);
uint16_t myListenPort = (uint16_t)listenPort; uint16_t myListenPort = (uint16_t)g_listenPort;
memcpy(ackData + ackOffset, &myListenPort, sizeof(myListenPort)); memcpy(ackData + ackOffset, &myListenPort, sizeof(myListenPort));
ackOffset += sizeof(myListenPort); ackOffset += sizeof(myListenPort);
uint64_t myNodeId = localNodeId; uint64_t myNodeId = g_localNodeId;
memcpy(ackData + ackOffset, &myNodeId, sizeof(myNodeId)); memcpy(ackData + ackOffset, &myNodeId, sizeof(myNodeId));
ackOffset += sizeof(myNodeId); ackOffset += sizeof(myNodeId);
@@ -1130,9 +1130,9 @@ void Node_Server_OnData(tcp_connection_t* client) {
// Find the block (deep-copy it for safe access) // Find the block (deep-copy it for safe access)
block_t* block = NULL; block_t* block = NULL;
bool loadedFromDisk = false; bool loadedFromDisk = false;
if (!Chain_GetBlockCopy(currentChain, (size_t)requestedHeight, &block) || !block) { if (!Chain_GetBlockCopy(g_currentChain, (size_t)requestedHeight, &block) || !block) {
// Try loading from disk directly // Try loading from disk directly
if (!Chain_LoadBlockFromFile(chainDataDir, requestedHeight, true, &block, NULL) || !block) { if (!Chain_LoadBlockFromFile(g_chainDataDir, requestedHeight, true, &block, NULL) || !block) {
printf("Requested block height %" PRIu64 " not found, ignoring\n", requestedHeight); printf("Requested block height %" PRIu64 " not found, ignoring\n", requestedHeight);
const char* msg = "Requested block not found!"; const char* msg = "Requested block not found!";
Node_SendPacket(Node_FromConnection(client), client, PACKET_TYPE_ERROR, msg, strlen(msg)); Node_SendPacket(Node_FromConnection(client), client, PACKET_TYPE_ERROR, msg, strlen(msg));
@@ -1142,7 +1142,7 @@ void Node_Server_OnData(tcp_connection_t* client) {
} else if (!block->transactions) { } else if (!block->transactions) {
// In-memory chain may be compacted to headers only after persistence. // In-memory chain may be compacted to headers only after persistence.
block_t* fullBlock = NULL; block_t* fullBlock = NULL;
if (Chain_LoadBlockFromFile(chainDataDir, requestedHeight, true, &fullBlock, NULL) && fullBlock) { if (Chain_LoadBlockFromFile(g_chainDataDir, requestedHeight, true, &fullBlock, NULL) && fullBlock) {
Block_Destroy(block); Block_Destroy(block);
block = fullBlock; block = fullBlock;
loadedFromDisk = true; loadedFromDisk = true;
@@ -1349,11 +1349,11 @@ void Node_Client_OnConnect(tcp_connection_t* client) {
memcpy((unsigned char*)data + offset, &blockHeight, sizeof(blockHeight)); memcpy((unsigned char*)data + offset, &blockHeight, sizeof(blockHeight));
offset += sizeof(blockHeight); offset += sizeof(blockHeight);
// Advertise the port we listen on so the peer can share us with others (and reach us back) // Advertise the port we listen on so the peer can share us with others (and reach us back)
uint16_t myListenPort = (uint16_t)listenPort; uint16_t myListenPort = (uint16_t)g_listenPort;
memcpy((unsigned char*)data + offset, &myListenPort, sizeof(myListenPort)); memcpy((unsigned char*)data + offset, &myListenPort, sizeof(myListenPort));
offset += sizeof(myListenPort); offset += sizeof(myListenPort);
// ...and who we are, so the peer can tell this connection apart from our other addresses // ...and who we are, so the peer can tell this connection apart from our other addresses
uint64_t myNodeId = localNodeId; uint64_t myNodeId = g_localNodeId;
memcpy((unsigned char*)data + offset, &myNodeId, sizeof(myNodeId)); memcpy((unsigned char*)data + offset, &myNodeId, sizeof(myNodeId));
offset += sizeof(myNodeId); offset += sizeof(myNodeId);
@@ -1625,20 +1625,20 @@ int Node_GetBestOutboundPeer(net_node_t* node, tcp_connection_t** outConn, uint6
} }
void Node_BroadcastChainRange(net_node_t* node, size_t startHeightInclusive, tcp_connection_t* sourceConn) { void Node_BroadcastChainRange(net_node_t* node, size_t startHeightInclusive, tcp_connection_t* sourceConn) {
if (!node || !currentChain) return; if (!node || !g_currentChain) return;
size_t chainSize = Chain_Size(currentChain); size_t chainSize = Chain_Size(g_currentChain);
if (startHeightInclusive >= chainSize) return; if (startHeightInclusive >= chainSize) return;
for (size_t h = startHeightInclusive; h < chainSize; ++h) { for (size_t h = startHeightInclusive; h < chainSize; ++h) {
block_t* blk = NULL; block_t* blk = NULL;
if (!Chain_GetBlockCopy(currentChain, h, &blk) || !blk) { if (!Chain_GetBlockCopy(g_currentChain, h, &blk) || !blk) {
if (!Chain_LoadBlockFromFile(chainDataDir, h, true, &blk, NULL) || !blk) { if (!Chain_LoadBlockFromFile(g_chainDataDir, h, true, &blk, NULL) || !blk) {
continue; continue;
} }
} else if (!blk->transactions) { } else if (!blk->transactions) {
block_t* full = NULL; block_t* full = NULL;
if (Chain_LoadBlockFromFile(chainDataDir, h, true, &full, NULL) && full) { if (Chain_LoadBlockFromFile(g_chainDataDir, h, true, &full, NULL) && full) {
Block_Destroy(blk); Block_Destroy(blk);
blk = full; blk = full;
} }
+3 -3
View File
@@ -153,11 +153,11 @@ static void Discovery_SeedSelfEndpoints(node_discovery_t* disc) {
if (it->ifa_addr->sa_family == AF_INET) { if (it->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in* o = (struct sockaddr_in*)&ep; struct sockaddr_in* o = (struct sockaddr_in*)&ep;
memcpy(o, it->ifa_addr, sizeof(struct sockaddr_in)); memcpy(o, it->ifa_addr, sizeof(struct sockaddr_in));
o->sin_port = htons(listenPort); o->sin_port = htons(g_listenPort);
} else if (it->ifa_addr->sa_family == AF_INET6) { } else if (it->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6* o = (struct sockaddr_in6*)&ep; struct sockaddr_in6* o = (struct sockaddr_in6*)&ep;
memcpy(o, it->ifa_addr, sizeof(struct sockaddr_in6)); memcpy(o, it->ifa_addr, sizeof(struct sockaddr_in6));
o->sin6_port = htons(listenPort); o->sin6_port = htons(g_listenPort);
o->sin6_scope_id = 0; // endpoints on the wire are scopeless; compare them the same way o->sin6_scope_id = 0; // endpoints on the wire are scopeless; compare them the same way
} else { } else {
continue; continue;
@@ -494,7 +494,7 @@ void NodeDiscovery_NoteIdentity(node_discovery_t* disc, const struct sockaddr_st
if (!disc || !endpoint || nodeId == 0) return; if (!disc || !endpoint || nodeId == 0) return;
pthread_mutex_lock(&disc->lock); pthread_mutex_lock(&disc->lock);
if (nodeId == localNodeId) { if (nodeId == g_localNodeId) {
// The peer on the other end is us under one of our own addresses. Record it and drop it so // The peer on the other end is us under one of our own addresses. Record it and drop it so
// discovery stops treating it as a peer. // discovery stops treating it as a peer.
Discovery_AddSelfUnlocked(disc, endpoint); Discovery_AddSelfUnlocked(disc, endpoint);
+1 -1
View File
@@ -21,7 +21,7 @@ static uint64_t g_nextSequence = 0;
// thread. It used to have no synchronisation at all, so a concurrent Insert could realloc the // thread. It used to have no synchronisation at all, so a concurrent Insert could realloc the
// array out from under a scan that was holding a raw element pointer. // array out from under a scan that was holding a raw element pointer.
// //
// Lock ordering: this mutex is never held while calling into chain.c (which takes chainLock). // Lock ordering: this mutex is never held while calling into chain.c (which takes g_chainLock).
// Candidate branches are collected under the lock, the lock is dropped, and only then is // Candidate branches are collected under the lock, the lock is dropped, and only then is
// Chain_ReplaceBranch/Chain_AddBlock called. // Chain_ReplaceBranch/Chain_AddBlock called.
static pthread_mutex_t g_orphanLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_orphanLock = PTHREAD_MUTEX_INITIALIZER;
+32 -32
View File
@@ -5,10 +5,10 @@
static pthread_mutex_t g_txMempoolLock; static pthread_mutex_t g_txMempoolLock;
static bool g_txMempoolLockInitialized = false; static bool g_txMempoolLockInitialized = false;
khash_t(tx_mempool_map_m)* txMempool = NULL; khash_t(tx_mempool_map_m)* g_txMempool = NULL;
void TxMempool_Init() { void TxMempool_Init() {
txMempool = kh_init(tx_mempool_map_m); g_txMempool = kh_init(tx_mempool_map_m);
pthread_mutex_init(&g_txMempoolLock, NULL); pthread_mutex_init(&g_txMempoolLock, NULL);
g_txMempoolLockInitialized = true; g_txMempoolLockInitialized = true;
} }
@@ -37,20 +37,20 @@ bool TxMempool_PolicyAccepts(const signed_transaction_t* tx, uint64_t nowMs) {
} }
size_t TxMempool_PruneExpired(uint64_t nowMs) { size_t TxMempool_PruneExpired(uint64_t nowMs) {
if (!txMempool) { if (!g_txMempool) {
return 0; return 0;
} }
size_t removed = 0; size_t removed = 0;
pthread_mutex_lock(&g_txMempoolLock); pthread_mutex_lock(&g_txMempoolLock);
for (khiter_t k = kh_begin(txMempool); k != kh_end(txMempool); ++k) { for (khiter_t k = kh_begin(g_txMempool); k != kh_end(g_txMempool); ++k) {
if (!kh_exist(txMempool, k)) { if (!kh_exist(g_txMempool, k)) {
continue; continue;
} }
const uint64_t ts = kh_value(txMempool, k).transaction.timestamp; const uint64_t ts = kh_value(g_txMempool, k).transaction.timestamp;
if (nowMs > ts && (nowMs - ts) > TX_EXPIRY_MS) { if (nowMs > ts && (nowMs - ts) > TX_EXPIRY_MS) {
kh_del(tx_mempool_map_m, txMempool, k); kh_del(tx_mempool_map_m, g_txMempool, k);
removed++; removed++;
} }
} }
@@ -60,7 +60,7 @@ size_t TxMempool_PruneExpired(uint64_t nowMs) {
} }
int TxMempool_Insert(signed_transaction_t tx) { int TxMempool_Insert(signed_transaction_t tx) {
if (!txMempool) { return -1; } if (!g_txMempool) { return -1; }
pthread_mutex_lock(&g_txMempoolLock); pthread_mutex_lock(&g_txMempoolLock);
uint8_t txHash[32]; uint8_t txHash[32];
@@ -70,13 +70,13 @@ int TxMempool_Insert(signed_transaction_t tx) {
memcpy(key.bytes, txHash, 32); memcpy(key.bytes, txHash, 32);
int ret; int ret;
khiter_t k = kh_put(tx_mempool_map_m, txMempool, key, &ret); khiter_t k = kh_put(tx_mempool_map_m, g_txMempool, key, &ret);
if (k == kh_end(txMempool)) { if (k == kh_end(g_txMempool)) {
pthread_mutex_unlock(&g_txMempoolLock); pthread_mutex_unlock(&g_txMempoolLock);
return -1; return -1;
} }
kh_value(txMempool, k) = tx; kh_value(g_txMempool, k) = tx;
pthread_mutex_unlock(&g_txMempoolLock); pthread_mutex_unlock(&g_txMempoolLock);
@@ -84,15 +84,15 @@ int TxMempool_Insert(signed_transaction_t tx) {
} }
bool TxMempool_Lookup(uint8_t* txHash, signed_transaction_t* out) { bool TxMempool_Lookup(uint8_t* txHash, signed_transaction_t* out) {
if (!txMempool || !txHash || !out) { return false; } if (!g_txMempool || !txHash || !out) { return false; }
pthread_mutex_lock(&g_txMempoolLock); pthread_mutex_lock(&g_txMempoolLock);
key32_t key; key32_t key;
memcpy(key.bytes, txHash, 32); memcpy(key.bytes, txHash, 32);
khiter_t k = kh_get(tx_mempool_map_m, txMempool, key); khiter_t k = kh_get(tx_mempool_map_m, g_txMempool, key);
if (k != kh_end(txMempool)) { if (k != kh_end(g_txMempool)) {
signed_transaction_t tx = kh_value(txMempool, k); signed_transaction_t tx = kh_value(g_txMempool, k);
memcpy(out, &tx, sizeof(signed_transaction_t)); memcpy(out, &tx, sizeof(signed_transaction_t));
pthread_mutex_unlock(&g_txMempoolLock); pthread_mutex_unlock(&g_txMempoolLock);
return true; return true;
@@ -110,7 +110,7 @@ bool TxMempool_Snapshot(signed_transaction_t** outTxs, size_t* outCount) {
*outTxs = NULL; *outTxs = NULL;
*outCount = 0; *outCount = 0;
if (!txMempool) { if (!g_txMempool) {
return true; return true;
} }
@@ -118,8 +118,8 @@ bool TxMempool_Snapshot(signed_transaction_t** outTxs, size_t* outCount) {
size_t count = 0; size_t count = 0;
khiter_t k; khiter_t k;
for (k = kh_begin(txMempool); k != kh_end(txMempool); ++k) { for (k = kh_begin(g_txMempool); k != kh_end(g_txMempool); ++k) {
if (kh_exist(txMempool, k)) { if (kh_exist(g_txMempool, k)) {
++count; ++count;
} }
} }
@@ -136,9 +136,9 @@ bool TxMempool_Snapshot(signed_transaction_t** outTxs, size_t* outCount) {
} }
size_t index = 0; size_t index = 0;
for (k = kh_begin(txMempool); k != kh_end(txMempool); ++k) { for (k = kh_begin(g_txMempool); k != kh_end(g_txMempool); ++k) {
if (kh_exist(txMempool, k)) { if (kh_exist(g_txMempool, k)) {
snapshot[index++] = kh_value(txMempool, k); snapshot[index++] = kh_value(g_txMempool, k);
} }
} }
@@ -150,13 +150,13 @@ bool TxMempool_Snapshot(signed_transaction_t** outTxs, size_t* outCount) {
} }
void TxMempool_Print() { void TxMempool_Print() {
if (!txMempool) { return; } if (!g_txMempool) { return; }
pthread_mutex_lock(&g_txMempoolLock); pthread_mutex_lock(&g_txMempoolLock);
khiter_t k; khiter_t k;
for (k = kh_begin(txMempool); k != kh_end(txMempool); ++k) { for (k = kh_begin(g_txMempool); k != kh_end(g_txMempool); ++k) {
if (kh_exist(txMempool, k)) { if (kh_exist(g_txMempool, k)) {
signed_transaction_t tx = kh_val(txMempool, k); signed_transaction_t tx = kh_val(g_txMempool, k);
char senderHex[65]; char senderHex[65];
char recipient1Hex[65]; char recipient1Hex[65];
char recipient2Hex[65]; char recipient2Hex[65];
@@ -174,10 +174,10 @@ void TxMempool_Print() {
} }
void TxMempool_Destroy() { void TxMempool_Destroy() {
if (txMempool) { if (g_txMempool) {
pthread_mutex_lock(&g_txMempoolLock); pthread_mutex_lock(&g_txMempoolLock);
kh_destroy(tx_mempool_map_m, txMempool); kh_destroy(tx_mempool_map_m, g_txMempool);
txMempool = NULL; g_txMempool = NULL;
pthread_mutex_unlock(&g_txMempoolLock); pthread_mutex_unlock(&g_txMempoolLock);
} }
@@ -188,19 +188,19 @@ void TxMempool_Destroy() {
} }
bool TxMempool_Remove(const uint8_t* txHash) { bool TxMempool_Remove(const uint8_t* txHash) {
if (!txMempool || !txHash) { return false; } if (!g_txMempool || !txHash) { return false; }
pthread_mutex_lock(&g_txMempoolLock); pthread_mutex_lock(&g_txMempoolLock);
key32_t key; key32_t key;
memcpy(key.bytes, txHash, 32); memcpy(key.bytes, txHash, 32);
khiter_t k = kh_get(tx_mempool_map_m, txMempool, key); khiter_t k = kh_get(tx_mempool_map_m, g_txMempool, key);
if (k == kh_end(txMempool)) { if (k == kh_end(g_txMempool)) {
pthread_mutex_unlock(&g_txMempoolLock); pthread_mutex_unlock(&g_txMempoolLock);
return false; return false;
} }
kh_del(tx_mempool_map_m, txMempool, k); kh_del(tx_mempool_map_m, g_txMempool, k);
pthread_mutex_unlock(&g_txMempoolLock); pthread_mutex_unlock(&g_txMempoolLock);
return true; return true;
} }