/** * Find our proof of work. * * @param cls closure (unused) */ static void find_proof (void *cls) { #define ROUND_SIZE 10 uint64_t counter; char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + sizeof (uint64_t)] GNUNET_ALIGN; struct GNUNET_HashCode result; unsigned int i; proof_task = NULL; GNUNET_memcpy (&buf[sizeof (uint64_t)], &my_identity, sizeof (struct GNUNET_PeerIdentity)); i = 0; counter = my_proof; while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) { GNUNET_memcpy (buf, &counter, sizeof (uint64_t)); pow_hash (buf, sizeof (buf), &result); if (nse_work_required <= count_leading_zeroes (&result)) { my_proof = counter; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof of work found: %llu!\n", (unsigned long long) GNUNET_ntohll (counter)); write_proof (); setup_flood_message (estimate_index, current_timestamp); return; } counter++; i++; } if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing proofs currently at %llu\n", (unsigned long long) counter); /* remember progress every 100 rounds */ my_proof = counter; write_proof (); } else { my_proof = counter; } proof_task = GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); }
/** * Check whether the given public key and integer are a valid proof of * work. * * @param pkey the public key * @param val the integer * @return #GNUNET_YES if valid, #GNUNET_NO if not */ static int check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, uint64_t val) { char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + sizeof (val)] GNUNET_ALIGN; struct GNUNET_HashCode result; GNUNET_memcpy (buf, &val, sizeof (val)); GNUNET_memcpy (&buf[sizeof (val)], pkey, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); pow_hash (buf, sizeof (buf), &result); return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES : GNUNET_NO; }
/** * Find our proof of work. * * @param cls closure (unused) * @param tc task context */ static void find_proof (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { #define ROUND_SIZE 10 uint64_t counter; char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + sizeof (uint64_t)] GNUNET_ALIGN; struct GNUNET_HashCode result; unsigned int i; struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Relative elapsed; if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) { write_proof (); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got Proof of Work %llu\n", proof); proof_task = NULL; memcpy (&buf[sizeof (uint64_t)], &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); i = 0; counter = proof; timestamp = GNUNET_TIME_absolute_get (); while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) { memcpy (buf, &counter, sizeof (uint64_t)); pow_hash (buf, sizeof (buf), &result); if (nse_work_required <= count_leading_zeroes (&result)) { proof = counter; FPRINTF (stdout, "Proof of work found: %llu!\n", (unsigned long long) proof); write_proof (); return; } counter++; i++; } elapsed = GNUNET_TIME_absolute_get_duration (timestamp); elapsed = GNUNET_TIME_relative_divide (elapsed, ROUND_SIZE); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current: %llu [%s/proof]\n", (unsigned long long) counter, GNUNET_STRINGS_relative_time_to_string (elapsed, 0)); if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing proofs currently at %llu\n", (unsigned long long) counter); /* remember progress every 100 rounds */ proof = counter; write_proof (); } else { proof = counter; } proof_task = GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); }