aad-assignment-1/aad_coin_miner_wasm.c

269 lines
5.4 KiB
C

//
// Arquiteturas de Alto Desempenho 2025/2026
//
// DETI Coin Miner - WebAssembly implementation
//
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aad_data_types.h"
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include "aad_sha1_wasm.h"
#else
#include "aad_sha1_cpu.h"
#include "aad_utilities.h"
#include "aad_vault.h"
#endif
// Global mining state
static volatile int keep_running = 1;
static u64_t total_attempts = 0;
static u32_t coins_found = 0;
static double mining_start_time = 0;
static u32_t found_coins[1024][14]; // Store up to 1024 found coins
static u32_t found_coins_count = 0;
//
// Check if a hash starts with aad20250
//
static int is_valid_coin(u32_t *hash)
{
return hash[0] == 0xAAD20250u;
}
//
// Increment coin variable part (positions 12-53)
//
static int increment_coin(u32_t coin[14])
{
int pos = 53;
while(pos >= 12)
{
u08_t *byte = &((u08_t *)coin)[pos ^ 3];
if(*byte == '\n' || *byte == 0x80)
*byte = 32;
(*byte)++;
if(*byte == '\n')
(*byte)++;
if(*byte >= 127)
{
*byte = 32;
pos--;
}
else
{
break;
}
}
return (pos >= 12);
}
//
// Get current time in seconds
//
static double get_time()
{
#ifdef __EMSCRIPTEN__
return emscripten_get_now() / 1000.0;
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return (double)ts.tv_sec + (double)ts.tv_nsec / 1e9;
#endif
}
//
// Main mining iteration (called from JavaScript)
//
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
int mine_coins_wasm(u32_t iterations_per_call)
{
static u32_t coin[14];
static int initialized = 0;
u32_t hash[5];
// Initialize coin template on first call
if(!initialized)
{
memset(coin, 0, sizeof(coin));
((u08_t *)coin)[0x0 ^ 3] = 'D';
((u08_t *)coin)[0x1 ^ 3] = 'E';
((u08_t *)coin)[0x2 ^ 3] = 'T';
((u08_t *)coin)[0x3 ^ 3] = 'I';
((u08_t *)coin)[0x4 ^ 3] = ' ';
((u08_t *)coin)[0x5 ^ 3] = 'c';
((u08_t *)coin)[0x6 ^ 3] = 'o';
((u08_t *)coin)[0x7 ^ 3] = 'i';
((u08_t *)coin)[0x8 ^ 3] = 'n';
((u08_t *)coin)[0x9 ^ 3] = ' ';
((u08_t *)coin)[0xa ^ 3] = '2';
((u08_t *)coin)[0xb ^ 3] = ' ';
((u08_t *)coin)[0x36 ^ 3] = '\n';
((u08_t *)coin)[0x37 ^ 3] = 0x80;
for(int i = 12; i < 54; i++)
((u08_t *)coin)[i ^ 3] = 'A' + (i - 12) % 26;
mining_start_time = get_time();
initialized = 1;
}
if(!keep_running)
return 0;
// Mine for the specified number of iterations
for(u32_t i = 0; i < iterations_per_call && keep_running; i++)
{
sha1(coin, hash);
total_attempts++;
if(is_valid_coin(hash))
{
if(found_coins_count < 1024)
{
memcpy(found_coins[found_coins_count], coin, sizeof(coin));
found_coins_count++;
}
coins_found++;
#ifndef __EMSCRIPTEN__
printf("COIN FOUND! (attempt %llu)\n", (unsigned long long)total_attempts);
save_coin(coin);
#endif
}
increment_coin(coin);
}
return keep_running;
}
//
// Get mining statistics
//
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
void get_statistics(u64_t *attempts, u32_t *coins, double *hash_rate, double *elapsed_time)
{
*attempts = total_attempts;
*coins = coins_found;
*elapsed_time = get_time() - mining_start_time;
*hash_rate = (*elapsed_time > 0) ? (total_attempts / *elapsed_time) : 0;
}
//
// Stop mining
//
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
void stop_mining()
{
keep_running = 0;
}
//
// Get found coin data (returns pointer to coin array)
//
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
u32_t* get_found_coin(u32_t index)
{
if(index < found_coins_count)
return found_coins[index];
return NULL;
}
//
// Get number of found coins
//
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
u32_t get_found_coins_count()
{
return found_coins_count;
}
//
// Reset mining state
//
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif
void reset_mining()
{
keep_running = 1;
total_attempts = 0;
coins_found = 0;
found_coins_count = 0;
mining_start_time = get_time();
}
//
// Main function (for standalone compilation/testing)
//
#ifndef __EMSCRIPTEN__
int main(int argc, char *argv[])
{
u64_t max_attempts = 0;
if(argc > 1)
max_attempts = strtoull(argv[1], NULL, 10);
printf("Mining DETI coins using WebAssembly implementation (standalone mode)...\n");
printf("Press Ctrl+C to stop\n\n");
time_measurement();
time_measurement();
double start_time = wall_time_delta();
double last_report = start_time;
while(keep_running && (max_attempts == 0 || total_attempts < max_attempts))
{
mine_coins_wasm(100000);
time_measurement();
double current_time = wall_time_delta() - start_time;
if(current_time - last_report >= 1.0)
{
u64_t attempts;
u32_t coins;
double hash_rate, elapsed;
get_statistics(&attempts, &coins, &hash_rate, &elapsed);
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u\n",
(unsigned long long)attempts, hash_rate / 1e6, coins);
last_report = current_time;
}
}
time_measurement();
double total_time = wall_time_delta() - start_time;
printf("\n=== Mining Statistics ===\n");
printf("Total attempts: %llu\n", (unsigned long long)total_attempts);
printf("Total time: %.2f seconds\n", total_time);
printf("Average rate: %.2f attempts/second\n", total_attempts / total_time);
printf("Coins found: %u\n", coins_found);
save_coin(NULL);
return 0;
}
#endif