huge chain test, added 1.5% yearly inflation at 3.5 million blocks
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include <block/chain.h>
|
||||
#include <constants.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -134,8 +135,9 @@ void Chain_Wipe(blockchain_t* chain) {
|
||||
Chain_ClearBlocks(chain);
|
||||
}
|
||||
|
||||
bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t currentSupply) {
|
||||
bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t currentSupply, uint64_t currentReward) {
|
||||
// To avoid stalling the chain from peers, write after every block addition (THAT IS VERIFIED)
|
||||
// TODO: Write to one "db" file instead of one file per block - filesystems (and rm *) don't like millions of files :(
|
||||
|
||||
if (!chain || !chain->blocks || !EnsureDirectoryExists(dirpath)) {
|
||||
return false;
|
||||
@@ -164,6 +166,8 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
|
||||
fwrite(&zeroSupply, sizeof(uint256_t), 1, metaFile);
|
||||
uint32_t initialTarget = INITIAL_DIFFICULTY;
|
||||
fwrite(&initialTarget, sizeof(uint32_t), 1, metaFile);
|
||||
uint64_t initialReward = 0;
|
||||
fwrite(&initialReward, sizeof(uint64_t), 1, metaFile);
|
||||
|
||||
// TODO: Potentially some other things here, we'll see
|
||||
}
|
||||
@@ -235,12 +239,13 @@ bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t curren
|
||||
fwrite(¤tSupply, sizeof(uint256_t), 1, metaFile);
|
||||
uint32_t difficultyTarget = ((block_t*)DynArr_at(chain->blocks, newSize - 1))->header.difficultyTarget;
|
||||
fwrite(&difficultyTarget, sizeof(uint32_t), 1, metaFile);
|
||||
fwrite(¤tReward, sizeof(uint64_t), 1, metaFile);
|
||||
fclose(metaFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* outCurrentSupply, uint32_t* outDifficultyTarget) {
|
||||
bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* outCurrentSupply, uint32_t* outDifficultyTarget, uint64_t* outCurrentReward) {
|
||||
if (!chain || !chain->blocks || !dirpath || !outCurrentSupply) {
|
||||
return false;
|
||||
}
|
||||
@@ -267,6 +272,7 @@ bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* out
|
||||
fread(lastSavedHash, sizeof(uint8_t), 32, metaFile);
|
||||
fread(outCurrentSupply, sizeof(uint256_t), 1, metaFile);
|
||||
fread(outDifficultyTarget, sizeof(uint32_t), 1, metaFile);
|
||||
fread(outCurrentReward, sizeof(uint64_t), 1, metaFile);
|
||||
fclose(metaFile);
|
||||
|
||||
// TODO: Might add a flag to allow reading from a point onward, but just rewrite for now
|
||||
|
||||
40
src/main.c
40
src/main.c
@@ -24,6 +24,9 @@ void handle_sigint(int sig) {
|
||||
|
||||
uint32_t difficultyTarget = INITIAL_DIFFICULTY;
|
||||
|
||||
// extern the currentReward from constants.h so we can update it as we mine blocks and save it to disk
|
||||
extern uint64_t currentReward;
|
||||
|
||||
static bool MineBlock(block_t* block) {
|
||||
if (!block) {
|
||||
return false;
|
||||
@@ -45,7 +48,7 @@ int main(int argc, char* argv[]) {
|
||||
signal(SIGINT, handle_sigint);
|
||||
|
||||
const char* chainDataDir = CHAIN_DATA_DIR;
|
||||
const uint64_t blocksToMine = 1000;
|
||||
const uint64_t blocksToMine = 4000000;
|
||||
const double targetSeconds = TARGET_BLOCK_TIME;
|
||||
|
||||
uint256_t currentSupply = uint256_from_u64(0);
|
||||
@@ -56,10 +59,14 @@ int main(int argc, char* argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!Chain_LoadFromFile(chain, chainDataDir, ¤tSupply, &difficultyTarget)) {
|
||||
if (!Chain_LoadFromFile(chain, chainDataDir, ¤tSupply, &difficultyTarget, ¤tReward)) {
|
||||
printf("No existing chain loaded from %s\n", chainDataDir);
|
||||
}
|
||||
|
||||
if (currentReward == 0) {
|
||||
currentReward = CalculateBlockReward(currentSupply, chain);
|
||||
}
|
||||
|
||||
if (Chain_Size(chain) > 0) {
|
||||
if (Chain_IsValid(chain)) {
|
||||
printf("Loaded chain with %zu blocks from disk\n", Chain_Size(chain));
|
||||
@@ -117,9 +124,11 @@ int main(int argc, char* argv[]) {
|
||||
signed_transaction_t coinbaseTx;
|
||||
memset(&coinbaseTx, 0, sizeof(coinbaseTx));
|
||||
coinbaseTx.transaction.version = 1;
|
||||
coinbaseTx.transaction.amount = CalculateBlockReward(currentSupply, block->header.blockNumber);
|
||||
coinbaseTx.transaction.amount1 = currentReward;
|
||||
coinbaseTx.transaction.fee = 0;
|
||||
memcpy(coinbaseTx.transaction.recipientAddress, minerAddress, sizeof(minerAddress));
|
||||
memcpy(coinbaseTx.transaction.recipientAddress1, minerAddress, sizeof(minerAddress));
|
||||
coinbaseTx.transaction.recipientAddress2[0] = 0; // Mark recipient 2 as unused
|
||||
coinbaseTx.transaction.amount2 = 0;
|
||||
memset(coinbaseTx.transaction.compressedPublicKey, 0, sizeof(coinbaseTx.transaction.compressedPublicKey));
|
||||
memset(coinbaseTx.transaction.senderAddress, 0xFF, sizeof(coinbaseTx.transaction.senderAddress));
|
||||
Block_AddTransaction(block, &coinbaseTx);
|
||||
@@ -144,7 +153,7 @@ int main(int argc, char* argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void)uint256_add_u64(¤tSupply, coinbaseTx.transaction.amount);
|
||||
(void)uint256_add_u64(¤tSupply, coinbaseTx.transaction.amount1);
|
||||
|
||||
uint8_t canonicalHash[32];
|
||||
uint8_t powHash[32];
|
||||
@@ -155,7 +164,7 @@ int main(int argc, char* argv[]) {
|
||||
(unsigned long long)blocksToMine,
|
||||
(unsigned long long)block->header.blockNumber,
|
||||
(unsigned long long)block->header.nonce,
|
||||
(unsigned long long)coinbaseTx.transaction.amount,
|
||||
(unsigned long long)coinbaseTx.transaction.amount1,
|
||||
(unsigned long long)currentSupply.limbs[0],
|
||||
(unsigned int)block->header.difficultyTarget,
|
||||
block->header.merkleRoot[0], block->header.merkleRoot[1], block->header.merkleRoot[2], block->header.merkleRoot[3],
|
||||
@@ -164,15 +173,18 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
free(block); // chain stores blocks by value; transactions are owned by chain copy
|
||||
|
||||
// Save chain after each mined block
|
||||
Chain_SaveToFile(chain, chainDataDir, currentSupply);
|
||||
// Save chain after each mined block; NOTE: In reality, blocks will appear every ~90s, so this won't be a realistic bottleneck on the mainnet
|
||||
Chain_SaveToFile(chain, chainDataDir, currentSupply, currentReward);
|
||||
|
||||
if (Chain_Size(chain) % DIFFICULTY_ADJUSTMENT_INTERVAL == 0) {
|
||||
difficultyTarget = Chain_ComputeNextTarget(chain, difficultyTarget);
|
||||
}
|
||||
currentReward = CalculateBlockReward(currentSupply, chain); // Update the global currentReward for the next block
|
||||
|
||||
// TEST, disabled diff
|
||||
//if (Chain_Size(chain) % DIFFICULTY_ADJUSTMENT_INTERVAL == 0) {
|
||||
// difficultyTarget = Chain_ComputeNextTarget(chain, difficultyTarget);
|
||||
//}
|
||||
}
|
||||
|
||||
if (!Chain_SaveToFile(chain, chainDataDir, currentSupply)) {
|
||||
if (!Chain_SaveToFile(chain, chainDataDir, currentSupply, currentReward)) {
|
||||
fprintf(stderr, "failed to save chain to %s\n", chainDataDir);
|
||||
} else {
|
||||
printf("Saved chain with %zu blocks to %s (supply=%llu)\n",
|
||||
@@ -185,12 +197,12 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
// Print chain
|
||||
for (size_t i = 0; i < Chain_Size(chain); i++) {
|
||||
/*for (size_t i = 0; i < Chain_Size(chain); i++) {
|
||||
block_t* blk = Chain_GetBlock(chain, i);
|
||||
if (blk) {
|
||||
Block_Print(blk);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
Chain_Destroy(chain);
|
||||
Block_ShutdownPowContext();
|
||||
|
||||
Reference in New Issue
Block a user