BigInts, save/load, will make a calculation for block rewards soon

This commit is contained in:
2026-03-29 22:18:57 +02:00
parent 57bfe61c13
commit 0d7adc39e0
10 changed files with 456 additions and 39 deletions

View File

@@ -10,13 +10,14 @@
#include <randomx/librx_wrapper.h>
typedef struct {
uint8_t version;
uint32_t blockNumber;
uint64_t blockNumber;
uint64_t timestamp;
uint64_t nonce;
uint8_t prevHash[32];
uint8_t merkleRoot[32];
uint64_t timestamp;
uint32_t difficultyTarget; // Encoding: [1 byte exponent][3 byte coefficient]; Target = coefficient * 256^(exponent-3)
uint64_t nonce; // Higher nonce for RandomX
uint8_t version;
uint8_t reserved[3]; // 3 bytes (Explicit padding for 8-byte alignment)
} block_header_t;
typedef struct {

View File

@@ -4,6 +4,9 @@
#include <block/block.h>
#include <dynarr.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
typedef struct {
DynArr* blocks;
@@ -16,5 +19,10 @@ bool Chain_AddBlock(blockchain_t* chain, block_t* block);
block_t* Chain_GetBlock(blockchain_t* chain, size_t index);
size_t Chain_Size(blockchain_t* chain);
bool Chain_IsValid(blockchain_t* chain);
void Chain_Wipe(blockchain_t* chain);
// I/O
bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath);
bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath);
#endif

37
include/constants.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
#include <stdint.h>
#include <uint256.h>
#include <stdbool.h>
#define DECIMALS 1000000000000ULL
#define EMISSION_SPEED_FACTOR 20
const uint64_t M_CAP = 18446744073709551615ULL; // Max uint64
const uint64_t TAIL_EMISSION = (uint64_t)(1.0 * DECIMALS); // Emission floor is 1.0 coins per block
// No max supply. Instead of halving, it'll follow a more gradual, Monero-like emission curve.
static inline uint64_t CalculateBlockReward(uint256_t currentSupply, uint64_t height) {
// Inclusive of block 0
if (current_supply.limbs[1] > 0 ||
current_supply.limbs[2] > 0 ||
current_supply.limbs[3] > 0 ||
current_supply.limbs[0] >= M_CAP) {
return TAIL_EMISSION;
}
uint64_t supply_64 = current_supply.limbs[0];
// Formula: (M - Supply) >> 2^k - lifted from Monero's codebase (thanks guys!)
uint64_t reward = (M_CAP - supply_64) >> EMISSION_SPEED_FACTOR;
// Check if the calculated reward has fallen below the floor
if (reward < TAIL_EMISSION) {
return TAIL_EMISSION;
}
return reward;
}
#endif

View File

@@ -10,7 +10,7 @@
extern "C" {
#endif
bool RandomX_Init(const char* key);
bool RandomX_Init(const char* key, bool preferFullMemory);
void RandomX_Destroy();
void RandomX_CalculateHash(const uint8_t* input, size_t inputLen, uint8_t* output);

58
include/uint256.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef UINT256_H
#define UINT256_H
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
typedef struct {
uint64_t limbs[4]; // 4 * 64 = 256 bits
} uint256_t;
// Initialize a uint256 with a standard 64-bit value
static inline uint256_t uint256_from_u64(uint64_t val) {
uint256_t res = {{val, 0, 0, 0}};
return res;
}
/**
* Adds a uint64_t (transaction amount) to a uint256_t (balance).
* Returns true if an overflow occurred (total supply exceeded 256 bits).
**/
static inline bool uint256_add_u64(uint256_t* balance, uint64_t amount) {
uint64_t old = balance->limbs[0];
balance->limbs[0] += amount;
// Check for carry: if the new value is less than the old, it wrapped around
if (balance->limbs[0] < old) {
for (int i = 1; i < 4; i++) {
balance->limbs[i]++;
// If the limb didn't wrap to 0, the carry is fully absorbed
if (balance->limbs[i] != 0) return false;
}
return true; // Overflowed all 256 bits
}
return false;
}
/**
* Adds two uint256_t values together.
* Standard full addition logic.
**/
static inline bool uint256_add(uint256_t* a, const uint256_t* b) {
uint64_t carry = 0;
for (int i = 0; i < 4; i++) {
uint64_t old_a = a->limbs[i];
a->limbs[i] += b->limbs[i] + carry;
// Detect carry: current is less than what we added, or we were at max and had a carry
if (carry) {
carry = (a->limbs[i] <= old_a);
} else {
carry = (a->limbs[i] < old_a);
}
}
return carry > 0;
}
#endif