Improved POW
This commit is contained in:
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Manual Proof of Work Loop Test
|
||||
*
|
||||
* Creates an event and manually mines it by incrementing nonce
|
||||
* until target difficulty is reached. Shows each iteration.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../nostr_core/nostr_core.h"
|
||||
#include "../cjson/cJSON.h"
|
||||
|
||||
// Helper function to count leading zero bits (from NIP-13)
|
||||
static int zero_bits(unsigned char b) {
|
||||
int n = 0;
|
||||
|
||||
if (b == 0)
|
||||
return 8;
|
||||
|
||||
while (b >>= 1)
|
||||
n++;
|
||||
|
||||
return 7-n;
|
||||
}
|
||||
|
||||
// Count leading zero bits in hash (from NIP-13)
|
||||
static int count_leading_zero_bits(unsigned char *hash) {
|
||||
int bits, total, i;
|
||||
for (i = 0, total = 0; i < 32; i++) {
|
||||
bits = zero_bits(hash[i]);
|
||||
total += bits;
|
||||
if (bits != 8)
|
||||
break;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Initialize library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize nostr library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Generate test keypair
|
||||
unsigned char private_key[32];
|
||||
unsigned char public_key[32];
|
||||
|
||||
if (nostr_generate_keypair(private_key, public_key) != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to generate keypair\n");
|
||||
nostr_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("=== Manual Proof of Work Mining (Target Difficulty: 8) ===\n\n");
|
||||
|
||||
// Create base event content
|
||||
const char* content = "Proof of Work Test";
|
||||
int kind = 1;
|
||||
time_t created_at = time(NULL);
|
||||
|
||||
// Target difficulty
|
||||
const int target_difficulty = 20;
|
||||
uint64_t nonce = 0;
|
||||
int max_attempts = 10000000000;
|
||||
|
||||
printf("Mining event with target difficulty %d...\n\n", target_difficulty);
|
||||
|
||||
// Mining loop
|
||||
for (int attempt = 0; attempt < max_attempts; attempt++) {
|
||||
// Create tags array with current nonce
|
||||
cJSON* tags = cJSON_CreateArray();
|
||||
if (!tags) {
|
||||
fprintf(stderr, "Failed to create tags array\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// Add nonce tag: ["nonce", "<nonce>", "<target_difficulty>"]
|
||||
cJSON* nonce_tag = cJSON_CreateArray();
|
||||
char nonce_str[32];
|
||||
char difficulty_str[16];
|
||||
snprintf(nonce_str, sizeof(nonce_str), "%llu", (unsigned long long)nonce);
|
||||
snprintf(difficulty_str, sizeof(difficulty_str), "%d", target_difficulty);
|
||||
|
||||
cJSON_AddItemToArray(nonce_tag, cJSON_CreateString("nonce"));
|
||||
cJSON_AddItemToArray(nonce_tag, cJSON_CreateString(nonce_str));
|
||||
cJSON_AddItemToArray(nonce_tag, cJSON_CreateString(difficulty_str));
|
||||
cJSON_AddItemToArray(tags, nonce_tag);
|
||||
|
||||
// Create and sign event with current nonce
|
||||
cJSON* event = nostr_create_and_sign_event(kind, content, tags, private_key, created_at);
|
||||
cJSON_Delete(tags);
|
||||
|
||||
if (!event) {
|
||||
fprintf(stderr, "Failed to create event at nonce %llu\n", (unsigned long long)nonce);
|
||||
nonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get event ID
|
||||
cJSON* id_item = cJSON_GetObjectItem(event, "id");
|
||||
if (!id_item || !cJSON_IsString(id_item)) {
|
||||
fprintf(stderr, "Failed to get event ID at nonce %llu\n", (unsigned long long)nonce);
|
||||
cJSON_Delete(event);
|
||||
nonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* event_id = cJSON_GetStringValue(id_item);
|
||||
|
||||
// Convert hex ID to bytes and count leading zero bits
|
||||
unsigned char hash[32];
|
||||
if (nostr_hex_to_bytes(event_id, hash, 32) != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to convert event ID to bytes at nonce %llu\n", (unsigned long long)nonce);
|
||||
cJSON_Delete(event);
|
||||
nonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int current_difficulty = count_leading_zero_bits(hash);
|
||||
|
||||
// Print current attempt
|
||||
printf("Nonce %llu: ID = %.16s... (difficulty: %d)",
|
||||
(unsigned long long)nonce, event_id, current_difficulty);
|
||||
|
||||
// Check if we've reached target difficulty
|
||||
if (current_difficulty >= target_difficulty) {
|
||||
printf(" ✓ SUCCESS!\n\n");
|
||||
|
||||
// Print final successful event
|
||||
printf("=== SUCCESSFUL EVENT ===\n");
|
||||
char* final_json = cJSON_Print(event);
|
||||
if (final_json) {
|
||||
printf("%s\n", final_json);
|
||||
free(final_json);
|
||||
}
|
||||
|
||||
printf("\n🎉 Mining completed!\n");
|
||||
printf(" Attempts: %d\n", attempt + 1);
|
||||
printf(" Final nonce: %llu\n", (unsigned long long)nonce);
|
||||
printf(" Final difficulty: %d (target was %d)\n", current_difficulty, target_difficulty);
|
||||
|
||||
cJSON_Delete(event);
|
||||
nostr_cleanup();
|
||||
return 0;
|
||||
} else {
|
||||
printf(" (need %d)\n", target_difficulty);
|
||||
}
|
||||
|
||||
cJSON_Delete(event);
|
||||
nonce++;
|
||||
}
|
||||
|
||||
// If we reach here, we've exceeded max attempts
|
||||
printf("\n❌ Mining failed after %d attempts\n", max_attempts);
|
||||
printf("Consider increasing max_attempts or reducing target_difficulty\n");
|
||||
|
||||
nostr_cleanup();
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user